feat: add deposit receipt preview, deposit identifier, and approve/reject modals with SMS
This commit is contained in:
@@ -28,6 +28,12 @@ export const exportWithdrawReport = async (params: TableInput & { flow_type?: st
|
|||||||
export const completeWithdraw = async (params: Withdraw) =>
|
export const completeWithdraw = async (params: Withdraw) =>
|
||||||
await useAxios.post<boolean>('/admin/wallet/withdraw/complete', params)
|
await useAxios.post<boolean>('/admin/wallet/withdraw/complete', params)
|
||||||
|
|
||||||
|
export const approveDeposit = async (params: { id: number; tracked_number?: string }) =>
|
||||||
|
await useAxios.post<{ message: string; withdraw: Withdraw }>('/admin/wallet/deposit/approve', params)
|
||||||
|
|
||||||
|
export const rejectDeposit = async (params: { id: number; reject_reason?: string }) =>
|
||||||
|
await useAxios.post<{ message: string; withdraw: Withdraw }>('/admin/wallet/deposit/reject', params)
|
||||||
|
|
||||||
export const updateSts = async (id: number, sts: Object) => {
|
export const updateSts = async (id: number, sts: Object) => {
|
||||||
return await useAxios.put(`/admin/wallet/withdraw/${id}`, sts)
|
return await useAxios.put(`/admin/wallet/withdraw/${id}`, sts)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -13,10 +13,11 @@ export interface User {
|
|||||||
lname?: string
|
lname?: string
|
||||||
mobile?: number
|
mobile?: number
|
||||||
name?: string
|
name?: string
|
||||||
|
n_code?: string
|
||||||
sts?: number
|
sts?: number
|
||||||
token_sms?: string
|
token_sms?: string
|
||||||
user_type?: string
|
user_type?: string
|
||||||
send_sms?:boolean
|
send_sms?: boolean
|
||||||
settings?: Const[]
|
settings?: Const[]
|
||||||
sms_billing_enabled?: boolean
|
sms_billing_enabled?: boolean
|
||||||
sms_panel_access?: boolean
|
sms_panel_access?: boolean
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ export interface Withdraw {
|
|||||||
date_at?: string
|
date_at?: string
|
||||||
sts?: number
|
sts?: number
|
||||||
type?: number
|
type?: number
|
||||||
|
receipt?: string | null
|
||||||
|
receipt_url?: string | null
|
||||||
|
deposit_identifier?: string | null
|
||||||
|
reject_reason?: string | null
|
||||||
bank_account_id?: number | null
|
bank_account_id?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
updated_at?: string
|
updated_at?: string
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
:item="selectedItem"
|
:item="selectedItem"
|
||||||
@withdraw="(row) => emit('withdraw', row)"
|
@withdraw="(row) => emit('withdraw', row)"
|
||||||
@weight="(row) => emit('weight', row)"
|
@weight="(row) => emit('weight', row)"
|
||||||
|
@approve-deposit="(row) => emit('approveDeposit', row)"
|
||||||
|
@reject-deposit="(row) => emit('rejectDeposit', row)"
|
||||||
@change-status="changeStatusHandler"
|
@change-status="changeStatusHandler"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -53,6 +55,8 @@ const props = withDefaults(
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'withdraw', item: Withdraw): void
|
(e: 'withdraw', item: Withdraw): void
|
||||||
(e: 'weight', item: Withdraw): void
|
(e: 'weight', item: Withdraw): void
|
||||||
|
(e: 'approveDeposit', item: Withdraw): void
|
||||||
|
(e: 'rejectDeposit', item: Withdraw): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { sheetVisible, selectedItem, openSheet, syncSelectedItem } = useMobileDetailSheet<Withdraw>()
|
const { sheetVisible, selectedItem, openSheet, syncSelectedItem } = useMobileDetailSheet<Withdraw>()
|
||||||
|
|||||||
@@ -6,8 +6,24 @@
|
|||||||
<div class="flex w-full items-center justify-between gap-3">
|
<div class="flex w-full items-center justify-between gap-3">
|
||||||
<span class="min-w-0 truncate">{{ sheetTitle }}</span>
|
<span class="min-w-0 truncate">{{ sheetTitle }}</span>
|
||||||
<div class="flex shrink-0 items-center gap-2">
|
<div class="flex shrink-0 items-center gap-2">
|
||||||
|
<template v-if="isPendingDepositRequest(row)">
|
||||||
|
<MobileIconButton
|
||||||
|
plain
|
||||||
|
icon="vuesax-linear:tick-circle"
|
||||||
|
color="#16A34A"
|
||||||
|
:size="22"
|
||||||
|
@click="$emit('approveDeposit', row)"
|
||||||
|
/>
|
||||||
|
<MobileIconButton
|
||||||
|
plain
|
||||||
|
icon="vuesax-linear:close-circle"
|
||||||
|
color="#DC2626"
|
||||||
|
:size="22"
|
||||||
|
@click="$emit('rejectDeposit', row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<MobileIconButton
|
<MobileIconButton
|
||||||
v-if="needsTrackingConfirmation(row)"
|
v-else-if="needsTrackingConfirmation(row)"
|
||||||
plain
|
plain
|
||||||
icon="vuesax-linear:tick-circle"
|
icon="vuesax-linear:tick-circle"
|
||||||
color="#16A34A"
|
color="#16A34A"
|
||||||
@@ -103,8 +119,51 @@
|
|||||||
<MobileDetailRow label="نام و نام خانوادگی" full-width :value="row.customer?.name || '-'" />
|
<MobileDetailRow label="نام و نام خانوادگی" full-width :value="row.customer?.name || '-'" />
|
||||||
<MobileDetailRow label="شماره کارت" full-width :value="row.bank_account?.cart_number || '-'" />
|
<MobileDetailRow label="شماره کارت" full-width :value="row.bank_account?.cart_number || '-'" />
|
||||||
<MobileDetailRow label="شماره شبا" full-width :value="row.bank_account?.shaba_number || '-'" />
|
<MobileDetailRow label="شماره شبا" full-width :value="row.bank_account?.shaba_number || '-'" />
|
||||||
|
<MobileDetailRow
|
||||||
|
label="شناسه واریز"
|
||||||
|
full-width
|
||||||
|
:value="row.deposit_identifier || row.customer?.n_code || '-'"
|
||||||
|
/>
|
||||||
<MobileDetailRow label="تاریخ ثبت" full-width :value="dateLabel(row)" />
|
<MobileDetailRow label="تاریخ ثبت" full-width :value="dateLabel(row)" />
|
||||||
|
<MobileDetailRow
|
||||||
|
v-if="row.reject_reason"
|
||||||
|
label="علت رد درخواست"
|
||||||
|
full-width
|
||||||
|
:value="row.reject_reason"
|
||||||
|
/>
|
||||||
|
<div v-if="row.receipt_url" class="col-span-2 py-2">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">فیش واریزی:</div>
|
||||||
|
<a-image
|
||||||
|
:src="row.receipt_url"
|
||||||
|
:height="120"
|
||||||
|
class="rounded-lg object-contain border max-w-full"
|
||||||
|
alt="فیش واریزی"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</MobileInfoGrid>
|
</MobileInfoGrid>
|
||||||
|
|
||||||
|
<div v-if="isPendingDepositRequest(row)" class="mt-4 flex gap-2">
|
||||||
|
<BaseButton
|
||||||
|
type="primary"
|
||||||
|
class="flex-1 !bg-emerald-600 hover:!bg-emerald-700 !border-emerald-600 text-white"
|
||||||
|
@click="$emit('approveDeposit', row)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<BaseIcon icon="vuesax-linear:tick-circle" size="16" />
|
||||||
|
</template>
|
||||||
|
تایید واریز
|
||||||
|
</BaseButton>
|
||||||
|
<BaseButton
|
||||||
|
danger
|
||||||
|
class="flex-1"
|
||||||
|
@click="$emit('rejectDeposit', row)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<BaseIcon icon="vuesax-linear:close-circle" size="16" />
|
||||||
|
</template>
|
||||||
|
رد واریز
|
||||||
|
</BaseButton>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MobileDetailSheet>
|
</MobileDetailSheet>
|
||||||
</template>
|
</template>
|
||||||
@@ -121,6 +180,7 @@ import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
|||||||
import {
|
import {
|
||||||
formatWithdrawAmountDisplay,
|
formatWithdrawAmountDisplay,
|
||||||
isMoneyWithdraw,
|
isMoneyWithdraw,
|
||||||
|
isPendingDepositRequest,
|
||||||
needsTrackingConfirmation,
|
needsTrackingConfirmation,
|
||||||
needsWeightAssignment,
|
needsWeightAssignment,
|
||||||
withdrawAmountValue,
|
withdrawAmountValue,
|
||||||
@@ -140,6 +200,8 @@ const emit = defineEmits<{
|
|||||||
(e: 'update:visible', value: boolean): void
|
(e: 'update:visible', value: boolean): void
|
||||||
(e: 'withdraw', item: Withdraw): void
|
(e: 'withdraw', item: Withdraw): void
|
||||||
(e: 'weight', item: Withdraw): void
|
(e: 'weight', item: Withdraw): void
|
||||||
|
(e: 'approveDeposit', item: Withdraw): void
|
||||||
|
(e: 'rejectDeposit', item: Withdraw): void
|
||||||
(e: 'changeStatus', item: Withdraw, statusEntry: [string, (typeof status)[keyof typeof status]]): void
|
(e: 'changeStatus', item: Withdraw, statusEntry: [string, (typeof status)[keyof typeof status]]): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,35 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #tracked="{ column, record }">
|
<template #tracked="{ column, record }">
|
||||||
<div v-if="record.tracked_number">{{ record.tracked_number }}</div>
|
<div v-if="record.tracked_number">{{ record.tracked_number }}</div>
|
||||||
<div v-else-if="needsTrackingConfirmation(record)">
|
<div v-else-if="!isPendingDepositRequest(record) && needsTrackingConfirmation(record)">
|
||||||
<BaseButton v-if="can('confirm')" @click="emits('withdraw', record)">
|
<BaseButton v-if="can('confirm')" @click="emits('withdraw', record)">
|
||||||
{{ confirmLabelForRecord(record, props.flowType) }}
|
{{ confirmLabelForRecord(record, props.flowType) }}
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>-</div>
|
<div v-else>-</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #receipt="{ column, record }">
|
||||||
|
<div v-if="record.receipt_url" class="flex justify-center items-center">
|
||||||
|
<a-image
|
||||||
|
:src="record.receipt_url"
|
||||||
|
:width="36"
|
||||||
|
:height="36"
|
||||||
|
class="rounded object-cover border border-gray-200 cursor-pointer shadow-sm hover:opacity-80 transition"
|
||||||
|
alt="فیش واریز"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span v-else class="text-gray-400">-</span>
|
||||||
|
</template>
|
||||||
<template #action="{ column, record }">
|
<template #action="{ column, record }">
|
||||||
<div class="gap-2 flex justify-center">
|
<div class="gap-2 flex justify-center items-center">
|
||||||
|
<a-tooltip v-if="record.reject_reason" class="cursor-pointer">
|
||||||
|
<template #title>
|
||||||
|
<span class="whitespace-pre-wrap">علت رد: {{ record.reject_reason }}</span>
|
||||||
|
</template>
|
||||||
|
<a-badge dot color="#dc2626">
|
||||||
|
<Icon icon="vuesax-linear:info-circle" color="#dc2626" />
|
||||||
|
</a-badge>
|
||||||
|
</a-tooltip>
|
||||||
<a-tooltip v-if="record.extra_note" class="cursor-pointer">
|
<a-tooltip v-if="record.extra_note" class="cursor-pointer">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span class="whitespace-pre-wrap">{{ record.extra_note }}</span>
|
<span class="whitespace-pre-wrap">{{ record.extra_note }}</span>
|
||||||
@@ -28,7 +48,34 @@
|
|||||||
<Icon icon="vuesax-linear:message-text" color="#64748b" />
|
<Icon icon="vuesax-linear:message-text" color="#64748b" />
|
||||||
</a-badge>
|
</a-badge>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip v-if="can('confirm') && needsTrackingConfirmation(record)" class="cursor-pointer">
|
<template v-if="isPendingDepositRequest(record) && can('confirm')">
|
||||||
|
<a-tooltip title="تایید واریز و شارژ کیف پول">
|
||||||
|
<BaseButton
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
class="!bg-emerald-600 hover:!bg-emerald-700 !border-emerald-600 text-white"
|
||||||
|
@click="emits('approveDeposit', record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<Icon icon="vuesax-linear:tick-circle" size="14" />
|
||||||
|
</template>
|
||||||
|
تایید
|
||||||
|
</BaseButton>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip title="رد واریز">
|
||||||
|
<BaseButton
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
@click="emits('rejectDeposit', record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<Icon icon="vuesax-linear:close-circle" size="14" />
|
||||||
|
</template>
|
||||||
|
رد
|
||||||
|
</BaseButton>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-tooltip v-else-if="can('confirm') && needsTrackingConfirmation(record)" class="cursor-pointer">
|
||||||
<template #title><span>{{ confirmLabelForRecord(record, props.flowType) }}</span></template>
|
<template #title><span>{{ confirmLabelForRecord(record, props.flowType) }}</span></template>
|
||||||
<BaseButton size="small" type="primary" @click="emits('withdraw', record)">
|
<BaseButton size="small" type="primary" @click="emits('withdraw', record)">
|
||||||
{{ confirmLabelForRecord(record, props.flowType) }}
|
{{ confirmLabelForRecord(record, props.flowType) }}
|
||||||
@@ -101,6 +148,8 @@
|
|||||||
:flow-type="props.flowType"
|
:flow-type="props.flowType"
|
||||||
@withdraw="(row) => emits('withdraw', row)"
|
@withdraw="(row) => emits('withdraw', row)"
|
||||||
@weight="(row) => emits('weight', row)"
|
@weight="(row) => emits('weight', row)"
|
||||||
|
@approve-deposit="(row) => emits('approveDeposit', row)"
|
||||||
|
@reject-deposit="(row) => emits('rejectDeposit', row)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -138,6 +187,7 @@ import { isMobile } from '@core/utils/is'
|
|||||||
import type { WithdrawFlowType } from '../types'
|
import type { WithdrawFlowType } from '../types'
|
||||||
import {
|
import {
|
||||||
confirmLabelForRecord,
|
confirmLabelForRecord,
|
||||||
|
isPendingDepositRequest,
|
||||||
needsTrackingConfirmation,
|
needsTrackingConfirmation,
|
||||||
needsWeightAssignment
|
needsWeightAssignment
|
||||||
} from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
} from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
||||||
@@ -166,7 +216,7 @@ const zarinEnabled = zarinEnabledSetting
|
|||||||
val.sts === 1 ? return ['1'] : ['2']
|
val.sts === 1 ? return ['1'] : ['2']
|
||||||
}*/
|
}*/
|
||||||
//emits
|
//emits
|
||||||
const emits = defineEmits(['delete', 'edit', 'add', 'withdraw', 'weight'])
|
const emits = defineEmits(['delete', 'edit', 'add', 'withdraw', 'weight', 'approveDeposit', 'rejectDeposit'])
|
||||||
|
|
||||||
const { prefixCls } = usePrefix('pophoverstatus')
|
const { prefixCls } = usePrefix('pophoverstatus')
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,24 @@ export function getWithdrawColumns(): BaseTableColumn[] {
|
|||||||
key: 'customer.name',
|
key: 'customer.name',
|
||||||
type: 'Text'
|
type: 'Text'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'شناسه واریز',
|
||||||
|
dataIndex: 'deposit_identifier',
|
||||||
|
key: 'deposit_identifier',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: ({ record }: any) => {
|
||||||
|
const val = record?.deposit_identifier || record?.customer?.n_code
|
||||||
|
return val ? <span dir="ltr" class="font-mono text-xs">{val}</span> : '-'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'فیش واریزی',
|
||||||
|
dataIndex: 'receipt_url',
|
||||||
|
key: 'receipt_url',
|
||||||
|
slot: 'receipt',
|
||||||
|
filterable: false,
|
||||||
|
sortable: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'نوع',
|
title: 'نوع',
|
||||||
dataIndex: 'asset_type',
|
dataIndex: 'asset_type',
|
||||||
@@ -172,9 +190,18 @@ export function getWithdrawColumns(): BaseTableColumn[] {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
customRender: ({ record }) => {
|
customRender: ({ record }: any) => {
|
||||||
|
let textColor = '#ca8a04'
|
||||||
|
let bgColor = '#fef3c7'
|
||||||
|
if (record?.sts === 2 || record?.sts === 4) {
|
||||||
|
textColor = '#25855A'
|
||||||
|
bgColor = '#E3F4E9'
|
||||||
|
} else if (record?.sts === 3) {
|
||||||
|
textColor = '#C53030'
|
||||||
|
bgColor = '#FECACA'
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<CustomTag textColor='#ca8a04' bgColor='#fef3c7'>{record?.sts_str}</CustomTag>
|
<CustomTag textColor={textColor} bgColor={bgColor}>{record?.sts_str || '-'}</CustomTag>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
@delete="deleteItem"
|
@delete="deleteItem"
|
||||||
@withdraw="openWithdraw"
|
@withdraw="openWithdraw"
|
||||||
@weight="openWeight"
|
@weight="openWeight"
|
||||||
|
@approve-deposit="openApproveDeposit"
|
||||||
|
@reject-deposit="openRejectDeposit"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||||
@@ -92,6 +94,95 @@
|
|||||||
اطلاعات تراکنش یافت نشد
|
اطلاعات تراکنش یافت نشد
|
||||||
</div>
|
</div>
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
|
|
||||||
|
<!-- مدال تایید واریز وجه -->
|
||||||
|
<BasicModal
|
||||||
|
v-model:visible="approveDepositModalVisible"
|
||||||
|
width="28rem"
|
||||||
|
title="تایید واریز وجه به کیف پول"
|
||||||
|
wrap-class-name="withdraw-stack-modal"
|
||||||
|
:loading="depositActionLoading"
|
||||||
|
@ok="handleApproveDeposit"
|
||||||
|
@close="approveDepositModalVisible = false"
|
||||||
|
>
|
||||||
|
<div v-if="selectedDepositRecord" class="space-y-3 py-2 text-sm">
|
||||||
|
<div class="rounded-lg bg-emerald-50 p-3 text-emerald-900 border border-emerald-200">
|
||||||
|
<div class="font-bold flex justify-between items-center">
|
||||||
|
<span>مشتری: {{ selectedDepositRecord.customer?.name || '-' }}</span>
|
||||||
|
<span class="text-xs text-emerald-700">موبایل: {{ selectedDepositRecord.customer?.mobile || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 text-xs flex justify-between">
|
||||||
|
<span>شناسه واریز: <strong dir="ltr">{{ selectedDepositRecord.deposit_identifier || selectedDepositRecord.customer?.n_code || '-' }}</strong></span>
|
||||||
|
<span>مبلغ: <strong class="text-emerald-800 text-sm">{{ formatWithdrawAmountDisplay(selectedDepositRecord) }}</strong></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="selectedDepositRecord.receipt_url" class="rounded border p-2 text-center bg-gray-50">
|
||||||
|
<div class="text-xs text-gray-500 mb-2">تصویر فیش واریزی (جهت بزرگنمایی روی عکس کلیک کنید):</div>
|
||||||
|
<a-image
|
||||||
|
:src="selectedDepositRecord.receipt_url"
|
||||||
|
:height="150"
|
||||||
|
class="rounded object-contain mx-auto max-w-full"
|
||||||
|
alt="فیش واریز"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="selectedDepositRecord.extra_note" class="rounded bg-gray-100 p-2 text-xs text-gray-700">
|
||||||
|
<span class="font-bold">توضیحات مشتری: </span>
|
||||||
|
<span>{{ selectedDepositRecord.extra_note }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-medium text-gray-700 mb-1">شماره پیگیری تراکنش:</label>
|
||||||
|
<BasicInput
|
||||||
|
v-model:value="approveTrackedNumber"
|
||||||
|
placeholder="شماره پیگیری فیش بانکی"
|
||||||
|
dir="ltr"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
با تایید، مبلغ به کیف پول نقدی مشتری واریز شده و پیامک تایید ارسال میگردد.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BasicModal>
|
||||||
|
|
||||||
|
<!-- مدال رد واریز وجه -->
|
||||||
|
<BasicModal
|
||||||
|
v-model:visible="rejectDepositModalVisible"
|
||||||
|
width="26rem"
|
||||||
|
title="رد درخواست واریز"
|
||||||
|
wrap-class-name="withdraw-stack-modal"
|
||||||
|
:loading="depositActionLoading"
|
||||||
|
@ok="handleRejectDeposit"
|
||||||
|
@close="rejectDepositModalVisible = false"
|
||||||
|
>
|
||||||
|
<div v-if="selectedDepositRecord" class="space-y-3 py-2 text-sm">
|
||||||
|
<div class="rounded-lg bg-red-50 p-3 text-red-900 border border-red-200">
|
||||||
|
<div class="font-bold flex justify-between items-center">
|
||||||
|
<span>مشتری: {{ selectedDepositRecord.customer?.name || '-' }}</span>
|
||||||
|
<span class="text-xs text-red-700">موبایل: {{ selectedDepositRecord.customer?.mobile || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 text-xs flex justify-between">
|
||||||
|
<span>مبلغ: <strong>{{ formatWithdrawAmountDisplay(selectedDepositRecord) }}</strong></span>
|
||||||
|
<span>شناسه: <strong dir="ltr">{{ selectedDepositRecord.deposit_identifier || selectedDepositRecord.customer?.n_code || '-' }}</strong></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-medium text-gray-700 mb-1">علت رد درخواست (در پیامک برای مشتری ارسال میشود):</label>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="rejectReason"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="مثال: عدم تطابق فیش واریزی با گردش حساب بانکی..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
با رد واریز، پیامک اطلاعرسانی حاوی علت رد برای مشتری ارسال میشود.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BasicModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -114,10 +205,21 @@ import type { Customer } from '@/model/customer'
|
|||||||
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
||||||
import type { Order } from '@/model/order'
|
import type { Order } from '@/model/order'
|
||||||
import type { Wallet, Withdraw } from '@/model/wallet'
|
import type { Wallet, Withdraw } from '@/model/wallet'
|
||||||
import {completeWithdraw, exportWithdrawReport, getWithdrawById, sendWeights} from '@/api/wallet'
|
import {
|
||||||
|
approveDeposit,
|
||||||
|
completeWithdraw,
|
||||||
|
exportWithdrawReport,
|
||||||
|
getWithdrawById,
|
||||||
|
rejectDeposit,
|
||||||
|
sendWeights
|
||||||
|
} from '@/api/wallet'
|
||||||
import Button from "@core/components/BaseButton";
|
import Button from "@core/components/BaseButton";
|
||||||
import type { WithdrawFlowType } from '@/pages/menuPages/withdraw/types'
|
import type { WithdrawFlowType } from '@/pages/menuPages/withdraw/types'
|
||||||
import { confirmLabelForRecord, needsWeightAssignment } from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
import {
|
||||||
|
confirmLabelForRecord,
|
||||||
|
formatWithdrawAmountDisplay,
|
||||||
|
needsWeightAssignment
|
||||||
|
} from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
||||||
import { openHtmlPrintWindow } from '@/pages/menuPages/withdraw/utils/openHtmlPrintWindow'
|
import { openHtmlPrintWindow } from '@/pages/menuPages/withdraw/utils/openHtmlPrintWindow'
|
||||||
//import DatePicker from '@core/components/_sample/components/datePicker.vue'
|
//import DatePicker from '@core/components/_sample/components/datePicker.vue'
|
||||||
|
|
||||||
@@ -360,6 +462,65 @@ function ok(i) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deposit approval / rejection logic
|
||||||
|
const approveDepositModalVisible = ref(false)
|
||||||
|
const rejectDepositModalVisible = ref(false)
|
||||||
|
const selectedDepositRecord = ref<Withdraw | null>(null)
|
||||||
|
const approveTrackedNumber = ref('')
|
||||||
|
const rejectReason = ref('')
|
||||||
|
const depositActionLoading = ref(false)
|
||||||
|
|
||||||
|
function openApproveDeposit(record: Withdraw) {
|
||||||
|
selectedDepositRecord.value = record
|
||||||
|
approveTrackedNumber.value = record.tracked_number || ''
|
||||||
|
approveDepositModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function openRejectDeposit(record: Withdraw) {
|
||||||
|
selectedDepositRecord.value = record
|
||||||
|
rejectReason.value = ''
|
||||||
|
rejectDepositModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleApproveDeposit() {
|
||||||
|
if (!selectedDepositRecord.value?.id) return
|
||||||
|
try {
|
||||||
|
depositActionLoading.value = true
|
||||||
|
await approveDeposit({
|
||||||
|
id: selectedDepositRecord.value.id,
|
||||||
|
tracked_number: approveTrackedNumber.value || undefined
|
||||||
|
})
|
||||||
|
message.success('واریز با موفقیت تایید و به کیف پول مشتری افزوده شد')
|
||||||
|
approveDepositModalVisible.value = false
|
||||||
|
selectedDepositRecord.value = null
|
||||||
|
refreshTable()
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error(e)
|
||||||
|
message.error(e?.response?.data?.message || 'خطا در تایید واریز')
|
||||||
|
} finally {
|
||||||
|
depositActionLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRejectDeposit() {
|
||||||
|
if (!selectedDepositRecord.value?.id) return
|
||||||
|
try {
|
||||||
|
depositActionLoading.value = true
|
||||||
|
await rejectDeposit({
|
||||||
|
id: selectedDepositRecord.value.id,
|
||||||
|
reject_reason: rejectReason.value || undefined
|
||||||
|
})
|
||||||
|
message.success('درخواست واریز رد شد و پیامک اطلاعرسانی ارسال گردید')
|
||||||
|
rejectDepositModalVisible.value = false
|
||||||
|
selectedDepositRecord.value = null
|
||||||
|
refreshTable()
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error(e)
|
||||||
|
message.error(e?.response?.data?.message || 'خطا در رد واریز')
|
||||||
|
} finally {
|
||||||
|
depositActionLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@@ -98,6 +98,15 @@ export function confirmLabelForRecord(
|
|||||||
return flowType === 'deposit' ? 'تایید واریز' : 'تایید برداشت'
|
return flowType === 'deposit' ? 'تایید واریز' : 'تایید برداشت'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** بررسی درخواست واریز معلق که نیاز به تایید یا رد ادمین دارد */
|
||||||
|
export function isPendingDepositRequest(
|
||||||
|
record: Pick<Withdraw, 'sts' | 'receipt' | 'receipt_url' | 'deposit_identifier' | 'note' | 'cash' | 'gold' | 'bank_account_id' | 'type'>
|
||||||
|
): boolean {
|
||||||
|
if (Number(record.sts ?? 0) !== 1) return false
|
||||||
|
if (record.receipt_url || record.receipt || record.deposit_identifier) return true
|
||||||
|
return resolveRecordFlowType(record as any) === 'deposit'
|
||||||
|
}
|
||||||
|
|
||||||
/** فقط تراکنشهای در انتظار پیگیری — نه واریز/کسر ادمین (sts=4) */
|
/** فقط تراکنشهای در انتظار پیگیری — نه واریز/کسر ادمین (sts=4) */
|
||||||
export function needsTrackingConfirmation(record: Pick<Withdraw, 'sts' | 'tracked_number'>): boolean {
|
export function needsTrackingConfirmation(record: Pick<Withdraw, 'sts' | 'tracked_number'>): boolean {
|
||||||
if (record.tracked_number) return false
|
if (record.tracked_number) return false
|
||||||
|
|||||||
Reference in New Issue
Block a user