work on moving customers from tahesab 7
This commit is contained in:
@@ -384,17 +384,21 @@ async function load(panelPage = 1) {
|
||||
search: panelSearch.value || undefined,
|
||||
page: panelPage,
|
||||
})
|
||||
status.value = res
|
||||
// این درخواست دادههای تهحساب را شامل نمیشود؛ پس فیلدهای تهحساب را دستنخورده نگه میداریم
|
||||
if (status.value) {
|
||||
status.value.panel_total = res.panel_total
|
||||
status.value.panel_registered = res.panel_registered
|
||||
status.value.panel_only = res.panel_only
|
||||
status.value.panel_only_list = res.panel_only_list
|
||||
} else {
|
||||
status.value = res
|
||||
}
|
||||
panelList.value = res.panel_only_list.data
|
||||
panelPagination.value = {
|
||||
page: res.panel_only_list.current_page,
|
||||
lastPage: res.panel_only_list.last_page,
|
||||
total: res.panel_only_list.total,
|
||||
}
|
||||
// دادههای تهحساب فقط اگر قبلاً fetch شده باشه بروز کن
|
||||
if (tahesabFetched.value) {
|
||||
tahesabOnlyList.value = res.tahesab_only_list.data ?? []
|
||||
}
|
||||
} catch (e) { console.error(e) }
|
||||
finally { loadingPanel.value = false }
|
||||
}
|
||||
@@ -500,9 +504,12 @@ async function doImport(customers: TahesabOnlyCustomer[]) {
|
||||
if (res.success) {
|
||||
message.success(`${res.success} مشتری وارد پنل شد`)
|
||||
customers.forEach(c => { if (!res.errors.find((e: any) => e.code === c.code)) tahesabDone.add(c.code) })
|
||||
if (status.value?.tahesab_only_count != null) {
|
||||
status.value.tahesab_only_count = Math.max(0, status.value.tahesab_only_count - res.success)
|
||||
}
|
||||
}
|
||||
if (res.failed) message.warning(`${res.failed} مشتری وارد نشد`)
|
||||
await load(panelPagination.value.page)
|
||||
await loadPanel(panelPagination.value.page)
|
||||
selectedTahesab.clear()
|
||||
} catch { message.error('خطا در ارتباط با سرور') }
|
||||
finally { syncingTahesab.value = false }
|
||||
@@ -531,7 +538,10 @@ watch(() => importStore.doneCodes.length, () => {
|
||||
watch(() => importStore.status, async (s, prev) => {
|
||||
if (prev === 'running' && (s === 'done' || s === 'canceled')) {
|
||||
selectedTahesab.clear()
|
||||
await load(panelPagination.value.page)
|
||||
if (status.value?.tahesab_only_count != null) {
|
||||
status.value.tahesab_only_count = Math.max(0, status.value.tahesab_only_count - importStore.success)
|
||||
}
|
||||
await loadPanel(panelPagination.value.page)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@ export type ImportStatus = 'idle' | 'running' | 'done' | 'canceled'
|
||||
/** نتیجهٔ نهایی برای نمایش آیکن/متن مناسب */
|
||||
export type ImportOutcome = 'running' | 'success' | 'error' | 'partial' | 'canceled'
|
||||
|
||||
/** تعداد مشتری در هر درخواست (برای جلوگیری از محدودیت نرخ سرور) */
|
||||
const CHUNK_SIZE = 50
|
||||
|
||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
|
||||
|
||||
/**
|
||||
* فروشگاه سراسری برای فرایند «وارد کردن همه» مشتریان تهحساب.
|
||||
* چون بهصورت singleton است، با جابهجایی بین صفحات از بین نمیرود و
|
||||
@@ -100,6 +105,19 @@ export const useCustomerImportStore = defineStore('customerImport', () => {
|
||||
await runLoop()
|
||||
}
|
||||
|
||||
// ارسال یک دسته با تلاش مجدد در صورت خطا (مثلاً محدودیت نرخ موقتی)
|
||||
async function importChunkWithRetry(chunk: TahesabOnlyCustomer[], attempt = 0): Promise<any> {
|
||||
try {
|
||||
return await importFromTahesab(chunk)
|
||||
} catch (e) {
|
||||
if (attempt < 2 && !cancelRequested) {
|
||||
await sleep(1500 * (attempt + 1))
|
||||
return importChunkWithRetry(chunk, attempt + 1)
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
async function runLoop() {
|
||||
while (processed.value < queue.value.length) {
|
||||
if (cancelRequested) {
|
||||
@@ -107,29 +125,30 @@ export const useCustomerImportStore = defineStore('customerImport', () => {
|
||||
return
|
||||
}
|
||||
|
||||
const customer = queue.value[processed.value]
|
||||
const chunk = queue.value.slice(processed.value, processed.value + CHUNK_SIZE)
|
||||
try {
|
||||
const res = await importFromTahesab([customer])
|
||||
if (res.success) {
|
||||
success.value++
|
||||
doneCodes.value.push(customer.code)
|
||||
} else {
|
||||
failed.value++
|
||||
errors.value.push({
|
||||
code: customer.code,
|
||||
name: customer.name,
|
||||
error: res.errors?.[0]?.error || 'ثبت ناموفق بود',
|
||||
})
|
||||
const res = await importChunkWithRetry(chunk)
|
||||
const errCodes = new Set((res.errors ?? []).map((e: any) => e.code))
|
||||
for (const c of chunk) {
|
||||
if (errCodes.has(c.code)) {
|
||||
const err = (res.errors ?? []).find((e: any) => e.code === c.code)
|
||||
failed.value++
|
||||
errors.value.push({ code: c.code, name: c.name, error: err?.error || 'ثبت ناموفق بود' })
|
||||
} else {
|
||||
success.value++
|
||||
doneCodes.value.push(c.code)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
failed.value++
|
||||
errors.value.push({
|
||||
code: customer.code,
|
||||
name: customer.name,
|
||||
error: 'خطا در ارتباط با سرور',
|
||||
})
|
||||
// کل دسته ناموفق شد (مثلاً محدودیت نرخ یا قطع ارتباط)
|
||||
for (const c of chunk) {
|
||||
failed.value++
|
||||
errors.value.push({ code: c.code, name: c.name, error: 'خطا در ارتباط با سرور' })
|
||||
}
|
||||
}
|
||||
processed.value++
|
||||
processed.value += chunk.length
|
||||
// مکث کوتاه بین دستهها برای جلوگیری از محدودیت نرخ سرور
|
||||
if (processed.value < queue.value.length) await sleep(250)
|
||||
}
|
||||
|
||||
status.value = 'done'
|
||||
|
||||
Reference in New Issue
Block a user