fix bugs and added some feature for withdraw handling
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-model:visible="visibleProxy"
|
||||
:width="isMobile ? '92vw' : '28rem'"
|
||||
title="ویرایش کد حسابداری"
|
||||
ok-text="ذخیره"
|
||||
:loading="loading"
|
||||
@ok="submit"
|
||||
@close="close"
|
||||
>
|
||||
<div class="flex flex-col gap-3">
|
||||
<p class="m-0 text-sm" style="color: var(--admin-text-secondary)">
|
||||
مشتری:
|
||||
<strong class="text-[var(--admin-text)]">{{ customer?.name || '—' }}</strong>
|
||||
</p>
|
||||
<a-form layout="vertical">
|
||||
<a-form-item label="کد حسابداری" class="mb-0">
|
||||
<BasicInput
|
||||
v-model:value="code"
|
||||
placeholder="کد حسابداری را وارد کنید"
|
||||
dir="ltr"
|
||||
class="text-left"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<p class="m-0 text-xs" style="color: var(--admin-text-secondary)">
|
||||
برای پاک کردن کد، فیلد را خالی بگذارید و ذخیره کنید.
|
||||
</p>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import BasicModal from '@/components/BasicModal.vue'
|
||||
import { updateCustomer } from '@/api/customer'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import type { AccountingProvider } from '@/utils/config'
|
||||
import { displayAccountingCode, normalizeAccountingCode } from '@/utils/accountingCode'
|
||||
import { isMobile } from '@core/utils/is'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
customer: Customer | null
|
||||
provider: AccountingProvider
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void
|
||||
(e: 'success'): void
|
||||
}>()
|
||||
|
||||
const loading = ref(false)
|
||||
const code = ref('')
|
||||
|
||||
const visibleProxy = computed({
|
||||
get: () => props.visible,
|
||||
set: (value: boolean) => emit('update:visible', value),
|
||||
})
|
||||
|
||||
function currentCodeOf(customer: Customer | null): string {
|
||||
if (!customer) return ''
|
||||
if (props.provider === 'pargar') return displayAccountingCode(customer.pargar_account_id)
|
||||
if (props.provider === 'tahesab') return displayAccountingCode(customer.moshtari_code)
|
||||
return ''
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [props.visible, props.customer, props.provider] as const,
|
||||
([visible]) => {
|
||||
if (!visible) return
|
||||
const shown = currentCodeOf(props.customer)
|
||||
code.value = shown === '-' ? '' : shown
|
||||
}
|
||||
)
|
||||
|
||||
function close() {
|
||||
visibleProxy.value = false
|
||||
}
|
||||
|
||||
async function submit() {
|
||||
if (!props.customer?.id) return
|
||||
if (props.provider !== 'pargar' && props.provider !== 'tahesab') {
|
||||
message.error('حسابداری فعال نیست.')
|
||||
return
|
||||
}
|
||||
|
||||
const normalized = normalizeAccountingCode(code.value)
|
||||
const payload =
|
||||
props.provider === 'pargar'
|
||||
? { pargar_account_id: normalized }
|
||||
: { moshtari_code: normalized }
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
await updateCustomer(props.customer.id, payload as Customer)
|
||||
message.success('کد حسابداری ذخیره شد.')
|
||||
emit('success')
|
||||
close()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -29,6 +29,7 @@
|
||||
@toggleTrade="forward('toggleTrade', $event)"
|
||||
@confirmUser="forwardAndClose('confirmUser', $event)"
|
||||
@sendSms="forwardAndClose('sendSms', $event)"
|
||||
@editAccounting="forwardAndClose('editAccounting', $event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -59,6 +60,7 @@ const emit = defineEmits<{
|
||||
(e: 'toggleTrade', item: Customer): void
|
||||
(e: 'confirmUser', item: Customer): void
|
||||
(e: 'sendSms', item: Customer): void
|
||||
(e: 'editAccounting', item: Customer): void
|
||||
}>()
|
||||
|
||||
const { sheetVisible, selectedItem, openSheet, syncSelectedItem } = useMobileDetailSheet<Customer>()
|
||||
@@ -72,6 +74,7 @@ type SheetAction =
|
||||
| 'toggleTrade'
|
||||
| 'confirmUser'
|
||||
| 'sendSms'
|
||||
| 'editAccounting'
|
||||
|
||||
function forward(action: SheetAction, item: Customer) {
|
||||
emit(action, item)
|
||||
|
||||
@@ -37,6 +37,15 @@
|
||||
</BaseButton>
|
||||
|
||||
<div class="customer-mobile-sheet__actions">
|
||||
<BaseButton
|
||||
v-if="accountingCodeLabel"
|
||||
size="small"
|
||||
type="default"
|
||||
icon="vuesax-linear:card-edit"
|
||||
@click="closeAndEmit('editAccounting', row)"
|
||||
>
|
||||
کد حسابداری
|
||||
</BaseButton>
|
||||
<BaseButton size="small" type="default" icon="vuesax-linear:stickynote" @click="closeAndEmit('info', row)">
|
||||
مشخصات
|
||||
</BaseButton>
|
||||
@@ -84,6 +93,11 @@
|
||||
|
||||
<MobileInfoGrid>
|
||||
<MobileDetailRow label="کد کاربری" :value="row.id ?? '-'" />
|
||||
<MobileDetailRow
|
||||
v-if="accountingCodeLabel"
|
||||
:label="accountingCodeLabel"
|
||||
:value="accountingCodeOf(row)"
|
||||
/>
|
||||
<MobileDetailRow label="کد معرف" :value="row.referral_id ?? '-'" />
|
||||
<MobileDetailRow label="نام معرف" :value="row.referral?.name ?? '-'" />
|
||||
<MobileDetailRow label="آخرین بازدید" :value="lastSeen(row)" value-class="text-xs" />
|
||||
@@ -94,7 +108,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { Modal } from 'ant-design-vue'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import type { ChargeTarget } from '@/model/wallet'
|
||||
@@ -105,7 +119,13 @@ import MobileDetailSheet from '@/components/mobile/MobileDetailSheet.vue'
|
||||
import MobileInfoGrid from '@/components/mobile/MobileInfoGrid.vue'
|
||||
import CustomerWalletBalancePanel from '@/components/customer/CustomerWalletBalancePanel.vue'
|
||||
import { toJalali } from '@core/utils/useDataTime'
|
||||
import { customerDirectSmsEnabledSetting } from '@/utils/config'
|
||||
import {
|
||||
accountingProviderSetting,
|
||||
customerDirectSmsEnabledSetting,
|
||||
initAccountingSettingsFromApi
|
||||
} from '@/utils/config'
|
||||
import { displayAccountingCode } from '@/utils/accountingCode'
|
||||
import { displayAccountingCode } from '@/utils/accountingCode'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
@@ -122,11 +142,29 @@ const emit = defineEmits<{
|
||||
(e: 'toggleTrade', item: Customer): void
|
||||
(e: 'confirmUser', item: Customer): void
|
||||
(e: 'sendSms', item: Customer): void
|
||||
(e: 'editAccounting', item: Customer): void
|
||||
}>()
|
||||
|
||||
const chargeTargets = ref<ChargeTarget[]>([])
|
||||
const customerDirectSmsEnabled = customerDirectSmsEnabledSetting
|
||||
|
||||
const accountingCodeLabel = computed(() => {
|
||||
const provider = accountingProviderSetting.value
|
||||
if (provider === 'pargar' || provider === 'tahesab') return 'کد حسابداری'
|
||||
return null
|
||||
})
|
||||
|
||||
function accountingCodeOf(row: Customer) {
|
||||
const provider = accountingProviderSetting.value
|
||||
if (provider === 'pargar') return displayAccountingCode(row.pargar_account_id)
|
||||
if (provider === 'tahesab') return displayAccountingCode(row.moshtari_code)
|
||||
return '-'
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void initAccountingSettingsFromApi()
|
||||
})
|
||||
|
||||
const visibleProxy = computed({
|
||||
get: () => props.visible,
|
||||
set: (value: boolean) => emit('update:visible', value),
|
||||
@@ -134,7 +172,7 @@ const visibleProxy = computed({
|
||||
|
||||
const sheetTitle = computed(() => props.item?.name?.trim() || 'مشتری')
|
||||
|
||||
type SheetEmit = 'archive' | 'chargeWallet' | 'info' | 'confirmUser' | 'edit' | 'sendSms'
|
||||
type SheetEmit = 'archive' | 'chargeWallet' | 'info' | 'confirmUser' | 'edit' | 'sendSms' | 'editAccounting'
|
||||
|
||||
function closeAndEmit(event: SheetEmit, row: Customer) {
|
||||
visibleProxy.value = false
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
افزودن مشتری
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #accountingCode="{ record }">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-1.5 border-none bg-transparent p-0 text-sm cursor-pointer"
|
||||
style="color: var(--admin-text)"
|
||||
@click="openAccountingCodeEdit(record)"
|
||||
>
|
||||
<span dir="ltr">{{ accountingCodeOf(record) }}</span>
|
||||
<Icon icon="vuesax-linear:edit-2" size="16" color="#4572E9" />
|
||||
</button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<div class="gap-2 hidden md:flex justify-center">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
@@ -54,7 +65,7 @@
|
||||
<Icon icon="vuesax-linear:wallet-add" color="#9333ea" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="tahesabEnabled && !record.moshtari_code"
|
||||
v-if="tahesabEnabled && !isValidAccountingCode(record.moshtari_code)"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openTahesabRegister(record)"
|
||||
@@ -63,7 +74,7 @@
|
||||
<Icon icon="vuesax-linear:profile-add" color="#CA8A04" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="pargarEnabled && !record.pargar_account_id"
|
||||
v-if="pargarEnabled && !isValidAccountingCode(record.pargar_account_id)"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openPargarRegister(record)"
|
||||
@@ -71,6 +82,15 @@
|
||||
<template #title><span>در پرگار ثبت نشده — کلیک برای ثبت</span></template>
|
||||
<Icon icon="vuesax-linear:profile-add" color="#7C3AED" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="accountingEnabled"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openAccountingCodeEdit(record)"
|
||||
>
|
||||
<template #title><span>ویرایش کد حسابداری</span></template>
|
||||
<Icon icon="vuesax-linear:card-edit" color="#0d9488" />
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('info', record)">
|
||||
<template #title><span>مشخصات</span></template>
|
||||
<Icon icon="vuesax-linear:stickynote" color="#10913A" />
|
||||
@@ -127,11 +147,19 @@
|
||||
@toggleTrade="(item) => changeCustomerOrderActivationFunction(item.id)"
|
||||
@confirmUser="openConfirmUser"
|
||||
@sendSms="openDirectSms"
|
||||
@editAccounting="openAccountingCodeEdit"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CustomerDirectSmsModal v-model:visible="directSmsVisible" :customer="directSmsCustomer" />
|
||||
|
||||
<CustomerAccountingCodeModal
|
||||
v-model:visible="accountingCodeVisible"
|
||||
:customer="accountingCodeCustomer"
|
||||
:provider="accountingProviderSetting"
|
||||
@success="fetch"
|
||||
/>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="confirmVisible"
|
||||
:width="isMobile ? '92vw' : '50vw'"
|
||||
@@ -178,7 +206,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import { ref } from 'vue'
|
||||
import { onMounted, ref, computed } from 'vue'
|
||||
import {
|
||||
changeCustomerActivation,
|
||||
changeCustomerArchive,
|
||||
@@ -189,6 +217,7 @@ import {
|
||||
import { buildCustomerColumns } from '@/pages/menuPages/customers/base/hooks/customerColumns'
|
||||
import CustomerMobileCardList from '@/pages/menuPages/customers/base/components/CustomerMobileCardList.vue'
|
||||
import CustomerDirectSmsModal from '@/pages/menuPages/customers/base/components/CustomerDirectSmsModal.vue'
|
||||
import CustomerAccountingCodeModal from '@/pages/menuPages/customers/base/components/CustomerAccountingCodeModal.vue'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
@@ -201,10 +230,12 @@ import PargarRetryModal from '@/components/PargarRetryModal.vue'
|
||||
import {
|
||||
tahesabEnabledSetting,
|
||||
pargarEnabledSetting,
|
||||
accountingProviderSetting,
|
||||
customerDirectSmsEnabledSetting,
|
||||
initAccountingSettingsFromApi,
|
||||
initWalletSettingsFromApi
|
||||
} from '@/utils/config'
|
||||
import { displayAccountingCode, isValidAccountingCode } from '@/utils/accountingCode'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeWallet'])
|
||||
@@ -219,16 +250,43 @@ const pargarRegisterVisible = ref(false)
|
||||
const pargarCustomer = ref<Customer>()
|
||||
const pargarEnabled = pargarEnabledSetting
|
||||
const customerDirectSmsEnabled = customerDirectSmsEnabledSetting
|
||||
const accountingCodeVisible = ref(false)
|
||||
const accountingCodeCustomer = ref<Customer | null>(null)
|
||||
const accountingEnabled = computed(() => {
|
||||
const provider = accountingProviderSetting.value
|
||||
return provider === 'pargar' || provider === 'tahesab'
|
||||
})
|
||||
|
||||
function accountingCodeOf(record: Customer) {
|
||||
const provider = accountingProviderSetting.value
|
||||
if (provider === 'pargar') return displayAccountingCode(record.pargar_account_id)
|
||||
if (provider === 'tahesab') return displayAccountingCode(record.moshtari_code)
|
||||
return '-'
|
||||
}
|
||||
|
||||
function openAccountingCodeEdit(user: Customer) {
|
||||
accountingCodeCustomer.value = user
|
||||
accountingCodeVisible.value = true
|
||||
}
|
||||
const directSmsVisible = ref(false)
|
||||
const directSmsCustomer = ref<Customer | null>(null)
|
||||
const mobileListRef = ref<null | { fetch: () => Promise<void> }>(null)
|
||||
const catalogMetals = ref<Parameters<typeof buildCustomerColumns>[0]>([])
|
||||
|
||||
function rebuildColumns(metals = catalogMetals.value) {
|
||||
catalogMetals.value = metals
|
||||
tblProps.value.columns = buildCustomerColumns(metals, {
|
||||
accountingProvider: accountingProviderSetting.value
|
||||
})
|
||||
}
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: buildCustomerColumns(),
|
||||
columns: buildCustomerColumns([], { accountingProvider: accountingProviderSetting.value }),
|
||||
api: async (params: TableInput) => {
|
||||
await initAccountingSettingsFromApi()
|
||||
const data = await getCustomerTable(params)
|
||||
const metals = data?.catalogMetals ?? []
|
||||
tblProps.value.columns = buildCustomerColumns(metals)
|
||||
rebuildColumns(metals)
|
||||
return data
|
||||
}
|
||||
})
|
||||
|
||||
@@ -5,10 +5,34 @@ import { usePrice } from '@core/utils/usePrice'
|
||||
import { getCashBalance } from '@/components/mobile/utils/wallet'
|
||||
import { customerWalletMetalBalanceTitle } from '@/utils/adminMetalLabels'
|
||||
import { formatMetalDisplayValue, metalCellValue } from '@/utils/metalWeight'
|
||||
import type { AccountingProvider } from '@/utils/config'
|
||||
|
||||
export type CustomerMetalColumn = { metal_id: number; label: string; display_unit?: string }
|
||||
|
||||
export function buildCustomerColumns(metals: CustomerMetalColumn[] = []): BaseTableColumn[] {
|
||||
export type CustomerColumnOptions = {
|
||||
accountingProvider?: AccountingProvider
|
||||
}
|
||||
|
||||
function accountingCodeColumn(provider: AccountingProvider | undefined): BaseTableColumn | null {
|
||||
if (provider === 'pargar' || provider === 'tahesab') {
|
||||
return {
|
||||
title: 'کد حسابداری',
|
||||
dataIndex: provider === 'pargar' ? 'pargar_account_id' : 'moshtari_code',
|
||||
key: 'accounting_code',
|
||||
type: 'Text',
|
||||
filterable: false,
|
||||
slot: 'accountingCode'
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function buildCustomerColumns(
|
||||
metals: CustomerMetalColumn[] = [],
|
||||
options: CustomerColumnOptions = {}
|
||||
): BaseTableColumn[] {
|
||||
const accountingColumn = accountingCodeColumn(options.accountingProvider)
|
||||
|
||||
const baseColumns: BaseTableColumn[] = [
|
||||
{
|
||||
title: 'ردیف',
|
||||
@@ -26,6 +50,7 @@ export function buildCustomerColumns(metals: CustomerMetalColumn[] = []): BaseTa
|
||||
key: 'id',
|
||||
type: 'Number'
|
||||
},
|
||||
...(accountingColumn ? [accountingColumn] : []),
|
||||
{
|
||||
title: 'نام و نام خانوادگی',
|
||||
dataIndex: 'name',
|
||||
|
||||
@@ -153,6 +153,11 @@
|
||||
|
||||
<div class="grid min-w-0 grid-cols-2 gap-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
|
||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||
<BasicInfoItem
|
||||
v-if="accountingCodeVisible"
|
||||
title="کد حسابداری"
|
||||
:value="accountingCodeValue"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||
@@ -246,7 +251,7 @@
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import { ref, watch, computed, onMounted } from 'vue'
|
||||
import tbl from './components/table.vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import BasicInfoModal from '@/components/BasicInfoModal/index.vue'
|
||||
@@ -277,6 +282,11 @@ import type { ChargeTarget } from '@/model/wallet'
|
||||
import { metalLabel } from '@/utils/adminMetalLabels'
|
||||
import type { DashboardHelp } from '@/pages/dashboard/dashboardSectionCopy'
|
||||
import DashboardLabelWithHelp from '@/pages/dashboard/components/DashboardLabelWithHelp.vue'
|
||||
import {
|
||||
accountingProviderSetting,
|
||||
initAccountingSettingsFromApi
|
||||
} from '@/utils/config'
|
||||
import { displayAccountingCode } from '@/utils/accountingCode'
|
||||
|
||||
const fnameHelp: DashboardHelp = {
|
||||
description: 'نام کوچک مشتری که در اپ و پنل نمایش داده میشود.',
|
||||
@@ -511,9 +521,7 @@ const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCus
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
await initAccountingSettingsFromApi()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@@ -533,6 +541,18 @@ async function loadInfoChargeTargets() {
|
||||
}
|
||||
const userInfo = ref<Customer>()
|
||||
|
||||
const accountingCodeVisible = computed(() => {
|
||||
const provider = accountingProviderSetting.value
|
||||
return provider === 'pargar' || provider === 'tahesab'
|
||||
})
|
||||
|
||||
const accountingCodeValue = computed(() => {
|
||||
const provider = accountingProviderSetting.value
|
||||
if (provider === 'pargar') return displayAccountingCode(userInfo.value?.pargar_account_id)
|
||||
if (provider === 'tahesab') return displayAccountingCode(userInfo.value?.moshtari_code)
|
||||
return '-'
|
||||
})
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
|
||||
Reference in New Issue
Block a user