188 lines
6.4 KiB
Vue
188 lines
6.4 KiB
Vue
<template>
|
||||
|
|
<div class="min-w-0 w-full max-w-full overflow-x-hidden">
|
|||
|
|
<BasicShowContext title="اسناد زرین">
|
|||
|
|
<div v-if="!isMobile" 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="!record.zarin_id && !record.customer?.moshtari_code"
|
|||
|
|
placement="bottom"
|
|||
|
|
class="cursor-pointer"
|
|||
|
|
@click="openRegister(record)"
|
|||
|
|
>
|
|||
|
|
<template #title><span>ثبت مشتری در زرین</span></template>
|
|||
|
|
<Icon icon="vuesax-linear:profile-add" color="#7C3AED" />
|
|||
|
|
</a-tooltip>
|
|||
|
|
|
|||
|
|
<!-- دکمه ۳: ارسال به زرین (فقط اگر هنوز در زرین ثبت نشده) -->
|
|||
|
|
<a-tooltip
|
|||
|
|
v-if="!record.zarin_id"
|
|||
|
|
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>
|
|||
|
|
|
|||
|
|
<ZarinMobileCardList v-else ref="mobileListRef" />
|
|||
|
|
</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="selected?.sync_log" class="rounded-lg bg-red-50 p-3 text-red-700 whitespace-pre-wrap">
|
|||
|
|
{{ selected.sync_log }}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</BasicModal>
|
|||
|
|
|
|||
|
|
<!-- مودال ارسال به زرین -->
|
|||
|
|
<ZarinRetryModal
|
|||
|
|
v-model="sendVisible"
|
|||
|
|
mode="retry-sanad"
|
|||
|
|
:zarin-id="selected?.id"
|
|||
|
|
@success="fetch"
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<!-- مودال ثبت مشتری در زرین -->
|
|||
|
|
<ZarinRetryModal
|
|||
|
|
v-model="registerVisible"
|
|||
|
|
mode="register-customer"
|
|||
|
|
:customer-id="selected?.customer_id"
|
|||
|
|
:customer-name="selected?.customer?.name"
|
|||
|
|
@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 { getZarinTable, type ZarinRecord } from '@/api/zarin'
|
|||
|
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
|||
|
|
import { isMobile } from '@core/utils/is'
|
|||
|
|
import BasicModal from '@/components/BasicModal.vue'
|
|||
|
|
import ZarinRetryModal from '@/components/ZarinRetryModal.vue'
|
|||
|
|
import ZarinMobileCardList from '@/pages/menuPages/accounting/components/ZarinMobileCardList.vue'
|
|||
|
|
import { zarinStatusLabel } from '@/pages/menuPages/accounting/utils/zarinStatus'
|
|||
|
|
import { toJalali } from '@core/utils/useDataTime'
|
|||
|
|
|
|||
|
|
const [submit, reload] = useBaseTable()
|
|||
|
|
const mobileListRef = ref<null | { fetch: () => Promise<void> }>(null)
|
|||
|
|
const infoVisible = ref(false)
|
|||
|
|
const sendVisible = ref(false)
|
|||
|
|
const registerVisible = ref(false)
|
|||
|
|
const selected = ref<ZarinRecord | null>(null)
|
|||
|
|
|
|||
|
|
const columns = [
|
|||
|
|
{
|
|||
|
|
title: 'ردیف',
|
|||
|
|
dataIndex: 'id',
|
|||
|
|
key: 'id',
|
|||
|
|
filterable: false,
|
|||
|
|
sortable: false,
|
|||
|
|
customRender: (r: any) => r.index + 1
|
|||
|
|
},
|
|||
|
|
{ title: 'مشتری', dataIndex: 'customer.name', key: 'customer.name', type: 'Text' },
|
|||
|
|
{ title: 'نوع', dataIndex: 'type', key: 'type', type: 'Text' },
|
|||
|
|
{ title: 'مقدار', dataIndex: 'amount', key: 'amount', type: 'Number' },
|
|||
|
|
{ title: 'شرح', dataIndex: 'desc', key: 'desc', type: 'Text' },
|
|||
|
|
{
|
|||
|
|
title: 'وضعیت',
|
|||
|
|
dataIndex: 'sync_status',
|
|||
|
|
key: 'sync_status',
|
|||
|
|
type: 'Text',
|
|||
|
|
filterable: false,
|
|||
|
|
customRender: (r: any) => zarinStatusLabel(r.record.sync_status, r.record.zarin_id)
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
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) => getZarinTable(params)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
/** اطلاعاتی که برای هر سند حسابداری نیاز است (بدون جزئیات زرینمحور) */
|
|||
|
|
const infoItems = computed(() => {
|
|||
|
|
const row = selected.value
|
|||
|
|
if (!row) return []
|
|||
|
|
return [
|
|||
|
|
{ label: 'شناسه سند', value: row.id },
|
|||
|
|
{ label: 'مشتری', value: row.customer?.name },
|
|||
|
|
{ label: 'موبایل', value: row.customer?.mobile },
|
|||
|
|
{ label: 'نوع', value: row.type },
|
|||
|
|
{ label: 'مقدار', value: row.amount },
|
|||
|
|
{ label: 'شرح', value: row.desc },
|
|||
|
|
{ label: 'زمان ثبت', value: row.created_at ? toJalali(row.created_at) : '-' },
|
|||
|
|
{ label: 'وضعیت', value: zarinStatusLabel(row.sync_status, row.zarin_id) },
|
|||
|
|
{ label: 'کد زرین', value: row.zarin_id || 'ثبت نشده' }
|
|||
|
|
]
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
function openInfo(record: ZarinRecord) {
|
|||
|
|
selected.value = record
|
|||
|
|
infoVisible.value = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function openSend(record: ZarinRecord) {
|
|||
|
|
selected.value = record
|
|||
|
|
sendVisible.value = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function openRegister(record: ZarinRecord) {
|
|||
|
|
selected.value = record
|
|||
|
|
registerVisible.value = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function fetch() {
|
|||
|
|
if (isMobile.value) {
|
|||
|
|
await mobileListRef.value?.fetch?.()
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
await reload()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
defineExpose({ fetch })
|
|||
|
|
</script>
|