174 lines
4.6 KiB
Vue
174 lines
4.6 KiB
Vue
<template>
|
|
<div class="wallet-charge-modal-body">
|
|
<div v-if="showCustomerSelect" class="wallet-charge-modal-body__section">
|
|
<label class="wallet-charge-modal-body__label">مشتری</label>
|
|
<a-select
|
|
v-model:value="customerIdProxy"
|
|
show-search
|
|
allow-clear
|
|
placeholder="انتخاب کنید"
|
|
class="w-full"
|
|
size="middle"
|
|
:options="customerOptions"
|
|
:loading="customersLoading"
|
|
:filter-option="filterCustomer"
|
|
/>
|
|
</div>
|
|
|
|
<div v-if="resolvedCustomerId && !targetsLoading" class="wallet-charge-modal-body__assets">
|
|
<CustomerWalletBalancePanel
|
|
:customer-id="resolvedCustomerId"
|
|
:charge-targets="targets"
|
|
:selected-charge-key="selectedTargetKey"
|
|
compact
|
|
@select-charge-target="selectedTargetKeyProxy = $event"
|
|
/>
|
|
</div>
|
|
|
|
<div class="wallet-charge-modal-body__section">
|
|
<label class="wallet-charge-modal-body__label">محصول / کیف پول</label>
|
|
<a-spin :spinning="targetsLoading">
|
|
<a-select
|
|
v-model:value="selectedTargetKeyProxy"
|
|
show-search
|
|
class="w-full"
|
|
:options="targetOptions"
|
|
placeholder="انتخاب کنید"
|
|
:filter-option="filterTarget"
|
|
/>
|
|
</a-spin>
|
|
</div>
|
|
|
|
<WalletChargeForm
|
|
ref="formRef"
|
|
:model-value="formCharge"
|
|
:unit-label="selectedTarget?.unit ?? 'ریال'"
|
|
:is-money="selectedTarget?.kind === 'money'"
|
|
:wallet-label="selectedTarget?.label"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref, watch } from 'vue'
|
|
import WalletChargeForm from '@/pages/menuPages/customers/base/components/WalletChargeForm.vue'
|
|
import CustomerWalletBalancePanel from '@/components/customer/CustomerWalletBalancePanel.vue'
|
|
import { getCustomersList } from '@/api/customer'
|
|
import type { Charge, ChargeTarget } from '@/model/wallet'
|
|
import type { Customer } from '@/model/customer'
|
|
|
|
const props = defineProps<{
|
|
formCharge: Charge
|
|
selectedTargetKey: string
|
|
customerId?: number | null
|
|
showCustomerSelect?: boolean
|
|
targets: ChargeTarget[]
|
|
targetsLoading?: boolean
|
|
selectedTarget?: ChargeTarget
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:formCharge', value: Charge): void
|
|
(e: 'update:selectedTargetKey', value: string): void
|
|
}>()
|
|
|
|
const formRef = ref<InstanceType<typeof WalletChargeForm>>()
|
|
const customers = ref<Customer[]>([])
|
|
const customersLoading = ref(false)
|
|
|
|
const formCharge = computed({
|
|
get: () => props.formCharge,
|
|
set: (value: Charge) => emit('update:formCharge', value),
|
|
})
|
|
|
|
const selectedTargetKeyProxy = computed({
|
|
get: () => props.selectedTargetKey,
|
|
set: (value: string) => emit('update:selectedTargetKey', value),
|
|
})
|
|
|
|
const resolvedCustomerId = computed(
|
|
() => props.formCharge.customer_id ?? props.customerId ?? undefined,
|
|
)
|
|
|
|
const customerIdProxy = computed({
|
|
get: () => formCharge.value.customer_id ?? undefined,
|
|
set: (value: number | undefined) => {
|
|
emit('update:formCharge', { ...formCharge.value, customer_id: value })
|
|
},
|
|
})
|
|
|
|
const customerOptions = computed(() =>
|
|
customers.value.map((customer) => ({
|
|
value: customer.id,
|
|
label: `${customer.name ?? ''} — ${customer.mobile ?? ''}`.trim(),
|
|
})),
|
|
)
|
|
|
|
const targetOptions = computed(() =>
|
|
props.targets.map((target) => ({
|
|
value: target.key,
|
|
label: target.label,
|
|
})),
|
|
)
|
|
|
|
function filterCustomer(input: string, option?: { label?: string }) {
|
|
return String(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
|
|
}
|
|
|
|
function filterTarget(input: string, option?: { label?: string }) {
|
|
return String(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
|
|
}
|
|
|
|
async function loadCustomers() {
|
|
if (!props.showCustomerSelect) return
|
|
customersLoading.value = true
|
|
try {
|
|
customers.value = (await getCustomersList()) ?? []
|
|
} catch (e) {
|
|
console.error(e)
|
|
} finally {
|
|
customersLoading.value = false
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => props.showCustomerSelect,
|
|
(show) => {
|
|
if (show) void loadCustomers()
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
defineExpose({
|
|
validateFields: () => formRef.value?.validateFields?.(),
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.wallet-charge-modal-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
padding: 0 0.75rem 0.25rem;
|
|
}
|
|
|
|
.wallet-charge-modal-body__assets {
|
|
margin-bottom: 0.75rem;
|
|
width: 100%;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.wallet-charge-modal-body__section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.35rem;
|
|
}
|
|
|
|
.wallet-charge-modal-body__label {
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
color: var(--admin-text-secondary, #64748b);
|
|
}
|
|
</style>
|