yml2213
|
a7bac9c1d8
|
fix(admin): 恢复接单模板计价配置并统一成本价格链路
|
2026-11-02 17:57:49 +08:00 |
|
yml2213
|
d871b93fde
|
feat(admin): 增加履约渠道批量删除并统一分页配置
|
2026-11-02 17:31:55 +08:00 |
|
yml2213
|
290890e848
|
feat(cost-center): 统一接单模板成本并自动同步商品
|
2026-11-02 16:14:51 +08:00 |
|
zhaoxing
|
53fe841460
|
feat(consignment): 新增待抢单手枪一键查询匹配看板
- 寄售仓库刷新前新增「一键查询待匹配订单」入口
- 待抢单非拼单工单 × 在库待匹配现货,按系统/区服/系列/钻级/璀璨细粒度评分
- 支持关键字搜索、冲突项开关、刷新与分页
- 只读查询,不自动履约、不改工单
|
2026-11-02 14:59:46 +08:00 |
|
zhaoxing
|
13869d345f
|
feat(worker-platform): 商品名按来源追加可配置后缀
- 新增来源后缀配置(来源下拉、启停、备注,同一时间仅启用一个)
- 管理端列表/详情与打手端列表/详情/大厅展示「商品名(后缀)」
- 打手端 DTO 透出 sourceProvider,仅展示,不改写商品名
- 新增来源选项接口与前后端单测
|
2026-11-02 14:25:53 +08:00 |
|
zhaoxing
|
db73e8f820
|
refactor(collect): 移除旧补资料链接 token 体系
- 删除管理端生成补资料链接接口、链接仓储读写与 TTL 配置服务
- 删除补资料链接配置面板及前端相关服务、类型
- 新增迁移 113:删除 work_order_material_links 表与 work_order_material_link 配置
- 「复制补资料链接」改为本地复制 /supplement/<平台订单号>,不再请求后端
|
2026-11-01 18:26:07 +08:00 |
|
zhaoxing
|
a2cf48f5fc
|
feat(collect): 补资料改为订单号直连并按状态一次性提交
- 公开补资料页 /supplement/:订单号 直接按平台订单号查询,不再依赖链接记录;旧 token 链接一律 404
- 仅「待完善 + 未指派 + 无拼单份额」可提交,提交后状态变为待分配,重复提交返回 409
- 非可编辑工单只返回商品、工单号、状态与客服提示,不返回已填资料和截图
- 管理端新增「重置补资料」:待分配且未指派、无份额、未发布时一键重置回待完善
- 新增 canResetMaterial 能力与 material_reset 流转事件,工单状态文案统一为「待分配」
|
2026-11-01 18:12:44 +08:00 |
|
zhaoxing
|
aed76e047e
|
fix(admin): 用户付款金额改为单击修改
|
2026-11-01 16:30:22 +08:00 |
|
zhaoxing
|
53d9ff39ad
|
fix(admin): 用户付款金额单元格金额与编辑图标不换行
|
2026-11-01 16:26:40 +08:00 |
|
zhaoxing
|
5879568ad0
|
fix(worker): 用户付款金额仅待完善可修改并补后端校验
|
2026-11-01 16:22:45 +08:00 |
|
zhaoxing
|
c46d9083a8
|
Merge branch 'main' into dev
|
2026-11-01 15:53:27 +08:00 |
|
zhaoxing
|
2ce8f601df
|
fix(worker): 不满额拼单母单显示待抢单,满额后才按份额状态推进
|
2026-11-01 15:43:20 +08:00 |
|
zhaoxing
|
4fd533c678
|
fix(worker): 拼单单人撤单后空出份额回大厅并重算母单状态
|
2026-11-01 15:12:11 +08:00 |
|
zhaoxing
|
c1dd2ee632
|
feat(work-order): 后台支持修改用户付款金额并留痕
|
2026-11-01 14:14:23 +08:00 |
|
zhaoxing
|
da16e8cf75
|
Merge branch 'dev'
|
2026-11-01 12:30:02 +08:00 |
|
zhaoxing
|
15956e704f
|
feat(work-order): 新增一次性补资料链接
|
2026-11-01 10:46:31 +08:00 |
|
yml2213
|
fb485f7e36
|
feat(risk-control): 新增 IP/账号手动封禁,并收口财务同步的全表更新
- 风控:worker_risk_bans 表 + 前置封禁中间件(登录一并拦截)+ 后台列表/新增/解封
- 财务:成本快照补商品维度收口到本批 order_item_id,不再整表扫 899MB 的 order_items
- 性能:order_items 覆盖索引(迁移 110)、大厅 pageSize 上限 20、已读/上传接口限流
|
2026-10-30 20:15:14 +08:00 |
|
yml2213
|
c7d650b482
|
fix(worker): 售后追缴自动驳回提现并扣冻结资金,修复欠款抵扣 500
- 修复欠款抵扣 SQL 参数类型冲突(debt_amount = $1 与 $1 = 0 推断不一致),
此前手动偿还、验收报酬抵扣、充值/押金解冻/寄卖自动抵扣都会 500
- 追缴顺序改为 待解冻押金 → 提现冻结 → 可用余额 → 欠款:
驳回待审核提现并直接扣走冻结资金,扣不完的部分退回可用余额
- 迁移 109:售后单记录 withdraw_deduction_amount,补 pending 提现部分索引
- 新增流水类型 after_sales_withdraw_deduction,前后端展示与标签同步
- 提现驳回退回余额后补调欠款自动抵扣,与充值/结算/解冻/寄卖路径对齐
- 补追缴分配单测与 SQL 参数类型静态门禁
|
2026-10-29 19:05:37 +08:00 |
|
zhaoxing
|
2ddc26091c
|
feat:寄卖增加对接客服,页面移动到接单平台
|
2026-10-27 18:49:39 +08:00 |
|
zhaoxing
|
a53321ef30
|
feat:寄卖增加对接客服,db脚本迁移修复
|
2026-10-27 13:56:08 +08:00 |
|
zhaoxing
|
622bd779dd
|
feat:寄卖增加对接客服,db脚本迁移修复
|
2026-10-27 13:39:48 +08:00 |
|
zhaoxing
|
e686a77a9e
|
fix:拼单明细状态补齐中文映射
|
2026-10-27 11:01:19 +08:00 |
|
zhaoxing
|
919e228452
|
fix:拼单明细状态补齐中文映射
|
2026-10-27 10:34:21 +08:00 |
|
zhaoxing
|
2bfcdd5b1f
|
Merge branch 'dev1023' into dev
|
2026-10-26 15:26:43 +08:00 |
|
zhaoxing
|
6a5a8d70b0
|
feat:拼单订单新增一个取消部分的按钮功能,点击之后,打手进行中和待接单的都会取消订单
|
2026-10-26 12:15:52 +08:00 |
|
yml2213
|
31a8b6fc65
|
Merge branch 'dev1023' into dev
解决 9 个冲突文件,并修复合并后遗留问题:
- 大厅候选集:采用 FIFO 窗口 + 全部置顶单 UNION(列表与抢单/拼单复核同源)
- 拼单份额:采用多次参与模型(每次参与 INSERT 新份额、requestId 幂等),
取消后可重新参与;移除 HEAD 已废弃的单行 rejoin 逻辑与对应测试
- 工单迁移与成本中心 103–108 编号撞车:合并重写为
109_work_order_share_participation / 110_work_order_hall_and_shop_indexes;
临时库全量执行与重跑幂等验证通过(10 列、唯一键已删、7 个索引)
- 实时补丁:保留个性化字段、置顶重排、分页总数同步;补回 orderTimelineVisible 类型
- 打手大厅:保留 memo 组件化,移植「再拼一次」多份额按钮逻辑
- 全项目表格统一 PercentTable:WorkerOrderShareTable 改造
验证:backend typecheck/lint/check:sql/test(833 pass)、
frontend typecheck/lint/test(172 pass)/build 全绿。
|
2026-10-26 12:10:53 +08:00 |
|
zhaoxing
|
b0ab8cd410
|
feat:售后问题单新增一个搜索订单的功能,搜索key:售后单号,工单号,平台号,责任打手,同时加上状态筛选
|
2026-10-26 10:25:36 +08:00 |
|
yml2213
|
b7ad69831a
|
feat(cost-center): 统一商品成本中心为全系统唯一标准价格源并闭环改价与工单同步
- 核心架构:将商品与成本中心确立为全系统唯一标准价格源,接单模板价格在接单平台禁止编辑并提示收敛至成本中心,后端 saveAdminWorkProductRule 严格拦截价格篡改
- 改价与同步:标准商品目录与自动发货专属面板提供统一改价弹窗,支持追溯/立即生效/指定时间;改价后自动或手动将新价格同步至接单大厅待抢单工单,保持下游业务一致
- 缺陷修复:修复 cost_versions 追溯改价时因同生效时间违反 chk_cost_versions_period 检查约束及 uq_cost_versions_scope 唯一索引冲突的问题,采用 active 版本就地更新机制
- 分类树优化:工单二级分类树限定仅在工单来源展示,自动发货与人工客服彻底隐藏分类树并重置过滤条件
- 验证方式:通过后端 784 项全量测试、前后端 tsc 类型检查及前端生产构建打包
|
2026-10-25 15:21:34 +08:00 |
|
zhaoxing
|
027cfc95b1
|
fix:拼单明细界面增加宽度,保证操作能显示全部的按钮
|
2026-10-25 14:46:28 +08:00 |
|
zhaoxing
|
9c620d39cb
|
feat:拼单明细管理加一个撤份额的功能,指定数量
|
2026-10-25 13:44:34 +08:00 |
|
zhaoxing
|
a7a8634a96
|
feat:加一个网站发布公告会弹出来点确定我已知晓的弹窗;mock数据自动匹配接单模板;本地访问模式修改
|
2026-10-25 12:27:32 +08:00 |
|
zhaoxing
|
0ee5554f57
|
add:新增验证视频可选上传功能
|
2026-10-24 16:12:56 +08:00 |
|
yml2213
|
ce8efa6bad
|
style(frontend): 全项目表格统一百分比布局并居中
|
2026-10-24 14:49:23 +08:00 |
|
zhaoxing
|
f9aeece7ab
|
add:新增同一个工单同一人可以多次拼单:拼单明细ui优化
|
2026-10-23 17:45:05 +08:00 |
|
zhaoxing
|
2befb57ef8
|
add:新增同一个工单同一人可以多次拼单:拼单后台撤单,不影响母单状态
|
2026-10-23 15:20:14 +08:00 |
|
zhaoxing
|
bfd2325ac5
|
add:新增同一个工单同一人可以多次拼单
|
2026-10-23 14:26:41 +08:00 |
|
zhaoxing
|
72a758fd7c
|
fix:修复问题接单平台使用游戏ID查询不到数据
|
2026-10-22 15:32:26 +08:00 |
|
zhaoxing
|
35259bd643
|
接单平台:新增店铺筛选条件,过滤快手店铺
|
2026-10-22 15:01:03 +08:00 |
|
zhaoxing
|
067d54fdd8
|
接单平台:新增店铺筛选条件
|
2026-10-22 14:45:40 +08:00 |
|
yml2213
|
10464fea89
|
refactor(product-match): 抽离接单模板匹配引擎(来源适配器/引擎/价格收口 + 后台按订单项试匹配)
新增 services/product-match:来源适配器(kuaishou-91 合成 91+快手 / pdd / douyin-mashida)+ 平台无关匹配上下文 + 条件打分引擎(并列最高=ambiguous 不猜、逐维诊断)+ 价格数量拼单唯一实现。
- 商店键命名空间化(kuaishou:/pdd:/douyin:),店铺为可选作用域:留空即可按订单信息匹配
- 抖音匹配文本只取内部 SKU,引流标题只进 promoTitle,itemTitle 恒空(修复 0.85 元误命中碎梦浮光珍宝礼盒、拼单未开)
- work-product-match-mappers 改为门面(签名不变),work-order-pricing 改为转发
- 新增后台「按订单项试匹配」接口与面板:走发单同一套链路,返回模板/数量/单价/总额/拼单
- 生产样本回放:91/PDD 6000 条决策 0 差异;抖音 5 条全为修正
设计见 docs/接单模板匹配引擎重构设计.md
|
2026-10-14 15:58:21 +08:00 |
|
yml2213
|
cb064d7cd5
|
fix(worker-platform): 工单号前缀改 WK 并在检索侧容错 O/0,彻底解决「按工单号搜不到」
## 线上定位到的真正根因
客服搜 `WO26101213031939` 搜不到,但用同单的平台号 `2628501763808879` 搜得到。
到生产库核对后确认:
- 库里真实值 `work_order_no = WO26101213031939`(hex 574f… = 字母 O),状态 pending_acceptance;
- 用字母 O 的 SQL 分支 → 1 行;用数字 0(`W026101213031939`)→ 0 行;
- 全库 127,906 单**全部**以 `WO` 开头、`W0` 开头 0 单、字母 `o` 只出现在第 2 位。
即:前缀里的字母 O 被输成数字 0(`WO` / `W0` 在界面字体里几乎无法区分),
落进通配符分支后必然为空 —— 与前面几轮的「筛选把单藏起来」是两个独立成因,
这也解释了为什么改筛选逻辑一直没解决。
## 修法
1. 生成端换前缀:generateWorkOrderNo 产出 `WK…`(K 与 0 不会看混),从源头消掉歧义;
2. 检索端同时兼容三种写法(历史 WO 号无需迁移):
- isWorkOrderNoLookupKeyword 放宽为 `^W[oOkK0]…`;
- 新增 buildWorkOrderNoKeywordVariants:W0→[W0, WO, WK]、WO→[WO, W0]、WK→[WK],
SQL 分支对每个候选下发「等值 + 前缀」条件(仍是索引条件,不会退化成全表扫);
- 前端 isExplicitOrderNoSearch 同步(否则面板不清理筛选、实时补丁护栏也不生效);
3. 顺手加一层归一化:NFKC(全角→半角)+ 去零宽字符,前后端同一口径
(normalizeLookupKeyword / normalizeSearchText),覆盖「粘贴带不可见字符」这类同族问题;
4. 寄卖匹配弹窗的占位提示更新为 WK... / WO...。
## 验证
- 后端 npm run check 全绿:692 tests(689 pass / 3 skip),新增
work-order-keyword-lookup.test.ts 直接断言 SQL 参数与「不得出现前置通配符」;
- 前端 npm run check 全绿:139 tests;
- 既有用例 worker-platform-repo.test.ts 的期望值同步为新形态(两条候选条件)。
|
2026-10-12 16:51:08 +08:00 |
|
yml2213
|
fe4d02d136
|
fix(worker-platform): 按工单号搜不到彻底收口 —— 显式单号检索不再被任何排他筛选吞掉
## 修的是什么
线上反复复发的「后台接单平台按工单号搜不到、某些状态尤其明显」,根因不是一处,
而是同一类问题在 5 个地方各留了一半(历次修复都只补了一处,所以总复发):
1. 状态筛选走运营态派生:拼单母单一旦有人参与,open → in_progress /
pending_acceptance,于是「单号 + 待接单」永远为空(没人参与时反而搜得到),
这正是「有人接单后就搜不到」;非拼单单子被接单后同理。
2. 「单号 + 接单人员 / 分类 / 打手等级 / 创建时间」照样过滤掉目标单
(接单人员是 INNER JOIN 可见集合,不在集合里整行消失)。
d6523635 只在面板查询按钮里清了 状态/赠送阶段/验收模式,这三个没清。
3. 待办通知跳转(buildNotificationActionPath 带 ?workOrderId=)设下的
「定位工单」是 wo.id = X 排他条件,不手点「取消定位」就一直生效,
之后搜任何别的单号都是空 —— 这条路径历次修复从未涉及。
4. AdminLayout 把服务端 operation='remove' 直接判成 mismatch,
绕过了「显式单号不删行」的护栏。
5. 打手端「我的订单」默认页签固定「代练中」,搜索不联动页签、
实时补丁又拿状态当可证伪条件删行 → 打手端同类问题(此前只修了关键词匹配)。
## 修法(收口到单一真源,不再按按钮打补丁)
后端:
- 新增 isExplicitOrderNoLookupKeyword()(工单号 / 平台单号 / SUB·INV·AS·DT);
- 后台列表筛选抽成纯函数 resolveAdminWorkOrderListFilters():显式单号检索时
不下推 状态/VIP待补图/验收模式/赠送阶段/接单人员/分类/打手等级/创建时间/定位工单;
- 打手端 resolveWorkerMyOrderStatusFilter():只放掉状态与 VIP 待补图,
**严格保留 workerSharingId 可见范围**(否则打手能搜到别人的单)。
前端:
- admin-realtime-work-orders.ts:显式单号检索直接判 unknown(含服务端 remove),
remove 的短路移交给判定函数;
- WorkOrdersPanel:单号检索时清空全部排他筛选并提示「已按单号精准检索,自动忽略…」,
通知定位工单时也清掉其它筛选,避免残留;
- WorkerOrdersPage:单号检索自动切「全部订单」;WorkerLayout 走新的
resolveWorkerMyOrderRealtimeVerdict(),与后台同策。
刻意不改(避免越权/召回不可用单):抢单大厅(候选必须是 open)、
寄卖手动匹配候选(只做未接单整单)。
## 验证
后端 npm run check 全绿:682 pass / 3 skip(新增 6 项);
前端 npm run check 全绿:138 pass(新增 6 项,含「单号检索 + 实时事件不得删行」,
以及「服务端 remove 不得绕过单号护栏」的回归);format/lint/typecheck/build 通过。
无数据库迁移。
|
2026-10-12 15:48:30 +08:00 |
|
yml2213
|
2d727a6797
|
fix(worker-platform): 修复对已冻结打手调级时误报冻结原因必填的问题
- 做了什么:
1. 后端 reviewAdminWorkerUser 中优化 freezeReason 校验条件:区分是否为新变为 rejected 状态,若账号原本已处于冻结态且本次仅调整等级未变动状态,直接沿用已有冻结原因,不再强制要求传 freezeReason;
2. 前端 submitLevel 在提交调级时补充传递打手既有的 freezeReason;
3. 后端新增对应测试用例确保后续回归。
- 为什么:
当打手处于冻结状态(rejected)时,管理员对其执行调级操作因未携带 freezeReason 触发了冻结原因校验错误,导致调级失败。
- 验证方式:
运行 npm run check(671 项测试全绿,类型与构建检查通过)。
|
2026-10-10 13:51:58 +08:00 |
|
yml2213
|
85fc2eaa7c
|
feat(worker-platform): 支持后台人工调级锁定等级与解除自动升级限制
- 做了什么:
1. 新增数据库迁移 098_worker_level_lock.sql,在 worker_users 表增加 is_level_locked、level_locked_at、level_locked_reason、level_locked_by 字段;
2. 后端自动升级函数 maybeUpgradeWorkerLevelWithClient 和判定函数 shouldApplyAutomaticWorkerLevel 增加 is_level_locked 守卫,被锁定的打手跳过自动升级;
3. 后台打手审核调级服务 reviewAdminWorkerUser 支持等级锁定参数与变更记录,人工调级时自动写入 worker_level_logs 流水,并提供 updateAdminWorkerLevelLock 专用接口;
4. 前端打手列表等级列展示「已锁定」状态及 Tooltip 原因,调级弹窗支持「锁定自动升级」开关与原因输入,操作列提供「解除限制」快捷操作;
5. 打手详情抽屉补充展示等级锁定说明。
- 为什么:
解决打手被人工调整等级(如 VIP5 调至 VIP4)后,因历史累计完成单数满足门槛导致后续结算再次自动升级回高等级的问题,并支持后续随时解除限制恢复自动升级。
- 验证方式:
1. 后端新增 shouldApplyAutomaticWorkerLevel 与 mapWorkerUser 单元测试,运行 npm run check(670 测试全过,类型与 SQL guard 验证通过);
2. 前端新增 worker-level-lock.test.ts 单元测试,运行 npm run check(130 测试全过,typecheck 与 build 验证通过)。
|
2026-10-10 13:44:57 +08:00 |
|
yml2213
|
893388b37f
|
feat(consignment): 寄售仓库在库列表增加通过审核入库时间并在手动匹配中补全时间展示
- 寄售仓库 (ConsignmentInventoryPanel):表格中增加「通过审核入库时间」列并格式化展示,详情弹窗规范化展示入库时间、出库时间与提报时间
- 手动匹配弹窗 (ConsignmentManualMatchModal):候选订单列表展示工单创建时间,顶部横幅与已选概要展示现货入库时间及订单创建时间;从订单匹配现货时展示现货入库时间
- 内部匹配接口与工单拦截:后端 listInventoryMatchableOrders 返回工单创建时间及平台单号;发布拦截弹窗中增加展示现货入库时间
- 验证方式:运行前后端单元测试全部通过,前端 build 校验通过
|
2026-10-08 15:41:23 +08:00 |
|
yml2213
|
5466783017
|
feat(worker-platform): 接单模板列表支持一键导出到本地 CSV
后台接单平台「接单模板列表」右上角新增「导出」按钮:
- 按当前筛选(搜索关键词 + 一级/二级分类)导出全部模板,服务端分页的
情况按每页 100 条循环拉全量(页数上限兜底),不会只导出当前页;
- 导出 UTF-8 带 BOM 的 CSV,Excel/WPS 双击直接打开,文件名带时间戳
(接单模板_YYYYMMDD_HHmm.csv);逗号/引号/换行按 CSV 规范转义;
- 22 列:模板名称/标识/分类/系统/平台/商品SKU/接单金额/按件价/拼单配置/
验收模式/自动建单/状态/超时策略/资料字段/已绑定商品与绑定明细/时间等;
- 空结果、超出上限、浏览器不支持下载分别给出明确提示。
导出逻辑集中在 apps/frontend/src/utils/product-rules-export.ts(纯函数,
无 @/ 别名与运行时相对导入,便于 node --experimental-strip-types 单测),
新增 tests/product-rules-export.test.ts 覆盖分类回退、金额与拼单转换、
绑定明细、CSV 转义、文件名、空列表与非浏览器环境。
|
2026-10-08 13:50:19 +08:00 |
|
 yml2213andCursor
|
dbdafd3dc4
|
fix(consignment): 撤销寄售履约按选择回库,不再因加好友强制作废扣押金
买家退款时应能把现货退回仓库继续匹配;卖家押金只在客服显式选择扣除时才没收。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-05 14:28:38 +08:00 |
|
yml2213
|
90de6b9419
|
perf(worker): 单号检索收敛为可走索引的等值/前缀,并支持关联单号反查
问题:后台「按单号检索」在平台单号/工单号分支里 OR 了一支
`work_order_no ILIKE '%'||$n||'%'`。前置通配符非 sargable,任何 B-Tree 都用不上,
整条查询退化成 work_orders 的 Seq Scan。
生产实测(10.3 万行 / 572MB,pg_stat_statements 46 小时窗口):
- 列表查询 + 统计查询用同一份 filters 并行执行,一次检索打两遍全表;
两者合计占全库 66% 的磁盘读(1.1TB/46h),单次读 26,442 个块(约 211MB)、398ms、返回 1 行。
- 收敛后同库同参数:等值 0.19ms,前缀 30ms(约 2000 倍)。
- 真实统计查询端到端 760ms → 61.6ms。
改动:
1. 平台单号/工单号分支收敛为「等值 + 前缀」,与 order-repo / task-repo 既有写法一致;
工单号含随机小写段(10.2 万行里 7.4 万行非全大写),保留 LOWER() 比较。
2. 迁移 090 补 text_pattern_ops 前缀索引:当前库 collation 为 en_US.utf8,
前缀 LIKE 在默认 B-Tree 上会退化成全索引扫(实测 438ms)。
3. 新增关联单号反查分支:SUB/INV/AS/DT 不在 work_orders 上,
经关联表反查工单 id,四条链路均命中唯一索引。
4. 前端 isExplicitOrderNoSearch 同步补齐(否则搜到的单会被状态页签挡掉、
实时补丁还会把行删掉)。
验证:生产 EXPLAIN 逐条比对 + 14 项仓储单测 + 6 项分类器单测。
|
2026-10-03 14:27:32 +08:00 |
|
yml2213
|
56e718a65d
|
fix(admin): 显式单号检索下,其它筛选不得把正在看的工单从实时补丁里删掉
## 修的是什么
实时补丁的判定链里,「状态 / 接单人员 / 日期范围」这些可证伪条件排在关键词护栏之前,
任一不成立就先返回 mismatch(允许删行),于是第 156 行那条「有关键词就不删行」的护栏
在带筛选时根本执行不到。
d6523635 只在 UI 侧补了一半:搜显式单号时清空 状态/赠送阶段/验收模式,
但**没清接单人员、分类、日期范围**,而 workerId 与 createdRange 同样会先返回 mismatch。
所以「单号 + 接单人员」或「单号 + 日期范围」仍会把行删掉。
实测(真实函数):
单号 + 状态筛选 -> mismatch(删行)
单号 + 接单人员筛选 -> mismatch(删行)
单号 + 日期范围 -> mismatch(删行)
## 修法
只对「显式单号检索」提前短路为 unknown(只原地更新,不插不移):
if (isExplicitOrderNoSearch(filters.keyword)) return 'unknown'
刻意**不**推翻既有设计:模糊关键词(产品名/昵称等)仍保留「状态可证伪即移除」的语义,
因此原来锁定该语义的用例继续通过。
顺带把 isExplicitOrderNoSearch 合并到 utils:此前面板与 AdminLayout 各有一份规则,
重复两份正是上次 tab 名单漏改那类问题的温床。
## 边界(重要)
**本次修复不覆盖「无任何其它筛选、只按单号搜索」的场景。**
实测该场景下判定本就是 unknown、行不会被删(状态原地更新、分页与统计一致),
因此线上反馈的「状态变化后搜不到、必须整页刷新」若发生在无筛选条件下,另有他因,尚未定位。
|
2026-10-02 17:51:39 +08:00 |
|
yml2213
|
78c676d2b9
|
feat(worker-risk): 风控后台页面(可调阈值/实时状态/事件留痕/人工封禁解封),并修复解封后仍被 403 的 bug
## 修复的 bug(生产已发生)
风控三级封号把 tracker.banned 置为 true 后,banned 检查发生在鉴权之前,
而它只存在于进程内存。后台把账号改回 active 时数据库变了、内存没变,
于是账号在库里已经正常、请求却永远 403,只能等容器重启才恢复。
修法两道:
- **数据库是唯一事实来源**:banned 改为带 30 秒 TTL 的缓存,到点回查
worker_users.status;已解封(或账号已删)则清除标记并放行。
对被判 banned 的 key 最多每 30 秒查一次,即便对方仍以 65 QPS 刷也只是
每 30 秒一次查询。查询失败时**保守维持封禁**,不因数据库抖动放行刷子。
- **后台改状态时主动释放**:review 只允许设 active/rejected/disabled/pending_review
(没有 frozen),所以走到那里就意味着不再由风控冻结,直接释放内存状态。
顺带修掉一个连带缺陷:解封时只清了 violationCount,没清滑动窗口计数,
账号刚恢复就会被上一轮残留的 windowCount 立刻限流、并在 60 秒内二次封禁。
现在整轮窗口状态一并清零。
## 新增后台页面
接单平台 → 风控(/admin/worker-platform?tab=risk-control),三块:
- 阈值配置:6 个阈值可视化编辑,落 app_config_entries,保存即热生效,无需重启
- 当前实时风控:进程内存状态(已封禁/惩罚中/仅记录),支持人工解封、封禁、仅释放内存状态
- 风控事件留痕:worker_risk_events 分页查询,可按类型/IP 筛选
## 关键取舍
只记**显著事件**(二级惩罚、三级封号、人工处置),不记每一次被拒请求。
被刷时实测 45~65 QPS,按请求写库正是最初要解决的问题。实时计数仍走进程内存。
事件写入为 fire-and-forget 并吞异常,留痕失败绝不影响大厅请求。
## 验证
- 新增 6 个用例覆盖解封立即生效、对账自愈、TTL 不重复查库、对账失败保守维持、阈值可配置
- 迁移 089 已在临时库实测:表结构/4 索引/CHECK 约束/外键均正确,非法 event_type 被拒
- 后端 557 测试 554 通过 0 失败;前后端 typecheck/lint/format/build 全绿
|
2026-10-02 17:05:25 +08:00 |
|