feat(wst): 超时未发加「导出明细」+ 武进安能不考核 + 钉钉明细带快递;修复推送时区 #87
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "yanhui-wst-export-20261027"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
目的与范围
业务 2026-10-27 四条要求 + 一个线上 bug,全部落在「仓储中心 24 小时发货时效」这一个模块:
GET /export+ 前端 DropdownEXCLUDED_CARRIERSbuildDetailLinepushShipTimelinessNotify改动文件 7 个(3 后端源码 + 2 测试 + 2 前端),无新增依赖、无表结构变更、无配置项变更。
① 导出明细
GET /api/warehouse-ship-timeliness/export:与/list共用getShipTimeliness,只是
fullDetail: true—— 不分页、不截断,返回本轮考核口径内的全部行。文件名
仓储中心发货时效_超时未发_<仓或全部仓库>_13点轮_2026-10-27.xlsx。centerKey过滤,与后端算超时用的主仓归属是同一套。String()—— 聚水潭单号 19 位,数字形态在 Excel 里会变科学计数法。
EXPORT_COLUMNS,不复用页面的DETAIL_COLUMNS:后者
title是 JSX(带 Tooltip),导出会变成[object Object]当表头。② 缓存改为「存全量、出口截断」
getShipTimeliness原来把limit拼进缓存键、并在建 payload 时就 slice。后果:页面
limit=1000、导出要全量 → 两边永不命中,每点一次导出都重查一遍 402 万行视图。改为:缓存键只留
round.key|round.date,payload 存全量,出口用withDetailLimit(payload, limit)切。顺带修正
detailTotal/heldTotal(截断前的真实总数)—— 页面原来用orders.length显示「共 N 单」,截断时会把「只显示前 1000 条」写成「一共就这么点」。
③ 武进安能不考核
EXCLUDED_CARRIERS = ['自提', '中铁', '壹米滴答', '武进安能'],物流公司名包含匹配,「武进安能大件」一起命中。
⚠️ 严格不泛化成「安能」。实测近 30 天
logistic_company_name带「安能」的有 8 个写法:业务确认只剔「武进安能」,其余(尤其单量最大的「常州安能新」)照旧考核。
与
warehouseLogisticsExceptionRegistry同一口径,那里也明写着「武进安能必须精确,别泛化成安能」。页面顶部 / 页脚 / 钉钉正文里的快递清单全部改成读服务层的
EXCLUDED_CARRIERS,不再前端写死 —— 这次就是写死的文案忘了改,页面和群里口径会对不上。
④ 钉钉明细加「快递」
群里看到超时单能直接判断是哪家快递、要不要走站点,不用回页面逐单点开。
⑤ 修复推送时区(线上 bug,重要)
生产容器
/etc/timezone = Etc/UTC。pushShipTimelinessNotify原来把裸new Date()传给
getShipTimeliness,而 service / registry 内部用getDate()/getHours()直读:修法与 2026-10-21 那次同源问题一致,拆两个「现在」:
rawNow—— 真实时刻,给chinaDateKey/minutesOfDay/toISOString;bjNow = beijingNow(rawNow)—— 平移成「本地 getter 读出来正好是北京时间」,给resolveRoundMeta/getShipTimeliness。本机是东八区,平移量为 0,所以本地表现不变;这也是它没被本地测试发现的原因。
同步与兼容性
/list返回体只新增detailTotal/heldTotal两个字段,原有字段语义不变(
orders仍按limit截断,truncated仍表示是否截断)。carrierSkipped由 2 → 4(自提/中铁/壹米滴答之外新增武进安能 2 单量级),超时单量相应减少;这是预期变化,不是回归。
/export。旧前端 + 新后端、新前端 + 旧后端都不会崩(旧后端没有
/export时按钮报「导出失败」),但必须同批部署才有功能。验证
单元测试
2 个失败是环境固有、与本次无关(改动前后一致):
cloudDatabaseConfigCache负缓存用例(要求业务库不可达)、resilientSecretStore0600 权限断言(Windows 返回 0o666)。新增/更新的用例:
/list共用同一份缓存(断言calls.state不增加)null时长给 0,不出现undefined/NaN前端
真实浏览器渲染(playwright,本地 5173 + 后端 4002)
/list与/export走 mock(避免每跑一次验收都压生产库),17/17 通过:undefined/NaN泄漏[object Object]),含「武进韵达」「未打单」占位仓储中心发货时效_超时未发_全部仓库_13点轮_2026-10-27.xlsx/..._崔桥工厂仓_....csv真实接口(本地后端 → 生产只读副本)13/13 通过
/list的detailTotal13/export包含/list的全部行(口径一致,缺 0 行)undefined/NaNlimit带来的收益(旧实现这里要再等一次 86 秒)风险与回退
exportTableFile落盘;页面表格仍按limit截断carrierSkipped计数beijingNow单测锁「任何机器时区下本地 getter 读出北京时间」;本次只是把 job 侧也接上,未改beijingNow本身回退:
git revert <merge_commit>即可,无数据迁移、无配置残留。唯一需人工留意的是钉钉消息格式回到 5 段(无消费方,无需处理)。
合规
main:无。分支yanhui-wst-export-20261027,单个提交。reset --hard、未删他人分支。.workbuddy/pr<N>-merge-authorization.md。① 导出明细(业务要求:超时未发要能导出核对) · 新增 GET /api/warehouse-ship-timeliness/export:不分页、不截断,返回本轮全部行 · 页面「超时未发货订单」卡片右上角加「导出明细」下拉(Excel / CSV) · 选中某个仓时只导该仓(前端按 centerKey 过滤,与后端主仓归属同一套) · 导出列比页面多「快递公司 / 运单号」(追单要看有没有打单),单号一律转字符串 避免 Excel 显示成科学计数法 ② 缓存改成「存全量、出口截断」 · 缓存键去掉 limit(原为企业级教训:WLE 核验缓存早就这么改了) · 页面 limit=1000、导出要全量,旧实现两边永不命中 → 每点一次导出重查一遍视图 · 实测:首次查询 86.3s,导出命中缓存 5ms · 顺带修 detailTotal / heldTotal:明细被截断时页面仍显示真实总数, 不再把「只显示前 1000 条」写成「一共就这么点」 ③ 不考核快递追加「武进安能」(业务 2026-10-27) · 包含匹配,同时覆盖「武进安能大件」 · ⚠️ 严格不泛化成「安能」:实测库里带「安能」的有 8 个写法, 常州安能新 4207 单 / 安能物流 110 单等仍照旧考核(与 warehouseLogisticsExceptionRegistry 同一口径,那里也写着这句) ④ 钉钉推送明细行在「线上单号」后加「快递」 · 一行 = 仓|内部单号|线上单号|快递|审核 时间|已等 X 小时 · 群里直接能判断是哪家快递、要不要走站点,不用回页面逐单点开 · 「已剔除 N 单不考核快递」的快递清单改成读服务层,别再各写一份 ⑤ 修复推送任务时区(生产容器 /etc/timezone = Etc/UTC) · 症状:pushShipTimelinessNotify 把裸 new Date() 传给 getShipTimeliness, 而 service / registry 内部用 getDate()/getHours() 直读 → 北京 13:05 = UTC 05:05,被判「未到 13:00 核验时间」→ 两轮推送永不触发 · 改法:rawNow(真实时刻,给 Intl / toISOString)+ bjNow(平移后, 给本地 getter 与 service 调用)双轨,与 2026-10-21 那次同源问题的修法一致