瀏覽代碼

fix: 门店级取数参数自愈——现行参数全零时自动改用该店真实连锁ID/空连锁ID重试(A/B/D 对照自动化进同步),完成日志带命中数

KenZ1117 2 周之前
父節點
當前提交
6d3664cf8c
共有 2 個文件被更改,包括 36 次插入 和 8 次删除
  1. 34 7
      napos-service.js
  2. 2 1
      server/routes/reports.js

+ 34 - 7
napos-service.js

@@ -422,9 +422,9 @@ const syncState = {
 
 function syncSnapshot() {
   const { running, cancelRequested, startedAt, finishedAt, error, entity, from, to,
-    planTotal, done, current, added, updated, failed } = syncState;
+    planTotal, done, current, added, updated, failed, variantHits } = syncState;
   return { running, cancelRequested, startedAt, finishedAt, error,
-    entity, from, to, planTotal, done, current, added, updated, failed };
+    entity, from, to, planTotal, done, current, added, updated, failed, variantHits: variantHits || 0 };
 }
 
 function dayShift(ymd, delta) {
@@ -454,7 +454,7 @@ async function runSync({ from, to, scope = 'all', chainId, shopIds, port } = {})
   Object.assign(syncState, {
     running: true, cancelRequested: false, startedAt: new Date().toISOString(), finishedAt: null,
     error: null, entity: null, from: null, to: null,
-    planTotal: 0, done: 0, current: '准备中', added: 0, updated: 0, failed: 0, steps: [],
+    planTotal: 0, done: 0, current: '准备中', added: 0, updated: 0, failed: 0, steps: [], variantHits: 0,
   });
 
   try {
@@ -490,10 +490,7 @@ async function runSync({ from, to, scope = 'all', chainId, shopIds, port } = {})
       for (const s of shops) {
         jobs.push({
           kind: 'shop', label: `门店·${s.shopName}`, params: { chainId: '-1', shopListIn: String(s.shopId) },
-          fn: () => callHistory(
-            { chainId: '-1', shopListIn: String(s.shopId) },
-            { scope: 'shop', shopId: s.shopId, shopName: s.shopName, chainId: s.chainId || '', chainName: s.chainName || '' },
-          ),
+          fn: () => callShopHistory(s, usedPort),
         });
       }
     }
@@ -537,6 +534,7 @@ async function runSync({ from, to, scope = 'all', chainId, shopIds, port } = {})
       cancelled: syncState.cancelRequested,
       added: syncState.added, updated: syncState.updated, failed: syncState.failed,
       done: syncState.done, total: syncState.planTotal,
+      variantHits: syncState.variantHits || 0,
       steps: syncState.steps,
     };
     store.appendSyncLog(entity.key, run);
@@ -583,6 +581,35 @@ async function callHistory(scopeKey, ctx, port = DEFAULT_CDP_PORT) {
   return daily;
 }
 
+/** 门店行是否有真实数据(全零 = 取数异常形态或确实无营业) */
+function shopRowsHaveData(rows) {
+  return (rows || []).some((r) => (Number(r.validOrderCnt) || 0) > 0 || (Number(r.grossAmt) || 0) > 0
+    || (Number(r.incomeAmt) || 0) > 0 || (Number(r.expUv) || 0) > 0);
+}
+
+/** 门店级取数(参数自愈):现行 chainId=-1+shopListIn 在部分账号(尤其新开单校区账号)
+ *  返回全零而接口侧数据确实存在。把取数诊断的 A/B/D 对照自动化进同步:
+ *  A 现行(-1) → B 该店真实连锁ID → D 空连锁ID,哪个变体取到真实数据就用哪个;
+ *  三种都全零则按合法无营业返回首个结果(多花的两次请求量级可接受)。 */
+async function callShopHistory(s, port = DEFAULT_CDP_PORT) {
+  const ctx = { scope: 'shop', shopId: s.shopId, shopName: s.shopName, chainId: s.chainId || '', chainName: s.chainName || '' };
+  const variants = [
+    { tag: 'A', scopeKey: { chainId: '-1', shopListIn: String(s.shopId) } },
+    ...(s.chainId ? [{ tag: 'B', scopeKey: { chainId: String(s.chainId), shopListIn: String(s.shopId) } }] : []),
+    { tag: 'D', scopeKey: { chainId: '', shopListIn: String(s.shopId) } },
+  ];
+  let fallback;
+  for (const v of variants) {
+    const rows = await callHistory(v.scopeKey, ctx, port);
+    if (shopRowsHaveData(rows)) {
+      if (v.tag !== 'A') syncState.variantHits = (syncState.variantHits || 0) + 1;
+      return rows;
+    }
+    if (!fallback) fallback = rows;
+  }
+  return fallback;
+}
+
 function requestSyncCancel() {
   if (syncState.running) syncState.cancelRequested = true;
   return syncSnapshot();

+ 2 - 1
server/routes/reports.js

@@ -127,8 +127,9 @@ function register(app, ctx) {
     entityPromise.then(async (snap) => {
       if (!snap) return; // 失败已在 catch 记日志
       if (snap.entity) {
+        const extra = snap.variantHits > 0 ? `,${snap.variantHits} 家门店改用连锁ID参数取到数据` : '';
         ctx.logs.pushSystemLog(
-          `同步完成:${snap.entity.name},新增 ${snap.added} 行、更新 ${snap.updated} 行、失败 ${snap.failed} 项`,
+          `同步完成:${snap.entity.name},新增 ${snap.added} 行、更新 ${snap.updated} 行、失败 ${snap.failed} 项${extra}`,
           snap.failed > 0 ? 'warn' : 'success'
         );
       }