Bläddra i källkod

feat: 校区关联统计纳入平台明细;店铺运营空态区分平台数据

liangzhao 2 veckor sedan
förälder
incheckning
c41607e6aa
2 ändrade filer med 28 tillägg och 7 borttagningar
  1. 12 6
      public/ops.js
  2. 16 1
      server/routes/schools.js

+ 12 - 6
public/ops.js

@@ -242,12 +242,18 @@
       return;
     }
     if (!summary.rowCount) {
-      body.innerHTML = `
-        <div class="empty-hint ops-empty">
-          <p>还没有店铺运营数据</p>
-          <small>上传商家后台导出的人工统计表(.xlsx),解析后按学校 / 店铺 / 日期查看</small>
-          <button type="button" class="btn btn-primary btn-small" id="opsEmptyUpload" style="margin-top:14px">上传文件</button>
-        </div>`;
+      const platformRows = Number(summary.platformRowCount) || 0;
+      body.innerHTML = platformRows > 0
+        ? `<div class="empty-hint ops-empty">
+            <p>已导入 ${platformRows} 行平台明细</p>
+            <small>平台全字段数据已入库(可在「导入记录」查看原件与行数);<br>上报人工统计表后,这里会显示指标矩阵</small>
+            <button type="button" class="btn btn-primary btn-small" id="opsEmptyUpload" style="margin-top:14px">上传文件</button>
+          </div>`
+        : `<div class="empty-hint ops-empty">
+            <p>还没有店铺运营数据</p>
+            <small>上传商家后台导出的人工统计表(.xlsx),解析后按学校 / 店铺 / 日期查看</small>
+            <button type="button" class="btn btn-primary btn-small" id="opsEmptyUpload" style="margin-top:14px">上传文件</button>
+          </div>`;
       $('opsEmptyUpload').addEventListener('click', openUpload);
       return;
     }

+ 16 - 1
server/routes/schools.js

@@ -20,22 +20,37 @@ function register(app, ctx) {
     // 关联运营数据:按学校名(含别名)匹配 ops_shop.school 与 ops_row.school
     let shops = [];
     let rows = [];
+    let platformRows = [];
     let opsAvailable = false;
     try {
       const summary = await opsStore.summary();
       shops = summary.shops || [];
       rows = await opsStore.queryRows({});
+      platformRows = await opsStore.queryPlatformRows({});
       opsAvailable = true;
     } catch { /* ops 库不可用:只影响关联字段 */ }
 
     const payload = schools.map((school) => {
       const names = namesOf(school);
-      const shopCount = shops.filter((s) => names.has(String(s.school || ''))).length;
+      // 门店口径:人工表的 shop_key 与平台明细的 shopId 取并集
+      const shopKeys = new Set();
+      for (const shop of shops) {
+        if (names.has(String(shop.school || ''))) shopKeys.add(String(shop.key || shop.shopId || ''));
+      }
+      for (const row of platformRows) {
+        if (names.has(String(row.school || ''))) shopKeys.add(String(row.shopId || ''));
+      }
+      shopKeys.delete('');
+      const shopCount = shopKeys.size;
       let lastDate = '';
       for (const row of rows) {
         if (!names.has(String(row.school || ''))) continue;
         if (!lastDate || row.date > lastDate) lastDate = row.date;
       }
+      for (const row of platformRows) {
+        if (!names.has(String(row.school || ''))) continue;
+        if (!lastDate || row.date > lastDate) lastDate = row.date;
+      }
       return {
         ...school,
         ops: opsAvailable ? { shopCount, lastDate: lastDate || null } : null,