diff --git a/components.d.ts b/components.d.ts index 4c90676..4b61d74 100644 --- a/components.d.ts +++ b/components.d.ts @@ -83,6 +83,7 @@ declare module '@vue/runtime-core' { CustomTag: typeof import('./src/components/CustomTag.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + TahesabRetryModal: typeof import('./src/components/TahesabRetryModal.vue')['default'] ThemeMenuSection: typeof import('./src/core/components/ThemeMenuSection.vue')['default'] ThemeToggle: typeof import('./src/core/components/ThemeToggle.vue')['default'] UploadPic: typeof import('./src/components/UploadPic.vue')['default'] diff --git a/src/api/tahesab.ts b/src/api/tahesab.ts new file mode 100644 index 0000000..eba759d --- /dev/null +++ b/src/api/tahesab.ts @@ -0,0 +1,36 @@ +import useAxios from '@core/utils/useAxios' +import type { TableInput } from '@core/type/baseTable' + +export interface TahesabRecord { + id: number + customer_id?: number + amount?: number + desc?: string + type?: string + sync_status?: 'pending' | 'success' | 'failed' + sync_log?: string | null + tahesab_id?: string | null + data?: string | null + res?: string | null + created_at?: string + customer?: { + id?: number + name?: string + mobile?: string + moshtari_code?: string | number | null + } +} + +export const getTahesabTable = async (params: TableInput) => + await useAxios.post('/admin/tahesab/table', params) + +export const getTahesabDetail = async (id: number) => + await useAxios.get(`/admin/tahesab/${id}`) + +export const retryTahesabSanad = async (id: number) => + await useAxios.post<{ ok: boolean; message: string; tahesab?: TahesabRecord }>(`/admin/tahesab/${id}/retry`) + +export const registerCustomerInTahesab = async (customerId: number) => + await useAxios.post<{ ok: boolean; message: string; moshtari_code?: string | number }>( + `/admin/customer/${customerId}/tahesab/register` + ) diff --git a/src/components/TahesabRetryModal.vue b/src/components/TahesabRetryModal.vue new file mode 100644 index 0000000..339e547 --- /dev/null +++ b/src/components/TahesabRetryModal.vue @@ -0,0 +1,126 @@ + + + diff --git a/src/model/customer.ts b/src/model/customer.ts index bc2d816..e232b88 100644 --- a/src/model/customer.ts +++ b/src/model/customer.ts @@ -36,5 +36,6 @@ export interface Customer { trade_active: boolean type_str: string gold: number + moshtari_code?: string | number | null // print_name: string } diff --git a/src/pages/menuPages/accounting/components/table.vue b/src/pages/menuPages/accounting/components/table.vue index 9a10612..8198534 100644 --- a/src/pages/menuPages/accounting/components/table.vue +++ b/src/pages/menuPages/accounting/components/table.vue @@ -5,6 +5,24 @@ diff --git a/src/pages/menuPages/accounting/components/tahesabTable.vue b/src/pages/menuPages/accounting/components/tahesabTable.vue new file mode 100644 index 0000000..a13bf6e --- /dev/null +++ b/src/pages/menuPages/accounting/components/tahesabTable.vue @@ -0,0 +1,134 @@ + + + diff --git a/src/pages/menuPages/accounting/hooks/accountingColumns.tsx b/src/pages/menuPages/accounting/hooks/accountingColumns.tsx index a95fcab..2deccce 100644 --- a/src/pages/menuPages/accounting/hooks/accountingColumns.tsx +++ b/src/pages/menuPages/accounting/hooks/accountingColumns.tsx @@ -22,7 +22,7 @@ const filteredDocTypes: FilterSelect = docTypes?.map((x: DocItem) => { } })*/ -export function getAccountingColumns(): BaseTableColumn[] { +export function getAccountingColumns(showTahesab = false): BaseTableColumn[] { return [ { title: 'ردیف', @@ -76,6 +76,25 @@ export function getAccountingColumns(): BaseTableColumn[] { key: 'note', type: 'Text', }, + ...(showTahesab + ? [ + { + title: 'ته‌حساب', + dataIndex: 'tahesab_sync_status', + key: 'tahesab_sync_status', + type: 'Text', + filterable: false, + customRender: (record: any) => { + const row = record.record + if (!row.tahesab_record_id && !row.tahesab_sync_status) return '-' + if (row.tahesab_failed_id) return 'ناموفق' + if (row.tahesab_sync_status === 'success') return 'موفق' + if (row.tahesab_sync_status === 'pending') return 'در انتظار' + return row.tahesab_sync_status ?? '-' + } + } as BaseTableColumn + ] + : []), { title: 'عملیات', dataIndex: 'action', diff --git a/src/pages/menuPages/accounting/index.vue b/src/pages/menuPages/accounting/index.vue index 03cdf51..1f1e526 100644 --- a/src/pages/menuPages/accounting/index.vue +++ b/src/pages/menuPages/accounting/index.vue @@ -1,12 +1,20 @@ @@ -154,6 +172,8 @@ import type { Customer } from '@/model/customer' import { MODAL_ABOVE_ACTION_SHEET_Z_INDEX } from '@/constants/overlayZIndex' import { isMobile } from '@core/utils/is' import { metalLabel } from '@/utils/adminMetalLabels' +import TahesabRetryModal from '@/components/TahesabRetryModal.vue' +import { tahesabEnabledSetting, initTahesabSettingFromApi } from '@/utils/config' const [submit, reload] = useBaseTable() const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold']) @@ -161,6 +181,9 @@ const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'char const loading = ref(false) const confirmVisible = ref(false) const confirmInfo = ref() +const tahesabRegisterVisible = ref(false) +const tahesabCustomer = ref() +const tahesabEnabled = tahesabEnabledSetting const mobileListRef = ref Promise }>(null) const tblProps = ref({ @@ -179,6 +202,10 @@ const fetch = async () => { defineExpose({ fetch }) +onMounted(() => { + void initTahesabSettingFromApi() +}) + async function changeCustomerActivationFunction(id: number) { try { loading.value = true @@ -197,6 +224,11 @@ function openConfirmUser(user: Customer) { confirmVisible.value = true } +function openTahesabRegister(user: Customer) { + tahesabCustomer.value = user + tahesabRegisterVisible.value = true +} + function handleArchive(customer: Customer) { Modal.confirm({ title: 'آیا مشتری را بایگانی می کنید؟', diff --git a/src/pages/menuPages/withdraw/components/table.vue b/src/pages/menuPages/withdraw/components/table.vue index 7d80d50..d6cb15a 100644 --- a/src/pages/menuPages/withdraw/components/table.vue +++ b/src/pages/menuPages/withdraw/components/table.vue @@ -66,6 +66,14 @@ @click="emits('weight', record)" /> + + + + @@ -80,6 +88,14 @@ @weight="(row) => emits('weight', row)" /> + + @@ -98,6 +114,8 @@ import {getWithdrawTable, updateSts} from '@/api/wallet' import WithdrawMobileCardList from './WithdrawMobileCardList.vue' import { isMobile } from '@core/utils/is' import type { WithdrawFlowType } from '../types' +import TahesabRetryModal from '@/components/TahesabRetryModal.vue' +import { initTahesabSettingFromApi, tahesabEnabledSetting } from '@/utils/config' const props = withDefaults( defineProps<{ @@ -110,6 +128,9 @@ const props = withDefaults( const [submit, reload] = useBaseTable() const mobileListRef = ref Promise }>(null) +const tahesabRetryVisible = ref(false) +const selectedTahesabId = ref() +const tahesabEnabled = tahesabEnabledSetting /*const select = (val) => { val.sts === 1 ? return ['1'] : ['2'] }*/ @@ -166,6 +187,12 @@ async function changeCustomerActivationFunction(id: number) { async function fetch() { await Promise.allSettled([reload(), mobileListRef.value?.fetch?.() as Promise]) } + +function openTahesabRetry(record: { tahesab_failed_id?: number }) { + if (!record.tahesab_failed_id) return + selectedTahesabId.value = record.tahesab_failed_id + tahesabRetryVisible.value = true +} // const spinTable = (val: boolean) => { // // console.log('sss') // table?.value?.loading.value = val @@ -175,6 +202,10 @@ defineExpose({ getExportParams: () => ({ ...lastTableParams.value, flow_type: props.flowType }) }) +onMounted(() => { + void initTahesabSettingFromApi() +}) + import { status } from '@/pages/menuPages/withdraw/information/hooks/status' import {toNumber} from "lodash"; const withdrawId = ref(null) diff --git a/src/utils/config.ts b/src/utils/config.ts index 301293f..6ff70b9 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -16,6 +16,11 @@ let settingsBootstrapped = false /** reactive — برای فیلتر منوی «بنرها» در پیکربندی */ export const bannerEnabledSetting = ref(false) +/** reactive — نمایش UI ته‌حsاب در حسابداری و ... */ +export const tahesabEnabledSetting = ref(false) + +let tahesabEnabledFromSettings: boolean | null = null + function isSwitchOn(value: string | undefined | null): boolean { const v = (value ?? '').trim().toLowerCase() return v === 'true' || v === '1' || v === 'yes' @@ -29,6 +34,11 @@ export function setBannerEnabledFromSettings(value: boolean): void { bannerEnabledSetting.value = value } +export function setTahesabEnabledFromSettings(value: boolean): void { + tahesabEnabledFromSettings = value + tahesabEnabledSetting.value = value +} + export function applyBannerEnabledFromRows(rows: Array<{ key?: string; value?: string | null }>) { const row = rows.find((item) => item.key === 'banner_enabled') setBannerEnabledFromSettings(row ? isSwitchOn(row.value) : false) @@ -45,7 +55,9 @@ async function bootstrapSettingsFromApi(): Promise { const isStoreRow = list.find((item) => item.key === 'is_store') const mainWalletRow = list.find((item) => item.key === 'main_wallet_products') const mainMetalRow = list.find((item) => item.key === 'main_metal') + const tahesabRow = list.find((item) => item.key === 'send_to_tahesab') storeModeFromSettings = isStoreRow ? isSwitchOn(isStoreRow.value) : false + setTahesabEnabledFromSettings(tahesabRow ? isSwitchOn(tahesabRow.value) : false) applyBannerEnabledFromRows(list) setCachedMainMetal(mainMetalRow?.value) const { setCachedMainWalletProductIds } = await import('@/components/mobile/utils/wallet') @@ -53,6 +65,7 @@ async function bootstrapSettingsFromApi(): Promise { } catch { storeModeFromSettings = false setBannerEnabledFromSettings(false) + setTahesabEnabledFromSettings(false) setCachedMainMetal(null) const { setCachedMainWalletProductIds } = await import('@/components/mobile/utils/wallet') setCachedMainWalletProductIds([]) @@ -77,3 +90,15 @@ export async function initWalletSettingsFromApi(): Promise { export function isStoreApp(): boolean { return storeModeFromSettings === true } + +export function isTahesabEnabled(): boolean { + return tahesabEnabledFromSettings === true +} + +export async function initTahesabSettingFromApi(): Promise { + if (tahesabEnabledFromSettings !== null) return tahesabEnabledFromSettings === true + + await bootstrapSettingsFromApi() + + return tahesabEnabledFromSettings === true +}