Files
boursecu_admin/src/pages/menuPages/accounting/components/shayeganTable.vue
T
safavimohadeseh78andCursor 8a4f95da7d feat(accounting): Shayegan docs tab and fixed provider UI
Show Shayegan sync table/health in admin and always treat boursecu accounting as Shayegan.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-05 17:12:55 +03:30

146 lines
4.5 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="flex h-full min-h-0 w-full flex-col gap-2">
<div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between shrink-0">
<div class="min-w-0">
<div class="font-medium">اسناد شایگان</div>
<div class="text-xs opacity-70">
وضعیت ارسال به حسابگر. تست اتصال فقط خواندنی است و سند آزمایشی در CYPRSD04 نمی‌سازد.
</div>
</div>
<div class="grid grid-cols-2 gap-2 sm:flex sm:w-auto">
<a-button :loading="healthLoading" @click="runHealth">تست اتصال</a-button>
<a-button type="primary" :loading="loading" @click="fetch">بروزرسانی</a-button>
</div>
</div>
<a-alert
v-if="healthMessage"
:type="healthOk ? 'success' : 'error'"
:message="healthMessage"
show-icon
closable
class="shrink-0"
@close="healthMessage = ''"
/>
<a-table
class="min-h-0 flex-1"
size="small"
:loading="loading"
:columns="columns"
:data-source="rows"
:pagination="pagination"
row-key="id"
@change="onTableChange"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'sync_status'">
<a-tag :color="statusColor(record.sync_status)">{{ record.sync_status }}</a-tag>
</template>
<template v-else-if="column.key === 'actions'">
<a-button
size="small"
:disabled="record.sync_status === 'success'"
@click="retry(record)"
>
ارسال مجدد
</a-button>
</template>
</template>
</a-table>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { Modal, message } from 'ant-design-vue'
import { shayeganHealth, shayeganRetry, shayeganTable } from '@/api/shayegan'
const loading = ref(false)
const healthLoading = ref(false)
const healthOk = ref(false)
const healthMessage = ref('')
const rows = ref<any[]>([])
const pagination = reactive({
current: 1,
pageSize: 20,
total: 0,
showSizeChanger: true
})
const columns = [
{ title: 'شناسه', dataIndex: 'id', key: 'id', width: 70 },
{ title: 'نوع', dataIndex: 'type', key: 'type', width: 110 },
{ title: 'مبلغ/مقدار', dataIndex: 'amount', key: 'amount', width: 110 },
{ title: 'وضعیت', dataIndex: 'sync_status', key: 'sync_status', width: 100 },
{ title: 'شماره شایگان', dataIndex: 'shayegan_number', key: 'shayegan_number', width: 120 },
{ title: 'توضیح', dataIndex: 'desc', key: 'desc' },
{ title: 'عملیات', key: 'actions', width: 120 }
]
function statusColor(status: string) {
if (status === 'success') return 'green'
if (status === 'failed') return 'red'
if (status === 'timeout') return 'orange'
return 'blue'
}
async function fetch() {
loading.value = true
try {
const res: any = await shayeganTable({
page: pagination.current,
per_page: pagination.pageSize
})
rows.value = res?.data ?? []
pagination.total = res?.total ?? 0
} catch (e: any) {
message.error(e?.message || 'خطا در دریافت اسناد شایگان')
} finally {
loading.value = false
}
}
function onTableChange(pag: any) {
pagination.current = pag.current
pagination.pageSize = pag.pageSize
fetch()
}
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 شده. فقط اگر در حسابگر ثبت نشده، تأیید کنید.'
: 'سند دوباره به شایگان ارسال شود؟',
onOk: async () => {
try {
await shayeganRetry(record.id, isTimeout)
message.success('انجام شد')
fetch()
} catch (e: any) {
message.error(e?.response?.data?.message || e?.message || 'خطا')
}
}
})
}
onMounted(fetch)
defineExpose({ fetch })
</script>