 yml2213andClaude Opus 4.5
|
d07d88e25c
|
feat(finance): 积分钱包操作 + 客服「确认履约」闭环
把「配置 → 待办 → 确认履约 → 扣额度 → 写成本快照」整条链路打通,
客服点一下就完成履约,不需要填复杂的东西。
积分钱包(P1.3):
- platform-credit-service.ts:充值 / 调整 / 消耗 / 流水查询。
- 三平台积分互不通用,每客服每平台一个账户;余额只能由流水产生,
消耗不足直接拒绝(409),不允许负余额,与备用金口径一致。
- 换算率按平台:南航、乐玩 1 积分 = 1 分,ROCK 1 积分 = 1 元。
- 充值 / 调整只对 admin/operator/finance 开放;客服只能看自己的钱包。
- 备用金现金不在这里,走现有 fund_* 链路。
确认履约(P1.4):
- manual-fulfillment-service.ts:待办列表 + 确认履约。
- 待办口径:order_items.fulfillment_mode='manual' 且已配 fulfillment_config_id。
人工单**不建 fulfillment_tasks**——那是自动发货通道的体系,人工单历来不走它
(本地 102,955 个人工单的任务行数为 0)。
- 「已履约」判定:该订单项存在有效 manual_case 成本快照。
- 固定成本(消耗积分 > 0)→ 零输入;成本不固定(= 0)→ 只填实际成本金额。
- 确认时:积分平台扣积分钱包、备用金现金走 writeFundExpense,
随后写 actual 成本快照(主体 = 积分流水 id 或备用金支出单 id)。
- 渠道与消耗积分永远提前配好,客服不选;重复履约直接拒绝。
前端:
- 新增「人工履约」页(客服菜单):待确认 / 已履约 / 全部,确认履约弹窗。
- 备用金页新增「平台积分」Tab(客服端与管理端各一份):
余额卡片、积分流水、管理员充值与调整。
E2E 实测:配置 ROCK 100 积分 → 成本 ¥100.00(1 积分 = 1 元);充值 5000 积分
= ¥5000;确认履约后积分 5000 → 4900,成本快照 actual ¥100.00 写入;
重复履约被拒绝。测试数据已清理,登记表保留 357 条扫描结果供运营使用。
校验:后端 765 项 / 0 失败,前端 143 项全通过(含 tsc -b 与 build)。
Co-Authored-By: Claude Opus 4.5 (1M context) <noreply@anthropic.com>
|
2026-10-24 13:21:34 +08:00 |
|
 yml2213andClaude Opus 4.5
|
4bcb4e6b57
|
feat(finance): 人工履约 SKU 配置清单 + 四钱包(南航/乐玩/ROCK积分 + 备用金现金)
客服人工履约有四个钱包,成本与渠道在后台配置好,客服确认履约时零输入。
口径(2026-10-24 确认):
- 四个钱包:南航积分 / 乐玩积分 / ROCK 积分 / 备用金现金。三平台积分互不通用,
每客服每平台一个积分账户;现金复用现有 fund_accounts / fund_entries。
- 积分换算率按平台不同:南航 1 积分 = 1 分,乐玩 1 积分 = 1 分,
ROCK 1 积分 = 1 元(100 分)。真源是履约档案 config_json.rechargeUnitPriceFen。
- 积分是货币,幸运币是商品;消耗积分与成本金额按换算率一一对应。
- 配置主键是**内部 SKU**(快手 spec_json.skuNick / 拼多多 spec_json.outSkuSn),
不是商品标题(标题是引流)。同名 SKU 算同一商品,跨渠道共用一份配置。
- 配置链路没有匹配引擎、没有打分:扫描 → 配置 → 重新匹配。
10 月口径下人工单 17,469 单 / 357 个内部 SKU,Top 50 覆盖 88% 单量。
更早的老单没配置意义,不纳入统计口径。
- 消耗积分填 0 = 成本不固定,客服在确认履约时手填实际成本;
渠道始终提前配好,客服不选。
迁移 110:
- manual_sku_registry:扫描到的内部 SKU 登记表(统计 + 配置状态)。
- manual_fulfillment_configs:内部 SKU → 渠道 + 消耗积分 + 成本模式。
- platform_credit_accounts / platform_credit_entries:三平台积分钱包与流水。
- order_items.fulfillment_config_id:订单项挂配置,重新匹配时回填。
- 4 条 manual_* 履约档案(manual_dispatch 执行器 + config_json 区分平台)。
不复用 kuaishou_ct_assisted / kuaishou_feifei——那是已下线的历史自动发货通道。
性能:spec_json->>'skuNick' 无索引时扫描 2.4s / 回填 5.4s;
新增 idx_order_items_manual_internal_sku 表达式索引后回填降到 1.7s。
后端:manual-fulfillment-config-service.ts(扫描/清单/配置CRUD/重新匹配),
成本中心挂 7 个接口。
前端:成本中心新增「人工 SKU 配置」Tab(扫描、清单、配置弹窗、重新匹配)。
校验:后端 765 项 / 0 失败(含 check:sql 迁移护栏),前端 143 项全通过;
E2E 实测扫描 357 个 SKU、配置四平台换算正确、重新匹配回填 7,604 个订单项;
本地库迁移 110 执行后数据量与改造前一致。
Co-Authored-By: Claude Opus 4.5 (1M context) <noreply@anthropic.com>
|
2026-10-24 13:12:46 +08:00 |
|
 yml2213andClaude Opus 4.5
|
fb679d76f6
|
refactor(finance): 人工成本收敛为「人工录单 → 扣备用金 → 写快照」
公司人工支出登记单与审批报销状态机整链下线,人工成本只留一条链路。
口径调整(2026-10-23 确认):
- 历史人工支出找不回来,直接放弃:不补录、不做样本校准、不做均价估算,
只保证上线后的新单不丢。
- 人工成本逐单按实际金额,从客服备用金扣款,客服只能用本人账户;
没有登记单、没有审批、没有报销,录入即计入毛利。
后端:
- 新增 services/finance/manual-order-cost-service.ts:扣备用金 + 写 actual
成本快照,同一事务,余额不足直接拒绝不允许负余额。
- 成本快照主体从「人工支出登记单 id」改为「客服备用金支出单 id」
(subject_type='manual_case',subject_id=manual_expenses.id)。
- 删除 services/finance/manual-expense-service.ts(1263 行)与
routes/admin/finance.ts 下 /finance/manual-expenses* 全套接口。
前端:
- 删除 AdminManualExpensePage.tsx(778 行)与 /admin/manual-expenses 菜单页。
- ManualOrderCostModal 去掉「提交审核 / 立即计入成本」开关,录入即生效。
- 新增 services/admin/manual-order-cost.ts。
迁移:
- 106_manual_expense_records.sql → 106_fund_account_no_readable.sql,
只保留备用金账户编号可读化。
- 108_drop_manual_expense_records.sql:删除 manual_expense_records 与
manual_expense_events 两张表。
- 109_isolate_legacy_manual_snapshots.sql:把来源为旧登记链的历史孤儿快照
subject_id 改为负数,与 manual_expenses.id 彻底隔离。
踩坑修复(E2E 实测发现):主体 id 换空间后与历史孤儿快照撞唯一索引
uq_cost_snapshots_active_subject_item,INSERT ... ON CONFLICT DO NOTHING
静默跳过,导致「钱从备用金扣了、成本快照却没写成」。修法是迁移 109 隔离
legacy 主体 + 后端快照写失败必须抛错回滚(409),杜绝账实不符。
文档:现行 5 篇 + README 基线校准为 dev @ 43f402cf + 迁移 103–109,
修正已删除的旧迁移号,删除「人工支出登记 + 审批 + 报销」口径,
已作废 DDL 草案移入 docs/archive/2026-10-23/。
校验:后端 765 项 / 0 失败(含 check:sql 迁移护栏),前端 143 项全通过;
E2E 实测两笔同订单项各自独立主体、余额扣减与快照金额一一对应;
本地库迁移 108/109 执行后数据量与改造前完全一致。
Co-Authored-By: Claude Opus 4.5 (1M context) <noreply@anthropic.com>
|
2026-10-24 11:31:29 +08:00 |
|
yml2213
|
63ae32d18c
|
refactor(finance): 成本模型与履约方式正交,拆分成本中心巨型文件
后端:
- 删除 services/admin/admin-cost-center-service.ts(4,248 行),拆为
services/cost-center/ 下 5 个模块:
cost-center-shared(类型/枚举/归一化/映射/costModelScopeSql)、
cost-center-overview(总览与选项)、
product-catalog(商品与渠道映射)、
template-bootstrap(模板引导、自动发货同步、工单证据回填)、
cost-definition(成本项/版本/异常/预览/快照)
- cost_items.carrier_type / cost_type 改为单一 cost_model;专属模型只对
对应履约方式生效,通用模型对所有履约方式生效
- cost_snapshots / cost_exceptions 删除载体列;按履约方式筛异常改用
IN 半连接(248k 异常下 EXISTS 逐行回表 2.7s -> 170ms)
- sales_daily_facts.carrier_type -> fulfillment_mode
- 人工支出按 cost_model 归类;履约方式只读 order_items.fulfillment_mode
- 移除 syncOpenCostExceptionCarrierTypes:异常表已无载体列可同步
前端:
- AdminCostCenterPage.tsx(2,887 行 -> 18 行转发),拆为
pages/admin/cost-center/ 下 8 个 Panel + shared + CostCenterContext
- CostCarrierType 删除;新增 FulfillmentMode / ProductSource / CostModel
- 销售毛利页 carrierType -> fulfillmentMode
同步补两个索引:idx_order_items_fulfillment_id(异常半连接)、
idx_work_categories_name(商品目录分类 lateral join)。
|
2026-10-23 16:06:25 +08:00 |
|
yml2213
|
5c549a2dc5
|
refactor(db): 12 个财务迁移合并重写为 5 个
原 103–114 十二个迁移(1,087 行)分批落地,字段反复摇摆,且同一语义
(履约载体)在四张表各存一份,口径互相打架。本次整体重写为五个:
- 103_product_catalog:product_catalog 不再存载体,来源改由 canonical_sku
前缀表达(aff: / tpl: / wo: / man:);channel_product_mappings 直接
包含 match_type 与 platform_sku_name_key
- 104_cost_center:cost_items 用 cost_model 取代 cost_type + carrier_type;
cost_snapshots / cost_exceptions 删除载体列;pricing_mode 精简为
per_item / per_order / percent_of_revenue(删除按小时与按天固定)
- 105_sales_daily_facts:carrier_type 改名 fulfillment_mode
- 106_manual_expense_records:合并原 111 与 113
- 107_order_item_fulfillment_mode:履约事实三列
核心口径:order_items.fulfillment_mode 是履约方式唯一真源;成本模型
与履约方式正交;核销码不参与履约判定。
本地库已按新 schema 原地改造(scripts/rewrite-local-db-2026-10-23.sql),
316,585 项四项计数与总纲一致,NULL = 0。
|
2026-10-23 16:06:11 +08:00 |
|
yml2213
|
5d1ba11523
|
feat(finance): 统一履约事实并改造人工账单分类
|
2026-10-23 13:35:48 +08:00 |
|
yml2213
|
fac34c8420
|
feat(fund): 备用金账户编号改为带用户名的可读编号
|
2026-10-23 11:57:39 +08:00 |
|
yml2213
|
a7f60414a4
|
fix(finance): 客服只能使用自己的备用金账户
|
2026-10-23 11:44:04 +08:00 |
|
yml2213
|
2aeb789e20
|
feat(finance): 人工支出改为从客服备用金扣款
|
2026-10-23 11:31:47 +08:00 |
|
yml2213
|
cd9bb1419c
|
fix(admin): 人工录单订单项只显示真实内部 SKU
|
2026-10-22 20:08:43 +08:00 |
|
yml2213
|
c38cd8ca2d
|
feat(admin): 订单列表只展示平台判断 SKU
|
2026-10-22 19:55:13 +08:00 |
|
yml2213
|
74b62f3494
|
feat(finance): 订单页人工录单按单实际金额计入成本
|
2026-10-22 19:48:56 +08:00 |
|
yml2213
|
7c8832078f
|
feat(finance): 接单模板发单金额落规则级成本版本
此前接单平台成本版本只有 sys_work_order_reward 的全局 0 元占位,662 个模板的发单金额从未进入 cost_versions。\n\n现在为 662 个模板各生成一条规则级版本:634 条固定发单金额 + 28 条按件单价;全局 0 元版本仅作“按工单实际结算”占位。成本版本页新增“用户实付均价”和“平均实发/项”,支持按模板名称/规则键搜索,按商品筛选也能命中规则版本。\n\n历史工单快照关联到对应模板版本;模板保存时自动同步单条成本版本;删除模板会先把历史版本脱钩停用,保留快照可追溯。\n\n新增迁移 112 覆盖索引,用户实付聚合从约 1.1s 降到约 150ms。
|
2026-10-22 19:29:53 +08:00 |
|
yml2213
|
72e1141c8a
|
feat(finance): 补齐自动发货与接单平台成本和对账
自动发货:价格导入支持 --effective-from,把首次基线版本回填到历史起点;41,676 个订单项全部归一并生成采购成本快照,缺失 0。\n\n接单平台:新增按工单 product_rule_id 回填商品的接口与按钮,长尾项按 provider+shop_id+sku_code+normalized_sku_name 补建 wo: 商品和 sku_code_name 渠道映射;118,053 个订单项全部归一。\n\n成本:已验收工单按 reward_amount 写 actual;未验收但已确定报酬的工单写 estimated,验收后升级。全量 95,870 actual + 21,217 estimated,actual 与 reward 0 差异。\n\n剩余 966 条取消/零报酬工单保留在成本异常队列,不自动记 0;人工块未改动。\n\n实测自动发货与接单平台未归一收入均为 0;整体未归一 79.67% 降至 57.54%,全部来自人工块。
|
2026-10-22 18:59:53 +08:00 |
|
yml2213
|
54d2eb2f59
|
feat(finance): 自动发货订单项按上游 SKU 直接归一
自动发货只有 affiliate-dash 单一上游渠道,订单项直接按 fulfillment_tasks.context_json.skuCode 归一为 aff:<skuCode>,不写 channel_product_mappings。\n\n新增 /cost-center/affiliate-products/backfill:按 order_item_id 取最新任务 SKU 回填 canonical_product_id,只更新有变化的订单项,并自动重算受影响日期的销售事实;返回 updatedCount/skippedCount/remainingCount。\n\n自动发货 SKU 列表改为实时统计履约任务数与最近履约时间,不读会被价格导入覆盖的 attributes_json。\n\n本地实测 41,676 个订单项全部归一,自动发货未归一收入 5,089,712.26 元降至 0;整体未归一占比 79.67% 降至 60.47%。
|
2026-10-22 18:41:31 +08:00 |
|
yml2213
|
0889235870
|
feat(finance): 完成成本快照运行层、销售事实与人工支出登记
迁移 108-111:快照业务时间与预估转实际、销售事实表、系统成本项、公司人工支出登记。接单平台按工单实际 reward 入账;人工支出支持登记/审批/驳回/报销并写 actual 快照。新增销售毛利页、人工支出页与订单入口。
|
2026-10-22 16:41:03 +08:00 |
|
yml2213
|
15989af87c
|
merge: 同步 main 最新到 dev(游戏ID查询修复)
|
2026-10-22 15:33:30 +08:00 |
|
zhaoxing
|
72a758fd7c
|
fix:修复问题接单平台使用游戏ID查询不到数据
|
2026-10-22 15:32:26 +08:00 |
|
yml2213
|
39cf14ed7a
|
merge: 同步 main 最新到 dev(接单平台店铺筛选)
|
2026-10-22 15:30:38 +08:00 |
|
yml2213
|
78580c6165
|
feat(cost-center): 成本项编码改系统自动生成,补自动发货价格导入脚本
- 新建成本项目不再手填编码:后端按成本类型生成基础编码(auto_purchase /
work_order_reward / manual_service / platform_fee / payment_fee /
after_sales_loss / shipping_other / other_cost),重复时追加 _2、_3;
接口显式传 code 时仍优先使用,兼容脚本导入
- 前端移除编码输入框,改为说明提示,创建成功提示展示生成的编码
- 新增 scripts/sync-affiliate-dash-prices.ts + scripts/data/affiliate-dash-prices.json:
按上游 38 条自动发货价格补建 aff:<sku> 商品,并按 cost_amount(分)生成
scope=product 的按件成本版本;价格变化时停用旧版本再插新版本
- 自动发货商品同步与价格导入的 attributes_json 改为合并,避免互相覆盖
|
2026-10-22 15:07:29 +08:00 |
|
zhaoxing
|
35259bd643
|
接单平台:新增店铺筛选条件,过滤快手店铺
|
2026-10-22 15:01:03 +08:00 |
|
zhaoxing
|
067d54fdd8
|
接单平台:新增店铺筛选条件
|
2026-10-22 14:45:40 +08:00 |
|
yml2213
|
0f7d9d4fad
|
feat(cost-center): 记住载体/Tab 选择,补配置引导并优化表格列宽
- 新增 usePersistedState:载体工作区与 Tab 存 localStorage(admin-cost-center:carrier / :tab),
刷新后保持;存储值非法或 Tab 不适用于该载体时自动回退
- 成本项目增加配置说明与常用成本项模板(采购成本/打手报酬/人工成本/平台费/通道费/售后损失),
成本项行新增「加版本」并按成本类型预选范围;成本项/版本弹窗补字段说明
- 商品与成本中心 8 张表统一 tableLayout=fixed,名称类列定宽 + 省略 + tooltip,
表格最小宽度按列宽之和设置,避免名称列独占剩余宽度
|
2026-10-22 14:36:56 +08:00 |
|
yml2213
|
b520a078b0
|
feat(cost-center): 商品与成本按履约载体分区,补充分页与删除能力
- 新增迁移 107_product_catalog_carrier:product_catalog 增加 carrier_type,
自动发货只认 fulfillment_tasks.executor_key='affiliate_dash' 的履约证据
(28 个上游 SKU),接单模板商品统一归为 work_order(662 个)
- 页面按「全部 / 自动发货 / 接单平台 / 人工客服 / 共用成本」分区;
自动发货只展示自动发货 SKU 列表与采购成本,不展示商品目录/渠道映射
- 新增「同步自动发货商品」接口与按钮,按 aff:<skuCode> 幂等补建
- 列表统一接入公共分页 buildAdminTablePagination,支持 10/20/50/100 每页条数
- 标准商品、自动发货 SKU、渠道映射、成本项目、成本版本支持删除,
带引用保护(映射/版本/快照/订单/接单规则)与生效版本先停用约束
|
2026-10-22 14:05:34 +08:00 |
|
yml2213
|
8f3babdabe
|
chore(db): 成本中心迁移重编号到 main 之后(103–106),check:sql 允许纯重编号
|
2026-10-22 12:42:59 +08:00 |
|
yml2213
|
3e73289e31
|
merge: 合并 main 到 feat/cost-center-wip(同步抖音券、设备认证与图标等最新改动)
|
2026-10-22 12:40:18 +08:00 |
|
yml2213
|
33b220ae10
|
fix(dcauth): order_site 白名单补充生产域名 ks.khhao.com
|
2026-10-22 10:04:05 +08:00 |
|
yml2213
|
d94a648c80
|
style(admin): 格式化后台用户管理页
|
2026-10-22 09:21:06 +08:00 |
|
yml2213
|
7a03abf8a1
|
feat(ui): 新增运营后台站点图标并统一登录页品牌标记
- 新增橙色渐变仪表盘图标(SVG / ICO / apple-touch-icon / 192 / 512)
- 登录页侧栏与移动端品牌标记改用同一 BrandMark
- index.html 补齐图标、theme-color 与页面描述,标题改为「运营后台管理中心」
|
2026-10-21 22:10:33 +08:00 |
|
yml2213
|
ef36453694
|
feat(dcauth): 移除机器码,改用纯设备码认证
- DCAuth 协议升级到 v2,签名原文只含设备码;客户端 2.0.0,旧版本返回 426
- 删除客户端机器码采集、后端 machine_code_* 字段与日志、后台机器码展示
- 102 迁移在生产执行前直接改为无机器码结构;SQL 守卫仅放行该文件
- Mock 短信不启用每日限额;修复慢电脑首次启动的协议转发竞态
- 新增 macOS DCAuth.app 打包脚本,注册 dcauth:// 协议,浏览器可直接唤起
|
2026-10-21 20:46:25 +08:00 |
|
yml2213
|
cb916d7750
|
feat(dcauth): 新增常驻托盘客户端与版本显示
Windows 改为单实例托盘常驻,协议唤起只弹一个确认窗口;补充 macOS 后台守护进程
与客户端版本显示。
|
2026-10-21 20:46:25 +08:00 |
|
yml2213
|
040100f290
|
feat(dcauth): 新增后台手机号与设备认证登录
登录链路改为账号密码 + 短信验证码 + DCAuth 设备签名,并新增后台手机号绑定、
登录日志、设备绑定与重置接口。
|
2026-10-21 20:46:24 +08:00 |
|
yml2213
|
111bc76357
|
feat(cost-center): 成本中心与商品映射开发草案 (含文档与订单页调整 WIP)
|
2026-10-20 10:01:52 +08:00 |
|
yml2213
|
7542d547bf
|
feat: 新增客服备用金台账与后台用户中文显示名
- 新增备用金账户、流水、支出、对账与权限
- 后台用户支持中文显示名并同步备用金姓名
- 审计、登录记录、任务及工单操作人优先展示中文名
- 补充备用金与人工支出方案文档
|
2026-10-18 13:55:24 +08:00 |
|
yml2213
|
6850bc64ff
|
feat(work-order): 发布并核销支持抖音券(按来源分流,抖音走 DYC 券核销)
|
2026-10-15 13:22:18 +08:00 |
|
yml2213
|
584b6f52aa
|
fix(work-order): 问题单处置存在活跃拼单份额时禁止取消/退回大厅/重开
生产实锤 WK26101503335487:客服对份额已提交的拼单母单走问题单处置-取消,
母单整单 cancelled 后份额验收/单人撤单全部被母单状态挡死,后台无补救入口。
- 抽出 getActiveWorkOrderShareCountWithClient 统一活跃份额统计口径
- resolveProblemWorkOrder 的 cancel/cancel_deduct/reopen 先过活跃份额防线
(return_to_worker 不拦),返回结构改为 {order, failureReason}
- settleOverdueWorkOrder 复用同一统计函数,消除两份 COUNT 口径
- 服务层映射 409 work_order_problem_resolution_has_active_shares,
文案引导客服先单独验收/单人撤单
|
2026-10-15 10:34:43 +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
|
4b081d88c5
|
feat(douyin-mashida): 抖音按 SKU 三层分类接入(对齐 91/快手)
- sku_code 恒为内部 SKU(不再被英文 sku 覆写);英文 sku / 引流标题分别落 snapshot
- 命中映射 → affiliate_dash;未命中不再兜底 manual_dispatch(无执行载体 = 待人工,不建任务)
- 抖音映射支持「常量表 + 后台 skuMapping 增量」,新增商品不必发版
- 载体唯一守卫:命中自动发货的订单项不再建工单
- 券 cert_link 与命中解耦(/h5 一律按订单号拼);券写入工单 material_json.douyinMashidaVoucher
- 新增/修正 16 例单测;后端全量 717 例 / 0 失败
|
2026-10-14 13:00:49 +08:00 |
|
yml2213
|
e8fbb28cf4
|
feat(claim): 人工履约单领取页只显示「人工处理中,请等待客服」
未命中 AFFILIATE_DASH_SKU_MAPPING 的抖音单显式回落 manual_dispatch(人工),这类单没有
自动发货通道(无 claim token、无绑定二维码),但卡券 cert_link 仍指向 /h5/<订单号> 领取页;
原页面会让买家「输 UID」,提交后没有任何自动发货动作,属于误导买家。
- 后端 kuaishou-cloud-claim-context.ts:新增 MANUAL_FULFILLMENT_MESSAGE 与
resolveManualFulfillmentMessage(executorKey)(manual_dispatch → 等待话术,其它执行器空串);
三个 payload builder 统一输出 manualFulfillment / manualFulfillmentMessage
- 前端 claim-snapshot.ts:输出 isManualFulfillment / manualFulfillmentMessage,
progressText 同步显示等待话术
- 前端 ClaimPage.tsx:在「渠道已下线」之后、「输 UID」之前插入人工单卡片(只读 + 刷新状态),
人工单不会自动轮询(无 expectedUid → 不安排下一次轮询)
- types/claim.ts:补齐两个可选字段;话术只在后端维护一份,前端只做兜底
验证:后端 npm run check(701 单测)与前端 npm run check(格式/lint/类型/143 单测/构建)全绿
|
2026-10-13 13:53:00 +08:00 |
|
yml2213
|
319e082254
|
fix(douyin-mashida): 领取消息只发给有自动发货领取单元的单,人工单不再假发货
根因:notifyBuyerClaimLink 对 `/h5` 形态的 claimLinkBase 走了一条捷径——只拼订单号
(`${base}/${orderNo}`)就发消息,跳过了「该订单项是否有自动发货领取单元」的校验。
领取 token 只由 affiliate_dash 执行器在建单时创建,未命中 AFFILIATE_DASH_SKU_MAPPING
回落 manual_dispatch 的人工单、以及自动准备失败的订单都没有 token,却照样收到
「您的订单已发货,请点击链接领取」(线上实测:非映射商品「套装-牛仔情诗」)。
- claim-link.ts:新增 buildDouyinMashidaBuyerClaimUrl(无自动领取单元一律返回空串 = 不发消息)
与 isDouyinMashidaH5ClaimBase(/h5 形态判定收敛到一处)
- notify-service.ts:两种基址形态统一先 resolveOrderItemClaimLink 拿 taskId 作为「会自动发货」
的证据,缺失则跳过并留痕「该订单项没有自动发货领取单元,跳过领取链接消息」
- claim-link.test.ts:补齐人工单不发消息、/h5 与 token 形态拼接、基址/订单号缺失等用例
验证:npm run check 全绿(prettier + SQL guard + eslint + tsc + 703 单测 + build)
|
2026-10-13 13:48:58 +08:00 |
|
yml2213
|
7e197c9413
|
fix(frontend): H5 领取前缀整段接管,/h5 裸链接不再跳后台登录
根因:公开路径判定原先只认「带参数」形态(isH5ClaimPath 只认 /h5/<orderNo>),
裸前缀 https://<域名>/h5(后台 claimLinkBase / certLink 的基址)判定不命中,
于是落回主站 HashRouter 被后台路由接管成
https://<域名>/h5/#/admin/dashboard 后台登录页。
- utils/claim-path.ts:isClaimPath / isH5ClaimPath 改为命名空间级判定(含裸前缀与多段路径),
参数解析仍严格;新增 resolveH5ClaimOrderNoFromInput(纯订单号 / 整条链接 / 缺协议 /
带后台残留 hash 都能取出订单号,只有前缀时返回空串)
- pages/claim/H5ClaimEntryPage.tsx:新增 /h5 领取入口页,买家输订单号或粘贴完整链接后
跳 /h5/<订单号>,走与分享链接同一套领取流程
- App.tsx:H5ClaimApplication 接管 /h5 整段前缀(/h5 入口页、/h5/:orderNo 领取页、
其它子路径回入口页);useClearStrayHash 抹掉历史残留的 #/admin/dashboard
- tests/claim-path.test.ts:补齐裸前缀、相邻前缀 /h5x、粘贴链接解析等回归用例
验证:npm run check 全绿(prettier + eslint + tsc + 143 单测 + vite build)
|
2026-10-13 13:42:06 +08:00 |
|
yml2213
|
5a73fb74a9
|
feat(douyin-mashida): 新增抖音券核销后台界面(列表/核销/冲正/同步/对账/作废)
抖音订单并非纯自动发货:内部 SKU 命中 AFFILIATE_DASH_SKU_MAPPING 才走自动通道,
未命中显式回落人工,且核销依赖买家自己到 /redeem 输订单号。此前核销侧在后台完全
不可见:自动核销是 void .catch(warn) 只落日志,cancelVerify 出网方法已就绪但没有入口。
照快手电子凭证的骨架做一套抖音版(两张表两套状态机,不复用):
- 券码状态、平台侧状态、同步错误全部可视化,支持只看同步失败
- 核销/冲正/重新同步/平台对账/重发券码/作废,每个写操作都带审计
- 券码列显示「核销实际会用的券码」(platform_cert_no 优先),平台改过名时额外标注
- 冲正先打平台 cancelVerify 再回退本地,避免本地与平台状态漂移
|
2026-10-12 19:45:06 +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
|
966b804bfc
|
feat(worker): 保留超时订单买家资料与快捷复制功能以方便打手核对辨认
- 调整目的:打手在订单超时退回大厅或被抢后,需要核对游戏内对应的好友与账号以分辨是哪一单,避免误认;
- 列表与抽屉展示:在桌面端表格、移动端卡片及详情抽屉中,恢复买家资料与主页截图展示,保留「复制信息」「复制图片」按钮,并补充「已超时,仅供核对辨认」轻量警示;
- 履约隔离:依然严格禁用一切提交验收、修改截图与申请取消等履约操作;
- 验证方式:通过前端 prettier、eslint、tsc、vitest、vite build 与后端全部 676 个测试。
|
2026-10-11 15:39:10 +08:00 |
|
yml2213
|
c5e8b78a33
|
fix(worker): 修复打手订单可见范围查询中参数类型推导不兼容错误
- 显式类型转换:在 worker_visible 的 4 个 UNION 分支中,为 workerSharePlaceholder 显式补充 ::bigint 与 ::text 类型转换;
- 避免类型推导冲突:消除由于 JSON 字符串比较导致的 bigint = text 操作符缺失错误(operator does not exist: text = bigint);
- 验证方式:在 PostgreSQL 容器中验证 PREPARE/EXECUTE 与在后端容器内实测 listWorkOrders 正常返回 20 条记录。
|
2026-10-11 15:25:48 +08:00 |
|
yml2213
|
9ce29964c7
|
style(frontend): 格式化前端代码并修复 eslint 异步操作未标记告警
- 统一 prettier 代码风格;
- 为 AdminTaskDetailPage 与 AdminTasksPage 中未捕获的 Promise 添加 void 标记;
- 验证方式:npm --prefix apps/frontend run check 全流程通过。
|
2026-10-11 15:20:54 +08:00 |
|
yml2213
|
6012add3c9
|
feat(worker): 打手接单界面支持查看超时历史订单并增加安全免责警示
- 数据库与查询层:通过索引 idx_work_order_events_timeout_worker_id 关联打手历史 timeout 事件与取消的拼单份额,打手在退回大厅或被他人抢走后仍能在「已超时」tab 查看历史记录;
- 状态与权限管控:针对超时工单将个人端状态稳定映射为 open,报酬与冻结押金置为 0,彻底禁用上传图片、提交验收、好友资料、申请取消等履约操作;
- 风险防护与免责说明:列表与抽屉详情顶部增加醒目的免责声明与警示横幅(告知订单已退回大厅或被他人接手,严禁在游戏内继续赠送,造成的损失平台概不负责);锁定买家游戏资料与快捷复制;
- 验证方式:通过后端全部 676 个测试、typecheck、check:sql 及前端 check(eslint、vitest/node:test、tsc、vite build)。
|
2026-10-11 15:20:46 +08:00 |
|
yml2213
|
b82f9c4063
|
fix(worker-platform): 补齐拼单份额超时自动处置机制与退回大厅流程
- 根因排查:此前超时扫描仅针对整单 in_progress,而拼单母单为 open 且 deadline_at 为空,导致打手超时的拼单份额无法被定时扫描命中与释放;
- 定时扫描:在 settleOverdueWorkOrders 中引入 listOverdueWorkOrderShares,自动扫描超时未提交资料的拼单份额(joined);
- 超时处置:新增 settleOverdueWorkOrderShare 事务处理,按母单 timeout_policy 释放或扣除押金,份额标记 cancelled,母单保持或恢复 open 状态重回抢单大厅,记录 timeout 事件并推送实时变更;
- 提交防呆:在打手提交拼单验收时检测个人份额是否已超时,超时则立即执行处置并拦截提交;
- 倒计时展示:在 mapWorkOrderForWorker 中根据 myShare.created_at + timeout_minutes 为拼单打手计算并展示个人履约截止时间;
- 质量验证:补齐拼单截止时间计算与处置链路测试,全量 676 个测试均通过,通过 npm run check 校验。
|
2026-10-11 14:53:56 +08:00 |
|
yml2213
|
06d888fb6f
|
fix(products): 恢复官方正版商品图并统一渠道代码格式化
- 从上游系统同步官方原始高清商品图(lucky_coin_x2/x30/x90),剔除此前劣质变形的合成图
- 验证全量 40 款商品资产与 affiliate_dash 官方权威库 100% 逐字节对齐
- 任务详情页接入 formatGameChannelLabel 统一渠道展示逻辑(1-1 -> 安卓-微信)
- 验证方式:npm run build、npm test(674 自动化单测全部通过)
|
2026-10-10 21:34:59 +08:00 |
|