Shayegan was rejected as inactive when editing moshtari_code. The document list now uses the shared table format. Co-authored-by: Cursor <cursoragent@cursor.com>
222 lines
6.2 KiB
Vue
222 lines
6.2 KiB
Vue
<template>
|
|
<div class="min-w-0 w-full max-w-full overflow-x-hidden">
|
|
<BasicShowContext title="اسناد شایگان" :help="help">
|
|
<template #extra>
|
|
<a-button size="small" :loading="healthLoading" @click="runHealth">تست اتصال</a-button>
|
|
</template>
|
|
|
|
<a-alert
|
|
v-if="healthMessage"
|
|
:type="healthOk ? 'success' : 'error'"
|
|
:message="healthMessage"
|
|
show-icon
|
|
closable
|
|
class="mb-2"
|
|
@close="healthMessage = ''"
|
|
/>
|
|
|
|
<div class="min-w-0 w-full max-w-full overflow-x-auto">
|
|
<BaseTable v-bind="tblProps" @register="submit">
|
|
<template #status="{ record }">
|
|
<a-tag :color="statusColor(record.sync_status)">{{ statusLabel(record.sync_status) }}</a-tag>
|
|
</template>
|
|
<template #ops="{ record }">
|
|
<div class="flex justify-center">
|
|
<a-tooltip
|
|
v-if="record.sync_status !== 'success'"
|
|
placement="bottom"
|
|
class="cursor-pointer"
|
|
@click="retry(record)"
|
|
>
|
|
<template #title><span>ارسال مجدد</span></template>
|
|
<Icon icon="vuesax-linear:send-2" color="#CA8A04" />
|
|
</a-tooltip>
|
|
</div>
|
|
</template>
|
|
</BaseTable>
|
|
</div>
|
|
</BasicShowContext>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { Modal, message } from 'ant-design-vue'
|
|
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
|
import type { TableInput } from '@core/type/baseTable'
|
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
|
import { toJalali } from '@core/utils/useDataTime'
|
|
import { usePrice } from '@core/utils/usePrice'
|
|
import { shayeganHealth, shayeganRetry, shayeganTable } from '@/api/shayegan'
|
|
|
|
const help =
|
|
'وضعیت ارسال به حسابگر. تست اتصال فقط خواندنی است و سند آزمایشی در CYPRSD04 نمیسازد.'
|
|
|
|
const TYPE_LABELS: Record<string, string> = {
|
|
customer: 'ثبت مشتری',
|
|
trade: 'معامله',
|
|
wallet_cash: 'کیف ریالی',
|
|
wallet_gold: 'کیف محصول'
|
|
}
|
|
|
|
const STATUS_LABELS: Record<string, string> = {
|
|
success: 'موفق',
|
|
failed: 'ناموفق',
|
|
timeout: 'تایماوت',
|
|
pending: 'در انتظار'
|
|
}
|
|
|
|
const [submit, reload] = useBaseTable()
|
|
const healthLoading = ref(false)
|
|
const healthOk = ref(false)
|
|
const healthMessage = ref('')
|
|
|
|
const columns = [
|
|
{ title: 'شناسه', dataIndex: 'id', key: 'id', width: 80, type: 'Number', filterable: false, sortable: false },
|
|
{
|
|
title: 'نوع',
|
|
dataIndex: 'type',
|
|
key: 'type',
|
|
type: 'Text',
|
|
customRender: (r: any) => typeLabel(r.record?.type)
|
|
},
|
|
{
|
|
title: 'مبلغ/مقدار',
|
|
dataIndex: 'amount',
|
|
key: 'amount',
|
|
type: 'Number',
|
|
filterable: false,
|
|
customRender: (r: any) => (r.record?.amount == null || r.record?.amount === '' ? '-' : usePrice(r.record.amount, true, ''))
|
|
},
|
|
{
|
|
title: 'وضعیت',
|
|
dataIndex: 'sync_status',
|
|
key: 'sync_status',
|
|
slot: 'status',
|
|
type: 'Text'
|
|
},
|
|
{ title: 'شماره شایگان', dataIndex: 'shayegan_number', key: 'shayegan_number', type: 'Text' },
|
|
{ title: 'توضیح', dataIndex: 'desc', key: 'desc', type: 'Text' },
|
|
{
|
|
title: 'زمان',
|
|
dataIndex: 'created_at',
|
|
key: 'created_at',
|
|
type: 'DateTime',
|
|
filterable: false,
|
|
customRender: (r: any) => (r.record?.created_at ? toJalali(r.record.created_at) : '-')
|
|
},
|
|
{
|
|
title: 'عملیات',
|
|
dataIndex: 'ops',
|
|
key: 'ops',
|
|
slot: 'ops',
|
|
width: 110,
|
|
filterable: false,
|
|
sortable: false
|
|
}
|
|
]
|
|
|
|
function asTable(res: any, params: TableInput) {
|
|
if (res?.query) {
|
|
return {
|
|
rows: Array.isArray(res.rows) ? res.rows : [],
|
|
query: {
|
|
...params,
|
|
...res.query,
|
|
filters: res.query.filters ?? []
|
|
}
|
|
}
|
|
}
|
|
const rows = Array.isArray(res)
|
|
? res
|
|
: Array.isArray(res?.data)
|
|
? res.data
|
|
: Array.isArray(res?.rows)
|
|
? res.rows
|
|
: []
|
|
return {
|
|
rows,
|
|
query: {
|
|
page: Number(res?.current_page ?? params.page ?? 1),
|
|
limit: Number(res?.per_page ?? params.limit ?? 20),
|
|
total: Number(res?.total ?? rows.length),
|
|
filters: params.filters ?? [],
|
|
search: params.search ?? '',
|
|
select: params.select ?? []
|
|
}
|
|
}
|
|
}
|
|
|
|
const tblProps = {
|
|
columns,
|
|
defaultPageLimit: 20,
|
|
api: async (params: TableInput) => {
|
|
try {
|
|
return asTable(await shayeganTable(params), params)
|
|
} catch (e: any) {
|
|
message.error(e?.message || 'خطا در دریافت اسناد شایگان')
|
|
throw e
|
|
}
|
|
}
|
|
}
|
|
|
|
function typeLabel(type?: string | null) {
|
|
if (!type) return '-'
|
|
return TYPE_LABELS[type] ?? type
|
|
}
|
|
|
|
function statusLabel(status?: string | null) {
|
|
if (!status) return '-'
|
|
return STATUS_LABELS[status] ?? status
|
|
}
|
|
|
|
function statusColor(status?: string) {
|
|
if (status === 'success') return 'green'
|
|
if (status === 'failed') return 'red'
|
|
if (status === 'timeout') return 'orange'
|
|
return 'blue'
|
|
}
|
|
|
|
async function runHealth() {
|
|
healthLoading.value = true
|
|
healthMessage.value = ''
|
|
try {
|
|
const res: any = await shayeganHealth()
|
|
healthOk.value = !!res?.ok
|
|
healthMessage.value = res?.message || (res?.ok ? 'اتصال برقرار است' : 'اتصال ناموفق')
|
|
} catch (e: any) {
|
|
healthOk.value = false
|
|
healthMessage.value = e?.response?.data?.message || e?.message || 'خطای تست اتصال'
|
|
} finally {
|
|
healthLoading.value = false
|
|
}
|
|
}
|
|
|
|
function retry(record: any) {
|
|
const isTimeout = record.sync_status === 'timeout'
|
|
Modal.confirm({
|
|
title: 'ارسال مجدد به شایگان',
|
|
content: isTimeout
|
|
? 'این سند timeout شده. فقط اگر در حسابگر ثبت نشده، تأیید کنید.'
|
|
: 'سند دوباره به شایگان ارسال شود؟',
|
|
okText: 'ارسال',
|
|
cancelText: 'انصراف',
|
|
onOk: async () => {
|
|
try {
|
|
await shayeganRetry(record.id, isTimeout)
|
|
message.success('انجام شد')
|
|
await reload()
|
|
} catch (e: any) {
|
|
message.error(e?.response?.data?.message || e?.message || 'خطا')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
async function fetch() {
|
|
await reload()
|
|
}
|
|
|
|
defineExpose({ fetch })
|
|
</script>
|