fix bug of pargar 4
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<a-alert v-if="summary && summary.count > 0" type="warning" show-icon>
|
||||
<template #message>
|
||||
<div class="flex flex-wrap items-center gap-x-2 gap-y-1">
|
||||
<span class="font-bold">{{ summary.count }} سند پنل هنوز در پرگار ثبت نشده</span>
|
||||
<span v-if="summary.customers" class="text-xs text-gray-600">
|
||||
ماندهٔ {{ summary.customers }} مشتری تا ثبت این اسناد روی کیف اعمال نمیشود
|
||||
</span>
|
||||
<a-button type="link" size="small" :loading="loading" @click="load">بروزرسانی</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="flex flex-col gap-2 text-xs">
|
||||
<div class="text-gray-600">
|
||||
قدیمیترین سند {{ waitLabel(summary.waited_minutes) }} در صف است.
|
||||
<template v-if="lastConfirmedLabel">
|
||||
آخرین سندی که پرگار تحویل گرفته: {{ lastConfirmedLabel }}
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template v-if="!compact">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div v-for="row in visibleRows" :key="row.id" class="stuck-row">
|
||||
<span class="font-bold">{{ pargarTypeLabel(row.type) }} {{ row.export_id }}</span>
|
||||
<span>{{ row.customer_name || 'بدون مشتری' }}</span>
|
||||
<span dir="ltr">{{ amountLabel(row) }}</span>
|
||||
<span class="text-gray-500">{{ waitLabel(row.waited_minutes) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a-button
|
||||
v-if="summary.rows.length > PREVIEW_COUNT"
|
||||
type="link"
|
||||
size="small"
|
||||
class="self-start"
|
||||
@click="expanded = !expanded"
|
||||
>
|
||||
{{ expanded ? 'بستن لیست' : `${summary.rows.length - PREVIEW_COUNT} سند دیگر` }}
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
<div class="text-gray-500">
|
||||
پرگار این اسناد را با «دریافت اسناد» میگیرد؛ تا آن زمان ماندهٔ این مشتریها عمداً اعمال نمیشود.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-alert>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { getStuckOutbound, type StuckOutboundRow, type StuckOutboundSummary } from '@/api/pargar'
|
||||
import { pargarTypeLabel } from '../utils/pargarDisplay'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { toJalali } from '@core/utils/useDataTime'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
/** فقط خلاصه بدون لیست اسناد — برای داشبورد */
|
||||
compact?: boolean
|
||||
pollMs?: number
|
||||
/** سندی که کمتر از این مدت در صف است هنوز «گیرکرده» نیست */
|
||||
thresholdMinutes?: number
|
||||
}>(),
|
||||
{ compact: false, pollMs: 60000, thresholdMinutes: 15 }
|
||||
)
|
||||
|
||||
const PREVIEW_COUNT = 5
|
||||
|
||||
const summary = ref<StuckOutboundSummary>()
|
||||
const loading = ref(false)
|
||||
const expanded = ref(false)
|
||||
let timer: ReturnType<typeof setInterval> | undefined
|
||||
|
||||
const visibleRows = computed(() => {
|
||||
const rows = summary.value?.rows ?? []
|
||||
return expanded.value ? rows : rows.slice(0, PREVIEW_COUNT)
|
||||
})
|
||||
|
||||
const lastConfirmedLabel = computed(() =>
|
||||
summary.value?.last_confirmed_at ? toJalali(summary.value.last_confirmed_at) : ''
|
||||
)
|
||||
|
||||
function waitLabel(minutes: number): string {
|
||||
if (minutes < 60) return `${minutes} دقیقه`
|
||||
const hours = Math.floor(minutes / 60)
|
||||
if (hours < 24) return `${hours} ساعت`
|
||||
return `${Math.floor(hours / 24)} روز`
|
||||
}
|
||||
|
||||
function amountLabel(row: StuckOutboundRow): string {
|
||||
if (row.amount == null) return '—'
|
||||
if (row.type === 'wallet_cash') return usePrice(Math.abs(row.amount))
|
||||
return `${Math.abs(row.amount).toFixed(4)} گرم`
|
||||
}
|
||||
|
||||
async function load() {
|
||||
try {
|
||||
loading.value = true
|
||||
summary.value = await getStuckOutbound(props.thresholdMinutes)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void load()
|
||||
if (props.pollMs > 0) {
|
||||
timer = setInterval(() => void load(), props.pollMs)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
defineExpose({ load })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.stuck-row {
|
||||
@apply flex flex-wrap items-center gap-x-3 gap-y-1 rounded-lg bg-white/60 px-2 py-1;
|
||||
}
|
||||
</style>
|
||||
@@ -5,6 +5,7 @@
|
||||
class="flex h-full w-full min-w-0 max-w-full flex-col overflow-x-hidden"
|
||||
:class="activeTab === 'customer-sync' || activeTab === 'pargar-customer-sync' || activeTab === 'zarin-customer-sync' ? 'overflow-y-auto' : 'overflow-hidden'"
|
||||
>
|
||||
<PargarStuckOutboundAlert v-if="pargarEnabled" class="mb-3 shrink-0" />
|
||||
<ATabs v-model:activeKey="activeTab" class="mb-3 shrink-0">
|
||||
<ATabPane key="reports" tab="گزارشات" />
|
||||
<ATabPane v-if="tahesabEnabled" key="tahesab" tab="اسناد تهحساب" />
|
||||
@@ -155,6 +156,7 @@ import zarinTbl from './components/zarinTable.vue'
|
||||
import zarinCustomerSync from './components/ZarinCustomerSync.vue'
|
||||
import pargarTbl from './components/pargarTable.vue'
|
||||
import pargarCustomerSync from './components/PargarCustomerSync.vue'
|
||||
import PargarStuckOutboundAlert from './components/PargarStuckOutboundAlert.vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import BasicInfoModal from '@/components/BasicInfoModal/index.vue'
|
||||
import { message } from 'ant-design-vue/es'
|
||||
|
||||
Reference in New Issue
Block a user