fix bug of pargar 3
This commit is contained in:
@@ -7,12 +7,15 @@ export interface PargarRecord {
|
|||||||
amount?: number
|
amount?: number
|
||||||
desc?: string
|
desc?: string
|
||||||
type?: string
|
type?: string
|
||||||
|
order_id?: number | null
|
||||||
|
withdraw_id?: number | null
|
||||||
sync_status?: 'pending' | 'success' | 'failed'
|
sync_status?: 'pending' | 'success' | 'failed'
|
||||||
sync_log?: string | null
|
sync_log?: string | null
|
||||||
pargar_ref?: string | null
|
pargar_ref?: string | null
|
||||||
data?: string | null
|
data?: string | null
|
||||||
res?: string | null
|
res?: string | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
|
confirmed_at?: string | null
|
||||||
customer?: {
|
customer?: {
|
||||||
id?: number
|
id?: number
|
||||||
name?: string
|
name?: string
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const EDITABLE_SETTING_GROUPS: SettingGroupDef[] = [
|
|||||||
title: 'دسترسی مشتری به قابلیتها',
|
title: 'دسترسی مشتری به قابلیتها',
|
||||||
icon: 'vuesax-linear:people',
|
icon: 'vuesax-linear:people',
|
||||||
match: (k) =>
|
match: (k) =>
|
||||||
/^(banner_enabled|tracking_systems_enabled|jibit_verification|register_jibit_verify)$/.test(k)
|
/^(banner_enabled|tracking_systems_enabled|jibit_verification|register_jibit_verify|show_product_details)$/.test(k)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'trading_hours',
|
id: 'trading_hours',
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
|||||||
show_last_price: 'switch',
|
show_last_price: 'switch',
|
||||||
show_home_price_when_closed: 'switch',
|
show_home_price_when_closed: 'switch',
|
||||||
show_gold_ounce_price: 'switch',
|
show_gold_ounce_price: 'switch',
|
||||||
|
show_product_details: 'switch',
|
||||||
send_to_tahesab: 'switch',
|
send_to_tahesab: 'switch',
|
||||||
accounting_provider: 'select',
|
accounting_provider: 'select',
|
||||||
profit_gold_api_enabled: 'switch',
|
profit_gold_api_enabled: 'switch',
|
||||||
@@ -561,6 +562,8 @@ const KEY_HELP_FALLBACK: Record<string, string> = {
|
|||||||
'روشن: وقتی فروشگاه خارج از ساعت کاری است، قیمت صفحه اصلی اپ همچنان نمایش داده میشود و پیام «فروشگاه بسته است» نشان داده نمیشود. خرید/فروش همچنان بسته میماند. خاموش (پیشفرض): خارج از ساعت پیام بسته بودن نشان داده میشود.',
|
'روشن: وقتی فروشگاه خارج از ساعت کاری است، قیمت صفحه اصلی اپ همچنان نمایش داده میشود و پیام «فروشگاه بسته است» نشان داده نمیشود. خرید/فروش همچنان بسته میماند. خاموش (پیشفرض): خارج از ساعت پیام بسته بودن نشان داده میشود.',
|
||||||
show_gold_ounce_price:
|
show_gold_ounce_price:
|
||||||
'روشن: اگر آدرس API تابلو (zaarbox_api_url) تنظیم شده باشد، قیمت انس طلا در اپ مشتری نمایش داده میشود. خاموش: نمایش داده نمیشود.',
|
'روشن: اگر آدرس API تابلو (zaarbox_api_url) تنظیم شده باشد، قیمت انس طلا در اپ مشتری نمایش داده میشود. خاموش: نمایش داده نمیشود.',
|
||||||
|
show_product_details:
|
||||||
|
'روشن: بعد از انتخاب محصول در صفحه خرید/فروش، متن توضیح محصول نمایش داده میشود. خاموش: توضیح نشان داده نمیشود.',
|
||||||
fee_single:
|
fee_single:
|
||||||
'اختلاف پایه (ریال) بین قیمت خرید و فروش روی مظنه. معمولاً نصف مجموع اختلاف قیمت خرید و فروش است.',
|
'اختلاف پایه (ریال) بین قیمت خرید و فروش روی مظنه. معمولاً نصف مجموع اختلاف قیمت خرید و فروش است.',
|
||||||
buy_fee:
|
buy_fee:
|
||||||
@@ -819,6 +822,7 @@ export const KEY_LABEL_FALLBACK: Record<string, string> = {
|
|||||||
show_last_price: 'نمایش آخرین قیمت ذخیرهشده',
|
show_last_price: 'نمایش آخرین قیمت ذخیرهشده',
|
||||||
show_home_price_when_closed: 'نمایش قیمت صفحه اصلی خارج از ساعت کاری',
|
show_home_price_when_closed: 'نمایش قیمت صفحه اصلی خارج از ساعت کاری',
|
||||||
show_gold_ounce_price: 'نمایش قیمت انس طلا',
|
show_gold_ounce_price: 'نمایش قیمت انس طلا',
|
||||||
|
show_product_details: 'نمایش جزئیات اطلاعات محصول',
|
||||||
fee_single: 'اختلاف پایه خرید/فروش',
|
fee_single: 'اختلاف پایه خرید/فروش',
|
||||||
buy_fee: 'اضافه قیمت خرید',
|
buy_fee: 'اضافه قیمت خرید',
|
||||||
sell_fee: 'کسر قیمت فروش',
|
sell_fee: 'کسر قیمت فروش',
|
||||||
@@ -978,7 +982,7 @@ export const SETTING_EDITABLE_KEYS = new Set([
|
|||||||
'open_register',
|
'open_register',
|
||||||
'referral_id', 'referral_limit', 'referral_gift_on_first_order',
|
'referral_id', 'referral_limit', 'referral_gift_on_first_order',
|
||||||
'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer',
|
'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer',
|
||||||
'sell_fee', 'show_last_price', 'show_home_price_when_closed', 'show_gold_ounce_price', 'startDay',
|
'sell_fee', 'show_last_price', 'show_home_price_when_closed', 'show_gold_ounce_price', 'show_product_details', 'startDay',
|
||||||
'support_messengers', 'support_messenger_text',
|
'support_messengers', 'support_messenger_text',
|
||||||
'deposit_support_message_text', 'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
|
'deposit_support_message_text', 'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
|
||||||
'text_about', 'text_rule',
|
'text_about', 'text_rule',
|
||||||
|
|||||||
@@ -0,0 +1,265 @@
|
|||||||
|
<template>
|
||||||
|
<div class="min-w-0 w-full max-w-full overflow-x-hidden">
|
||||||
|
<BasicShowContext title="لاگها و اسناد پرگار">
|
||||||
|
<div class="min-w-0 w-full max-w-full overflow-x-auto">
|
||||||
|
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
|
<template #action="{ record }">
|
||||||
|
<div class="flex justify-center gap-2">
|
||||||
|
<a-tooltip placement="bottom" class="cursor-pointer" @click="openInfo(record)">
|
||||||
|
<template #title><span>اطلاعات سند</span></template>
|
||||||
|
<Icon icon="vuesax-linear:stickynote" color="#10913A" />
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip
|
||||||
|
v-if="canRetryPargar(record)"
|
||||||
|
placement="bottom"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="openSend(record)"
|
||||||
|
>
|
||||||
|
<template #title><span>ارسال به پرگار</span></template>
|
||||||
|
<Icon icon="vuesax-linear:send-2" color="#CA8A04" />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</BaseTable>
|
||||||
|
</div>
|
||||||
|
</BasicShowContext>
|
||||||
|
|
||||||
|
<BasicModal v-model:visible="infoVisible" title="اطلاعات سند پرگار" width="36rem" :footer="null">
|
||||||
|
<div class="space-y-2 text-sm">
|
||||||
|
<div
|
||||||
|
v-for="item in infoItems"
|
||||||
|
:key="item.label"
|
||||||
|
class="flex justify-between gap-3 border-b border-gray-100 py-2"
|
||||||
|
>
|
||||||
|
<span class="text-gray-500">{{ item.label }}</span>
|
||||||
|
<span class="break-all text-left">{{ item.value ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selected?.res"
|
||||||
|
class="rounded-lg bg-gray-100 p-3 text-xs font-mono text-gray-700 whitespace-pre-wrap"
|
||||||
|
>
|
||||||
|
{{ selected.res }}
|
||||||
|
</div>
|
||||||
|
<div v-if="parsedPayload?.transactions.length" class="space-y-2">
|
||||||
|
<div class="text-sm font-600 text-gray-700">جزئیات اسناد دریافتی از پرگار</div>
|
||||||
|
<div
|
||||||
|
v-for="(tx, idx) in parsedPayload.transactions"
|
||||||
|
:key="idx"
|
||||||
|
class="rounded-lg border border-gray-100 bg-gray-50 p-3 text-xs space-y-1"
|
||||||
|
>
|
||||||
|
<div class="flex justify-between gap-2">
|
||||||
|
<span class="text-gray-500">شرح</span>
|
||||||
|
<span class="text-left">{{ tx.desc || tx.docType || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-2">
|
||||||
|
<span class="text-gray-500">تاریخ</span>
|
||||||
|
<span class="text-left">{{ tx.date || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-2">
|
||||||
|
<span class="text-gray-500">شماره سند</span>
|
||||||
|
<span class="text-left">{{ tx.docId || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-2">
|
||||||
|
<span class="text-gray-500">مبالغ</span>
|
||||||
|
<span class="text-left">{{ formatTransactionAmount(tx) }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="tx.remainGold || tx.remainRial" class="flex justify-between gap-2">
|
||||||
|
<span class="text-gray-500">مانده</span>
|
||||||
|
<span class="text-left">
|
||||||
|
{{ tx.remainGold ? `${tx.remainGold} گرم` : '' }}
|
||||||
|
{{ tx.remainRial ? `${tx.remainRial} ریال` : '' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="selected?.data"
|
||||||
|
class="rounded-lg bg-gray-100 p-3 text-xs font-mono text-gray-700 whitespace-pre-wrap overflow-x-auto"
|
||||||
|
>
|
||||||
|
{{ selected.data }}
|
||||||
|
</div>
|
||||||
|
<div v-if="selected?.sync_log" class="rounded-lg bg-red-50 p-3 text-red-700 whitespace-pre-wrap">
|
||||||
|
{{ selected.sync_log }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BasicModal>
|
||||||
|
|
||||||
|
<PargarRetryModal
|
||||||
|
v-model="sendVisible"
|
||||||
|
mode="retry-sanad"
|
||||||
|
:pargar-id="selected?.id"
|
||||||
|
@success="fetch"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||||
|
import type { TableInput } from '@core/type/baseTable'
|
||||||
|
import { getPargarTable, type PargarRecord } from '@/api/pargar'
|
||||||
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
|
import BasicModal from '@/components/BasicModal.vue'
|
||||||
|
import PargarRetryModal from '@/components/PargarRetryModal.vue'
|
||||||
|
import { canRetryPargar, pargarStatusLabel } from '@/pages/menuPages/accounting/utils/pargarStatus'
|
||||||
|
import {
|
||||||
|
formatTransactionAmount,
|
||||||
|
parsePargarPayload,
|
||||||
|
pargarAmountLabel,
|
||||||
|
pargarDescLabel,
|
||||||
|
pargarTypeLabel
|
||||||
|
} from '@/pages/menuPages/accounting/utils/pargarDisplay'
|
||||||
|
import { toJalali } from '@core/utils/useDataTime'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
customerId?: number
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const [submit, reload] = useBaseTable()
|
||||||
|
const infoVisible = ref(false)
|
||||||
|
const sendVisible = ref(false)
|
||||||
|
const selected = ref<PargarRecord | null>(null)
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'ردیف',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'id',
|
||||||
|
filterable: false,
|
||||||
|
sortable: false,
|
||||||
|
customRender: (r: any) => r.index + 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'شناسه',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'log_id',
|
||||||
|
type: 'Number',
|
||||||
|
filterable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'نوع',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: (r: any) => pargarTypeLabel(r.record.type)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'مقدار',
|
||||||
|
dataIndex: 'amount',
|
||||||
|
key: 'amount',
|
||||||
|
type: 'Number',
|
||||||
|
customRender: (r: any) => pargarAmountLabel(r.record)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'شرح',
|
||||||
|
dataIndex: 'desc',
|
||||||
|
key: 'desc',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: (r: any) => pargarDescLabel(r.record)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'سفارش',
|
||||||
|
dataIndex: 'order_id',
|
||||||
|
key: 'order_id',
|
||||||
|
type: 'Number',
|
||||||
|
filterable: false,
|
||||||
|
customRender: (r: any) => r.record.order_id || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'برداشت',
|
||||||
|
dataIndex: 'withdraw_id',
|
||||||
|
key: 'withdraw_id',
|
||||||
|
type: 'Number',
|
||||||
|
filterable: false,
|
||||||
|
customRender: (r: any) => r.record.withdraw_id || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'وضعیت',
|
||||||
|
dataIndex: 'sync_status',
|
||||||
|
key: 'sync_status',
|
||||||
|
type: 'Text',
|
||||||
|
filterable: false,
|
||||||
|
customRender: (r: any) =>
|
||||||
|
pargarStatusLabel(r.record.sync_status, r.record.pargar_ref, r.record.desc)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'زمان',
|
||||||
|
dataIndex: 'created_at',
|
||||||
|
key: 'created_at',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: (r: any) => toJalali(r.record.created_at)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'عملیات',
|
||||||
|
dataIndex: 'action',
|
||||||
|
key: 'action',
|
||||||
|
slot: 'action',
|
||||||
|
filterable: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tblProps = ref({
|
||||||
|
columns,
|
||||||
|
api: (params: TableInput) => {
|
||||||
|
if (props.customerId) {
|
||||||
|
params.filters = []
|
||||||
|
params.filters.push({
|
||||||
|
field: 'customer_id',
|
||||||
|
type: 'text',
|
||||||
|
value: props.customerId,
|
||||||
|
cr: 'and',
|
||||||
|
op: 'eq',
|
||||||
|
hidden: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return getPargarTable(params)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const infoItems = computed(() => {
|
||||||
|
const row = selected.value
|
||||||
|
if (!row) return []
|
||||||
|
const payload = parsePargarPayload(row.data)
|
||||||
|
return [
|
||||||
|
{ label: 'شناسه سند', value: row.id },
|
||||||
|
{ label: 'کد حساب پرگار', value: payload?.accountId || row.pargar_ref || '-' },
|
||||||
|
{ label: 'نوع', value: pargarTypeLabel(row.type) },
|
||||||
|
{ label: 'مقدار', value: pargarAmountLabel(row) },
|
||||||
|
{ label: 'شرح', value: pargarDescLabel(row) },
|
||||||
|
{ label: 'سفارش', value: row.order_id || '-' },
|
||||||
|
{ label: 'برداشت', value: row.withdraw_id || '-' },
|
||||||
|
{
|
||||||
|
label: 'تعداد سطر سند',
|
||||||
|
value: payload?.transactions.length ? String(payload.transactions.length) : '-'
|
||||||
|
},
|
||||||
|
{ label: 'زمان ثبت', value: row.created_at ? toJalali(row.created_at) : '-' },
|
||||||
|
{
|
||||||
|
label: 'تأیید پرگار',
|
||||||
|
value: row.confirmed_at ? toJalali(row.confirmed_at) : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'وضعیت',
|
||||||
|
value: pargarStatusLabel(row.sync_status, row.pargar_ref, row.desc)
|
||||||
|
},
|
||||||
|
{ label: 'کد پرگار', value: row.pargar_ref || 'ثبت نشده' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const parsedPayload = computed(() => parsePargarPayload(selected.value?.data))
|
||||||
|
|
||||||
|
function openInfo(record: PargarRecord) {
|
||||||
|
selected.value = record
|
||||||
|
infoVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSend(record: PargarRecord) {
|
||||||
|
selected.value = record
|
||||||
|
sendVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetch() {
|
||||||
|
await reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ fetch })
|
||||||
|
</script>
|
||||||
@@ -26,38 +26,49 @@
|
|||||||
>
|
>
|
||||||
همگامسازی مانده از پرگار
|
همگامسازی مانده از پرگار
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-popconfirm
|
<a-button
|
||||||
title="ماندهٔ پرگار بدون بررسی اعتبار روی کیف مشتری نوشته شود؟"
|
type="link"
|
||||||
ok-text="بله، اعمال کن"
|
size="small"
|
||||||
cancel-text="انصراف"
|
block
|
||||||
|
danger
|
||||||
|
class="pargar-wallet-sync__force"
|
||||||
:disabled="!canSync || loading"
|
:disabled="!canSync || loading"
|
||||||
@confirm="$emit('sync', true)"
|
@click="confirmForceSync"
|
||||||
>
|
>
|
||||||
<a-button
|
اعمال اجباری مانده
|
||||||
type="link"
|
</a-button>
|
||||||
size="small"
|
|
||||||
block
|
|
||||||
danger
|
|
||||||
class="pargar-wallet-sync__force"
|
|
||||||
:disabled="!canSync || loading"
|
|
||||||
>
|
|
||||||
اعمال اجباری مانده
|
|
||||||
</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Modal } from 'ant-design-vue'
|
||||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
|
import { SELECT_DROPDOWN_Z_INDEX } from '@/constants/overlayZIndex'
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
canSync?: boolean
|
canSync?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'sync', force: boolean): void
|
(e: 'sync', force: boolean): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
function confirmForceSync() {
|
||||||
|
if (!props.canSync || props.loading) return
|
||||||
|
|
||||||
|
// Popconfirm داخل مودال جزئیات مشتری پشت میافتد؛ Modal.confirm با zIndex درست
|
||||||
|
Modal.confirm({
|
||||||
|
title: 'اعمال اجباری مانده',
|
||||||
|
content: 'ماندهٔ پرگار بدون بررسی اعتبار روی کیف مشتری نوشته شود؟',
|
||||||
|
okText: 'بله، اعمال کن',
|
||||||
|
cancelText: 'انصراف',
|
||||||
|
okType: 'danger',
|
||||||
|
centered: true,
|
||||||
|
zIndex: SELECT_DROPDOWN_Z_INDEX,
|
||||||
|
onOk: () => emit('sync', true)
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
:title="modalTitle"
|
:title="modalTitle"
|
||||||
:ok-text="okText"
|
:ok-text="okText"
|
||||||
:loading="submitting"
|
:loading="submitting"
|
||||||
|
:confirm-loading="submitting"
|
||||||
@ok="submit"
|
@ok="submit"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
@@ -140,31 +141,34 @@ function closeModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function submit() {
|
async function submit() {
|
||||||
const customerId = formCharge.value.customer_id ?? props.customerId
|
// قفل همینجا بسته میشود تا اعتبارسنجیِ async بین دو کلیک، سند تکراری نسازد
|
||||||
if (!customerId) {
|
if (submitting.value) return
|
||||||
message.warning('مشتری را انتخاب کنید')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await bodyRef.value?.validateFields?.()
|
|
||||||
} catch {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = selectedTarget.value
|
|
||||||
|
|
||||||
submitting.value = true
|
submitting.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const customerId = formCharge.value.customer_id ?? props.customerId
|
||||||
|
if (!customerId) {
|
||||||
|
message.warning('مشتری را انتخاب کنید')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await bodyRef.value?.validateFields?.()
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = selectedTarget.value
|
||||||
|
|
||||||
await chargeWalletUnified({
|
await chargeWalletUnified({
|
||||||
...buildChargePayload({ ...formCharge.value, customer_id: customerId }, target?.product_id ?? null),
|
...buildChargePayload({ ...formCharge.value, customer_id: customerId }, target?.product_id ?? null),
|
||||||
})
|
})
|
||||||
message.success(walletChargeSuccessMessage(formCharge.value.direction))
|
message.success(walletChargeSuccessMessage(formCharge.value.direction))
|
||||||
emit('success')
|
emit('success')
|
||||||
closeModal()
|
closeModal()
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
message.error('خطا در ثبت عملیات')
|
message.error(e?.response?.data?.message ?? 'خطا در ثبت عملیات')
|
||||||
} finally {
|
} finally {
|
||||||
submitting.value = false
|
submitting.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,6 +243,9 @@
|
|||||||
<a-tab-pane key="قلک ها" tab="قلک ها">
|
<a-tab-pane key="قلک ها" tab="قلک ها">
|
||||||
<FundsTable ref="fundTable" :customerId="userInfo?.id" />
|
<FundsTable ref="fundTable" :customerId="userInfo?.id" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
<a-tab-pane v-if="pargarWalletSyncVisible" key="لاگ پرگار" tab="لاگ پرگار">
|
||||||
|
<CustomerPargarLogsTable ref="pargarLogsTable" :customer-id="userInfo?.id" />
|
||||||
|
</a-tab-pane>
|
||||||
<a-tab-pane
|
<a-tab-pane
|
||||||
v-if="conditionalOrderEnabled"
|
v-if="conditionalOrderEnabled"
|
||||||
key="سفارش شرطی"
|
key="سفارش شرطی"
|
||||||
@@ -302,6 +305,7 @@ import transactionsTbl from '@/pages/menuPages/transactions/components/table.vue
|
|||||||
import smsTbl from '@/pages/menuPages/sms/components/table.vue'
|
import smsTbl from '@/pages/menuPages/sms/components/table.vue'
|
||||||
import FundsTable from '@/pages/menuPages/customers/base/components/fundsTable.vue'
|
import FundsTable from '@/pages/menuPages/customers/base/components/fundsTable.vue'
|
||||||
import ReferralsTable from '@/pages/menuPages/customers/base/components/referralsTable.vue'
|
import ReferralsTable from '@/pages/menuPages/customers/base/components/referralsTable.vue'
|
||||||
|
import CustomerPargarLogsTable from '@/pages/menuPages/customers/base/components/CustomerPargarLogsTable.vue'
|
||||||
import CustomerConditionalOrderTab from '@/pages/menuPages/customers/base/components/CustomerConditionalOrderTab.vue'
|
import CustomerConditionalOrderTab from '@/pages/menuPages/customers/base/components/CustomerConditionalOrderTab.vue'
|
||||||
import type { Order } from '@/model/order'
|
import type { Order } from '@/model/order'
|
||||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
@@ -374,12 +378,14 @@ const transactionTable = ref(null)
|
|||||||
const smsTable = ref(null)
|
const smsTable = ref(null)
|
||||||
const referralTable = ref(null)
|
const referralTable = ref(null)
|
||||||
const fundTable = ref(null)
|
const fundTable = ref(null)
|
||||||
|
const pargarLogsTable = ref<{ fetch?: () => void } | null>(null)
|
||||||
const refreshTable = () => table?.value?.fetch()
|
const refreshTable = () => table?.value?.fetch()
|
||||||
const refreshOrderTable = () => orderTable?.value?.fetch()
|
const refreshOrderTable = () => orderTable?.value?.fetch()
|
||||||
const refreshTransactionTable = () => transactionTable?.value?.fetch()
|
const refreshTransactionTable = () => transactionTable?.value?.fetch()
|
||||||
const refreshSMSTable = () => smsTable?.value?.fetch()
|
const refreshSMSTable = () => smsTable?.value?.fetch()
|
||||||
const refreshReferralTable = () => referralTable?.value?.fetch()
|
const refreshReferralTable = () => referralTable?.value?.fetch()
|
||||||
const refreshFundTable = () => fundTable?.value?.fetch()
|
const refreshFundTable = () => fundTable?.value?.fetch()
|
||||||
|
const refreshPargarLogsTable = () => pargarLogsTable.value?.fetch?.()
|
||||||
|
|
||||||
let updateKey = ref<number>(0)
|
let updateKey = ref<number>(0)
|
||||||
|
|
||||||
@@ -500,6 +506,7 @@ async function info(val: Customer) {
|
|||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
refreshFundTable()
|
refreshFundTable()
|
||||||
|
refreshPargarLogsTable()
|
||||||
refreshReferralTable()
|
refreshReferralTable()
|
||||||
refreshSMSTable()
|
refreshSMSTable()
|
||||||
refreshTransactionTable()
|
refreshTransactionTable()
|
||||||
@@ -678,6 +685,7 @@ async function syncPargarWallet(force = false) {
|
|||||||
|
|
||||||
await refreshWalletPanels()
|
await refreshWalletPanels()
|
||||||
refreshTransactionTable()
|
refreshTransactionTable()
|
||||||
|
refreshPargarLogsTable()
|
||||||
refreshTable()
|
refreshTable()
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
// فقط خطای واقعی شبکه/سرور — پیام ۴۲۲ را interceptor هم نشان میدهد؛ دوباره نزن
|
// فقط خطای واقعی شبکه/سرور — پیام ۴۲۲ را interceptor هم نشان میدهد؛ دوباره نزن
|
||||||
@@ -691,6 +699,7 @@ async function syncPargarWallet(force = false) {
|
|||||||
|
|
||||||
await refreshWalletPanels()
|
await refreshWalletPanels()
|
||||||
refreshTransactionTable()
|
refreshTransactionTable()
|
||||||
|
refreshPargarLogsTable()
|
||||||
refreshTable()
|
refreshTable()
|
||||||
|
|
||||||
if (applied) {
|
if (applied) {
|
||||||
|
|||||||
@@ -212,6 +212,19 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<a-form-item name="description" class="!mb-0">
|
||||||
|
<template #label>
|
||||||
|
<DashboardLabelWithHelp label="توضیح محصول" :help="productDescriptionHelp" size="sm" />
|
||||||
|
</template>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="form.description"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="متن توضیح برای نمایش در اپ مشتری (اختیاری)"
|
||||||
|
:maxlength="2000"
|
||||||
|
show-count
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<div v-if="!isMeltedGroup" class="product-editor-panel flex flex-col gap-4">
|
<div v-if="!isMeltedGroup" class="product-editor-panel flex flex-col gap-4">
|
||||||
<div class="product-spec-switch-row">
|
<div class="product-spec-switch-row">
|
||||||
<div class="product-spec-label">
|
<div class="product-spec-label">
|
||||||
@@ -523,6 +536,11 @@ const titleHelp: DashboardHelp = {
|
|||||||
description: 'نام نمایشی محصول در اپ کاربر و پنل.',
|
description: 'نام نمایشی محصول در اپ کاربر و پنل.',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const productDescriptionHelp: DashboardHelp = {
|
||||||
|
description:
|
||||||
|
'متن توضیح محصول که در اپ مشتری، بعد از انتخاب محصول در صفحه خرید/فروش نمایش داده میشود (اگر سوییچ «نمایش جزئیات اطلاعات محصول» در تنظیمات روشن باشد).',
|
||||||
|
}
|
||||||
|
|
||||||
const categoryHelp: DashboardHelp = {
|
const categoryHelp: DashboardHelp = {
|
||||||
description: 'دستهبندی محصول در تبهای اپ (سکه، شمش، آبشده و …).',
|
description: 'دستهبندی محصول در تبهای اپ (سکه، شمش، آبشده و …).',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -420,6 +420,7 @@ function resetData() {
|
|||||||
has_physical_delivery: false,
|
has_physical_delivery: false,
|
||||||
min_physical_delivery_quantity: undefined,
|
min_physical_delivery_quantity: undefined,
|
||||||
inventory: 0,
|
inventory: 0,
|
||||||
|
description: '',
|
||||||
min_order_cash: undefined,
|
min_order_cash: undefined,
|
||||||
max_order_cash: undefined,
|
max_order_cash: undefined,
|
||||||
auto_open_at: dayjs('00:00:00', 'HH:mm:ss'),
|
auto_open_at: dayjs('00:00:00', 'HH:mm:ss'),
|
||||||
@@ -440,6 +441,7 @@ const PRICING_FIELDS = new Set([
|
|||||||
])
|
])
|
||||||
const DETAILS_FIELDS = new Set([
|
const DETAILS_FIELDS = new Set([
|
||||||
'title',
|
'title',
|
||||||
|
'description',
|
||||||
'group_type',
|
'group_type',
|
||||||
'metal_id',
|
'metal_id',
|
||||||
'amount',
|
'amount',
|
||||||
|
|||||||
Reference in New Issue
Block a user