220 lines
6.3 KiB
Vue
220 lines
6.3 KiB
Vue
<template>
|
||
<a-form
|
||
:model="modelValue"
|
||
ref="formRef"
|
||
autocomplete="off"
|
||
class="wallet-charge-form"
|
||
:class="formClass"
|
||
>
|
||
<a-form-item label="نوع عملیات" name="direction">
|
||
<a-radio-group
|
||
v-model:value="modelValue.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="modelValue.talabBedehi">طلب/بدهی</a-checkbox>
|
||
</a-form-item>
|
||
|
||
<a-form-item :label="amountLabel" name="amountAbs" :rules="amountRules">
|
||
<BasicInput
|
||
v-model:value="modelValue.amountAbs"
|
||
:addon-before="resolvedUnit"
|
||
:type="resolvedInputType"
|
||
:place-holder="amountPlaceholder"
|
||
/>
|
||
<div v-if="isMoney && Number(modelValue.amountAbs) > 10" class="wallet-charge-form__hint">
|
||
معادل {{ usePrice(Number(modelValue.amountAbs) / 10, true, 'تومان') }}
|
||
</div>
|
||
</a-form-item>
|
||
|
||
<a-form-item :label="noteLabel" name="note" :rules="inputRules()">
|
||
<BasicInput v-model:value="modelValue.note" :place-holder="notePlaceholder" />
|
||
</a-form-item>
|
||
</a-form>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, ref } 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 = withDefaults(
|
||
defineProps<{
|
||
/** @deprecated از unitLabel و isMoney استفاده کنید */
|
||
variant?: 'money' | 'gold'
|
||
modelValue: Charge
|
||
/** واحد نمایش: ریال، گرم، عدد، ... */
|
||
unitLabel?: string
|
||
/** true = ورودی قیمتی (ریال)، false = عددی */
|
||
isMoney?: boolean
|
||
/** نام کیف پول برای پیشنمایش */
|
||
walletLabel?: string
|
||
}>(),
|
||
{
|
||
variant: 'money',
|
||
},
|
||
)
|
||
|
||
const formRef = ref<FormInstance>()
|
||
|
||
const resolvedUnit = computed(
|
||
() => props.unitLabel ?? (props.variant === 'money' ? 'ریال' : 'گرم'),
|
||
)
|
||
const isMoney = computed(() => props.isMoney ?? props.variant === 'money')
|
||
const resolvedInputType = computed(() => (isMoney.value ? 'price' : 'number'))
|
||
const isDischarge = computed(() => props.modelValue.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.walletLabel ?? (isMoney.value ? 'موجودی ریالی' : 'موجودی محصول')
|
||
return `${action} ${wallet} کاربر`
|
||
})
|
||
|
||
const amountLabel = computed(() =>
|
||
isDischarge.value ? `مقدار دشارژ (${resolvedUnit.value})` : `مقدار شارژ (${resolvedUnit.value})`,
|
||
)
|
||
|
||
const noteLabel = computed(() => (isDischarge.value ? 'علت دشارژ' : 'علت شارژ'))
|
||
|
||
const amountPlaceholder = computed(() =>
|
||
isMoney.value ? 'مثلاً ۱۰۰٬۰۰۰' : 'مثلاً ۰.۵',
|
||
)
|
||
|
||
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 :deep(.ant-form-item) {
|
||
margin-bottom: 0.65rem;
|
||
}
|
||
|
||
.wallet-charge-form__direction :deep(.ant-radio-button-wrapper) {
|
||
width: 50%;
|
||
text-align: center;
|
||
height: 2.35rem;
|
||
line-height: 2.25rem;
|
||
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.5rem;
|
||
margin-bottom: 0.5rem;
|
||
padding: 0.55rem 0.75rem;
|
||
border-radius: 0.6rem;
|
||
border: 1px solid transparent;
|
||
font-size: 0.8125rem;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.wallet-charge-form__preview-sign {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 1.45rem;
|
||
height: 1.45rem;
|
||
border-radius: 9999px;
|
||
font-size: 1rem;
|
||
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>
|