Files
boursecu_admin/src/pages/menuPages/customers/base/components/WalletChargeForm.vue
T

220 lines
6.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>