fix withdraw and desposit ui

This commit is contained in:
2026-06-15 15:48:10 +03:30
parent f7b86a5fa1
commit 57a8fb9854
11 changed files with 438 additions and 100 deletions
@@ -0,0 +1,221 @@
<template>
<a-form
:model="form"
ref="formRef"
autocomplete="off"
class="wallet-charge-form"
:class="formClass"
>
<a-form-item label="نوع عملیات" name="direction">
<a-radio-group
v-model:value="form.direction"
button-style="solid"
class="wallet-charge-form__direction w-full"
>
<a-radio-button value="charge" class="wallet-charge-form__radio wallet-charge-form__radio--charge">
<span class="wallet-charge-form__radio-icon">+</span>
شارژ
</a-radio-button>
<a-radio-button value="discharge" class="wallet-charge-form__radio wallet-charge-form__radio--discharge">
<span class="wallet-charge-form__radio-icon">−</span>
دشارژ
</a-radio-button>
</a-radio-group>
</a-form-item>
<div class="wallet-charge-form__preview" :class="previewClass">
<span class="wallet-charge-form__preview-sign">{{ previewSign }}</span>
<span class="wallet-charge-form__preview-text">{{ previewText }}</span>
</div>
<a-form-item name="talabBedehi">
<a-checkbox v-model:checked="form.talabBedehi">طلب/بدهی</a-checkbox>
</a-form-item>
<a-form-item :label="amountLabel" name="amountAbs" :rules="amountRules">
<BasicInput
v-model:value="form.amountAbs"
:addon-before="unit"
:type="variant === 'money' ? 'price' : 'number'"
:place-holder="amountPlaceholder"
/>
<div v-if="variant === 'money' && Number(form.amountAbs) > 10" class="wallet-charge-form__hint">
معادل {{ usePrice(Number(form.amountAbs) / 10, true, 'تومان') }}
</div>
</a-form-item>
<a-form-item :label="noteLabel" name="note" :rules="inputRules()">
<BasicInput v-model:value="form.note" :place-holder="notePlaceholder" />
</a-form-item>
</a-form>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { FormInstance } from 'ant-design-vue'
import type { Charge } from '@/model/wallet'
import { inputRules } from '@/utils/inputRules'
import { usePrice } from '@core/utils/usePrice'
const props = defineProps<{
variant: 'money' | 'gold'
modelValue: Charge
}>()
const emit = defineEmits<{
'update:modelValue': [value: Charge]
}>()
const form = ref<Charge>({ ...props.modelValue })
watch(
() => props.modelValue,
(value) => {
form.value = { ...value }
},
{ deep: true }
)
watch(
form,
(value) => {
emit('update:modelValue', { ...value })
},
{ deep: true }
)
const formRef = ref<FormInstance>()
const unit = computed(() => (props.variant === 'money' ? 'ریال' : 'گرم'))
const isDischarge = computed(() => form.value.direction === 'discharge')
const formClass = computed(() =>
isDischarge.value ? 'wallet-charge-form--discharge' : 'wallet-charge-form--charge'
)
const previewClass = computed(() =>
isDischarge.value
? 'wallet-charge-form__preview--discharge'
: 'wallet-charge-form__preview--charge'
)
const previewSign = computed(() => (isDischarge.value ? '−' : '+'))
const previewText = computed(() => {
const action = isDischarge.value ? 'کسر از' : 'افزایش'
const wallet = props.variant === 'money' ? 'موجودی ریالی' : 'موجودی طلایی'
return `${action} ${wallet} کاربر`
})
const amountLabel = computed(() =>
isDischarge.value ? `مقدار دشارژ (${unit.value})` : `مقدار شارژ (${unit.value})`
)
const noteLabel = computed(() => (isDischarge.value ? 'علت دشارژ' : 'علت شارژ'))
const amountPlaceholder = computed(() =>
props.variant === 'money' ? 'مثلاً ۱۰۰٬۰۰۰' : 'مثلاً ۰.۵'
)
const notePlaceholder = computed(() =>
isDischarge.value ? 'دلیل کسر موجودی' : 'دلیل افزایش موجودی'
)
const amountRules = [
...inputRules('مقدار'),
{
validator: (_rule: unknown, value: string | number | undefined) => {
const num = Math.abs(Number(value) || 0)
if (!num) {
return Promise.reject('مقدار باید بیشتر از صفر باشد')
}
return Promise.resolve()
}
}
]
defineExpose({
validateFields: () => formRef.value?.validateFields()
})
</script>
<style scoped>
.wallet-charge-form__direction :deep(.ant-radio-button-wrapper) {
width: 50%;
text-align: center;
height: 2.75rem;
line-height: 2.65rem;
font-weight: 700;
}
.wallet-charge-form__radio-icon {
display: inline-block;
margin-left: 0.35rem;
font-size: 1.1rem;
font-weight: 800;
}
.wallet-charge-form__preview {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
padding: 0.85rem 1rem;
border-radius: 0.75rem;
border: 1px solid transparent;
font-size: 0.9rem;
font-weight: 600;
}
.wallet-charge-form__preview-sign {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.75rem;
height: 1.75rem;
border-radius: 9999px;
font-size: 1.15rem;
font-weight: 800;
flex-shrink: 0;
}
.wallet-charge-form__preview--charge {
background: rgba(34, 197, 94, 0.12);
border-color: rgba(34, 197, 94, 0.35);
color: #86efac;
}
.wallet-charge-form__preview--charge .wallet-charge-form__preview-sign {
background: rgba(34, 197, 94, 0.2);
color: #4ade80;
}
.wallet-charge-form__preview--discharge {
background: rgba(239, 68, 68, 0.12);
border-color: rgba(239, 68, 68, 0.35);
color: #fca5a5;
}
.wallet-charge-form__preview--discharge .wallet-charge-form__preview-sign {
background: rgba(239, 68, 68, 0.2);
color: #f87171;
}
.wallet-charge-form__hint {
margin-top: 0.35rem;
font-size: 0.75rem;
opacity: 0.75;
}
.wallet-charge-form__direction :deep(.ant-radio-button-wrapper-checked.wallet-charge-form__radio--charge) {
background: #15803d !important;
border-color: #15803d !important;
color: #fff !important;
}
.wallet-charge-form__direction :deep(.ant-radio-button-wrapper-checked.wallet-charge-form__radio--discharge) {
background: #b91c1c !important;
border-color: #b91c1c !important;
color: #fff !important;
}
</style>