fix bug of pargar 4

This commit is contained in:
2026-07-26 21:29:10 +03:30
parent 9d20b99579
commit 993de3a4cf
4 changed files with 170 additions and 1 deletions
@@ -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>
+2
View File
@@ -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'