Commit Graph
221 Commits
Author SHA1 Message Date
yml2213 9d5af359fa feat(finance): 完成财务控制、L1 钱包硬化与迁移收敛
- P0/P1:影子总账追加调整、关账/退款/资金/积分幂等、成本版本追溯、对账订单项维度
- 迁移收敛:原 103–114 合并为 103_finance_foundation、104_finance_controls、105_work_order_consignment
- 数据:L1 钱包 BIGINT/CHECK/奖励幂等;重复奖励审计口径修正与人工核对清单
- 报表:销售毛利缺失成本收入提示,旧收支页明确现金流口径
- 文档:同步迁移基线、合并评估、代码复核与上线说明
2026-10-27 16:08:16 +08:00
yml2213 a3e2bdb7c4 feat(finance): 人工成本单事务/幂等 + 配置自动匹配 + 缺成本监控
- 确认履约改为单事务:锁订单项 → 复查快照 → 扣积分/备用金 → 写成本快照;
  快照失败整体回滚,不再出现「钱扣了、成本没记」
- manual_case 的 subject_id 统一为 order_item_id,新增订单项级唯一索引(迁移 111),
  消除 manual_expenses.id / platform_credit_entries.id 跨表撞车
- 人工 SKU 匹配增加 sku_code / sku_name 兜底;保存配置立即回填最近 30 天,
  定时任务按窗口 rematch,确认时再按 SKU 兜底匹配
- 新增 manual_cost_missing 异常队列:从首次人工配置起算,确认履约立即收口
- 补单元测试与真实 PostgreSQL 集成测试(并发、重复、强制快照失败回滚、双资金链路)
- 校准财务文档并新增上线初始化/验收手册(历史人工不补录,只保证配置后的新单)

验证:backend typecheck/lint/format/check:sql/test 843(839 pass / 4 skip);
frontend typecheck/lint/test 172;迁移 111 在 scratch 库全量执行 + 重跑幂等。
2026-10-26 13:04:51 +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 60fe00b28c fix:打手端/我的订单/验收:验收视频和验收图片至少上传一个就好了,其他逻辑按照上传图片走 2026-10-25 16:45:38 +08:00
yml2213 ccc71e0aab Merge branch 'main' into dev 2026-10-25 13:33:05 +08:00
yml2213 2fb7aae13f feat(auth): 登录态改为滑动续期(后台 24h/7d,打手 7d/30d) 2026-10-25 13:28:58 +08:00
yml2213 790de676c6 feat(admin): 收口人工履约入口并修复履约筛选 2026-10-24 17:42:07 +08:00
yml2213 faf56e567e feat(finance): P2 手动退款登记与成本异常闭环
- 迁移 112:order_refunds(订单项级退款,整单拆多条共享 batch_no,source/external_ref 预留平台 API)+ cost_exceptions.resolution_note
- 新服务 order-refund-service:整单/指定商品退款、可退金额校验、撤销、全额退完同步 pay_status
- 销售事实改为按有效退款记录冲减;无记录时仍兼容 pay_status=refunded 的历史全额退款
- 订单详情新增退款登记与退款记录表,商品明细显示收入/已退/可退
- 全额退款自动关闭该订单项成本异常并写处理备注;成本异常处理改为带备注弹窗
- 财务事件 UNION 接入退款记录,文档同步 P2 状态与 API
2026-10-24 17:18:51 +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
zhaoxing bfd2325ac5 add:新增同一个工单同一人可以多次拼单 2026-10-23 14:26:41 +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 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 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
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 3e73289e31 merge: 合并 main 到 feat/cost-center-wip(同步抖音券、设备认证与图标等最新改动) 2026-10-22 12:40:18 +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 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 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 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 f3f2550b19 feat(admin): 彻底优化任务列表与详情界面,集成到账存证凭单与联盟直充面板
- 优化任务列表角色列:支持从 affiliateDash 及 claimIdentity 中自动提取并展示角色名与 UID(含一键复制)
- 列表操作栏支持一键查看到账存证凭单,支持直接复制图片发给买家或下载保存
- 任务详情页全面现代化重构:
  - 新增「兑换成功 · 官方直充到账存证凭据」大卡片,实时生成 640x960 Retina 高清卡片,支持一键写入系统剪贴板(微信/QQ/客服窗口直接 Ctrl+V 发送)、下载 PNG 大图与全屏预览
  - 新增「联盟直充履约 (affiliate_dash)」专属面板,结构化展示上游订单号、直充状态、点数积分、核销状态及供应商回执
  - 优化凭据生成器 (voucher.ts):强制优先读取本地高清商品图,彻底消除上游图片文字水印与圆环破图问题
- 验证方式:npm run build & npm test (133 项单测全量通过)
2026-10-10 21:04:01 +08:00
yml2213 d8ce40e346 feat(douyin-mashida): 彻底重构优化配置面板,支持一键填域名/订阅推送/网关自检并剔除冗余字段
- 剔除历史旧卡券时代废弃的 afterVerifyLink(去使用链接)与 afterVerifyMessage(通知正文)
- 面板新增一键填入当前域名、向开放平台一键订阅推送、停用推送以及网关连通与签名自检功能
- 业务配置重构为「基础接入与商户凭据」、「买家 H5 直充与发货私信」、「高级网关设置」三层清晰结构
- 后端与前端服务新增 /douyin-mashida/subscribe 与 /douyin-mashida/test-gateway 统一接口

验证方式:前端类型检查与打包构建通过,全量 132 项前端单测与 674 项后端单测全部通过
2026-10-10 20:05:46 +08:00
yml2213 748c18bc7d feat(order): 精准区分自动直发与接单平台打手履约,智能门控H5直充按钮
- 后端增加按订单批量关联接单工单查询,精准识别履约类型(自动直发 / 打手履约 / 电子凭证 / 拼多多发货)
- 订单列表与详情页中,仅当订单为自动直发(affiliate_dash / 码速达直充)时展示【H5】一键复制直充链接与兑换状态控制
- 接单平台工单单与纯核销单隐藏直充 H5 按钮与兑换暂停/关闭标签,防止客服向打手单买家误发直充链接
- 交付模式标签升级为「⚡ 自动直发」、「👥 打手履约」、「🎫 电子凭证」、「📦 拼多多发货」

验证方式:前端类型检查与打包构建通过,全量 132 项前端单测与 674 项后端单测全部通过
2026-10-10 19:44:20 +08:00
yml2213 122144a2b7 feat(task): 任务详情与列表页增加H5订单号领取链接及兑换有效性控制
- 后端 AdminTaskDetail 视图补充关联订单的 claimStatus、claimStatusReason 等状态字段
- 任务详情页升级“领取链接”卡片:支持固定 H5 链接展示、状态标签(有效/暂停/关闭),并支持一键复制及【暂停/关闭/恢复启用】弹窗操作
- 任务详情页保留历史 Token 链接作为辅助对比展示
- 任务列表页在平台订单号旁增加一键复制 H5 领取链接的快捷按钮
- 验证方式:前后端类型检查、全量单元测试(后端 674、前端 132)及前后端全量构建均通过
2026-10-10 18:38:49 +08:00
yml2213 412d219cca feat(claim): 支持固定H5订单号领取与订单兑换有效性后台控制
- 数据库新增 099_order_claim_status.sql 迁移,扩展 claim_status、claim_status_reason 等字段
- 后端新增 /claims/h5/:orderNo、UID提交、分销提交接口,保留原有 token 接口双轨兼容
- 增加兑换有效性强拦截:暂停/关闭/退款/取消订单精准阻断并返回友好提示
- 后台新增 POST /admin/orders/:orderId/claim-status 接口与审计日志记录
- 前端管理后台(订单列表、详情页)支持 H5 兑换状态展示、一键复制链接及暂停/关闭/启用弹窗
- 前端领取页面适配 /h5/:orderNo 路由及暂停/关闭等状态的异常展示
- 验证方式:运行前后端类型检查、全量单元测试(后端 674、前端 132)及全量构建编译均通过
2026-10-10 18:05:46 +08:00
yml2213 4fce07a621 refactor(douyin-mashida)!: 纠偏——删掉自建的皮肤通道,改回复用 affiliate_dash
上一轮我把皮肤交付做成了「另建一套执行器 + 独立领取接口 + 只提交账号就结束」,
跟买家实际要走的过程不一致(真正的完成信号是「扫码绑定后的 UID == 买家填的 UID」),
而且核销还触发了老通知逻辑,给买家**又发了一条 /redeem** —— 买家收到两条链接。
本次按用户要求改回**完全复用仓库现成的 affiliate_dash 通道**(= 旧的快手皮肤自动发货)。

**删掉**
- 执行器 `douyin_mashida_skin`(含 registry/types/planner/bootstrap/路由白名单注册)
- `services/claim/claim-skin-service.ts`、`routes/claim-skin.ts`、`/api/v1/claim-skin` 挂载
- 迁移 096 的 `claim_submission_json` 全链路(task-repo / rows / inputs / task-detail /
  admin-read-service 的 claimSubmission),并新增 **097 兜底迁移**把该列 DROP 掉
- 顺带清掉上一轮专为已删接口加的死代码(utils/http.ts 的 buildMessageSuccessPayload 等)

**改回复用**
- `resolveOrderItemClaimLink`:通用解析(只看订单项、不看执行器)→
  `buildConfiguredClaimUrl(claimLinkBase, token)`;多履约单元取 task id 最小并告警;
  **绝不回退** hash 形态的 `buildClaimUrl`
- `cert_link` 与付款后那条**唯一**消息共用同一个解析结果
- **核销后不再给抖音买家发第二条消息**(`shouldNotifyBuyerAfterVerify` 只放行非抖音 provider)
- 买家侧走既有流程:输 UID → 二维码 → 扫码绑定 → 比对 UID → delivered/REDEEMED;
  在 delivered 分支 best-effort 核销平台券(幂等、失败只 warn,不拖慢买家响应)
- 后台回显链接改按 **order.provider** 判断(抖音用 `claimLinkBase`)

**SQL 守卫**:允许「删除历史迁移」,但强制要求「同时新增兜底迁移」配对
(修改历史迁移仍禁止),并把改动来源换成 `git status --porcelain`(否则未跟踪的新迁移看不见)

`npm run check`:tests 671 / pass 668 / fail 0 / skipped 3(含新增的物品图回退用例)
2026-10-09 16:13:39 +08:00
yml2213 b70741daec feat(admin): 后台可配领取链接/发消息模板 + 可见买家账号 + 修正皮肤领取链接
**面板新增三项(抖音码速达接入配置)**
- 领取链接基址 (claimLinkBase):带实时预览「皮肤订单最终链接」,并拦截两类误配 ——
  带 `#`(`#/claim` 是打手领取页,会把买家带进绑定 UID 流程)、缺 http(s) 协议
- 发消息模板 (messageTemplate):提示可用占位符;模板里没有 `{link}` 直接报错提示
- 付款后发领取消息开关 (claimMessageEnabled)
- 顺带把默认出网超时的展示值对齐后端(10s → 20s)

**后台可见买家提交的账号(运营发货依据)**
- `getAdminTaskDetail` 新增 `claimSubmission`,按 `canViewSensitiveTaskData` 门禁下发
  (与 claimToken 明文同一门禁);任务详情新增「买家提交信息」卡片(可一键复制账号)

**修正:皮肤任务的领取链接**
- 详情接口原来用全局 `buildClaimUrl`(默认 hash 形式 `…/#/claim/…`),那是**打手**领取页;
  皮肤任务改用 `claimLinkBase + '/' + token`,运营复制给买家的链接才是买家页
- 顺带把「履约渠道」筛选项加上「皮肤自动发货」、任务详情执行器标签加上它、
  「来源渠道」加上「抖音码速达」(此前筛不出来抖音订单)
2026-10-09 15:06:49 +08:00
yml2213 56a8184576 feat(douyin-mashida): 皮肤自动发货(按内部 SKU 分流 + 领取链接 + 买家领取接口)
抖音码速达的皮肤类商品改为「自动发货 + 领取链接」:买家不用输订单号,点链接直接领。

**分流(按内部 SKU)**
- 平台闸门放行 `provider='douyin_mashida' && platform='doudian'`,走**独立分支**
  (原有 91/快手路径一行未动,避免外溢)
- 判据:内部 SKU(`sku_order_list[].code`,即 order_items.sku_code)命中权威表
  `AFFILIATE_DASH_SKU_MAPPING` → 新执行器 `douyin_mashida_skin`;未命中 → `manual_dispatch`
- 皮肤判定与商品图同源(都用那张权威表),保证「能路由 ⇒ 有图」
- 履约路由新增 `internal_sku` 匹配维度(`rules[].internalSku`,NFKC+去空白+小写,exact/contains);
  旧规则缺 `matchField` 时默认 `product_name`,**归一化/优先级/回退顺序完全不变**

**执行器与领取 token**
- 新增 `douyin-mashida-skin-executor`:建 claim token、置 `link_generated/pending_claim`,
  `resolveDeliveryLink` 返回本站路径式领取链接;注册进 registry、planner 分支、
  bootstrap 种子 profile(`抖音皮肤自动发货`);进 `ROUTABLE_EXECUTOR_KEYS`
- token 粒度 = 一个履约单元一个(`claim_tokens.task_id` 唯一);一单多项时
  cert_link/买家消息取 task id 最小的那个并告警

**cert_link 与发消息**
- 皮肤订单且该订单项已有 token 且配了 `claimLinkBase` → `cert_link = claimLinkBase/token`;
  其它情况一律用 `certLink`(老行为不变)
- 领取链接**只认** `claimLinkBase`,绝不回退 `buildClaimUrl`/`orders.claimBaseUrl`
  (那是 hash 形式的打手领取页,语义不同)
- 付款建单+发券成功后按 `messageTemplate`(`{link}/{sku}/{orderNo}/{productTitle}`)
  经 `order.message` 发给买家;best-effort,失败只记 warn

**买家领取接口**
- `GET/POST /api/v1/claim-skin/:token`(限流、公开);详情含内部SKU/引流标题/商品图/
  数量/金额/支付时间/动态表单字段;token 失效给明确 errorCode(404/410/409),不打 500
- 提交账号:先核销平台券再落记录(避免「记账了但券没核销」的资损),已提交幂等

**隐私**
- 买家游戏账号落 `fulfillment_tasks.claim_submission_json`(迁移 096),
  **不进** `work_orders.material_json`(那是发给打手的素材);详情接口不返回券码明文/手机号/地址/open_id
2026-10-09 15:06:43 +08:00
yml2213 7834ee7bef feat(douyin-mashida): 商品展示统一改为内部 SKU(引流标题降级)
平台 sku_order_list[].code 是商家维护的**内部 SKU**(如「幸运币2个」),
product_name 只是店铺用来**引流**的长标题(如「【测试专用】和平精英皮肤小店入口…」)。
商家按内部 SKU 认货(后续履约匹配也用它),原来的展示把引流标题当商品名,
列表/详情/兑换页三处都会让人认错货。

改为以内部 SKU 为主、引流标题降级为副信息:
- 后台订单列表「商品 / 任务」:itemTitle = 内部 SKU,skuNick = 引流标题
- 后台订单详情「商品明细」:商品 = 内部 SKU;SKU/规格 不再重复展示同一串
- 兑换中心 /redeem:商品 = 内部 SKU(粗体)+ 引流标题(灰色小字,新增 productTitle 字段)

实现只在 `source === 'douyin_mashida'` 时生效(resolveOrderItemTitle /
resolveOrderItemSkuNick 加 douyin 分支),其它平台展示逻辑不变;
用真实订单形态补了单测。
2026-10-09 13:31:45 +08:00
yml2213 72606796b3 feat(douyin-mashida): 抖音码速达最小接入后端(消息建单/券码同步/兑换核销/退款作废)
- 签名:出网 md5(secret+Σ(名+值)+secret) 与推送 md5(secret+data+pub_time+topic+secret)
  两套独立实现,含文档 golden 向量单测(与 91 大写 / affiliate_dash HMAC 都不通用)
- 进单:trade_TradePaid 推送 → 验签 → webhook_events 幂等 → order.orderDetail
  → upsertOrderFromSource(provider=douyin_mashida / platform=doudian)
- 精度:19 位订单号超出 JS 安全整数,JSON.parse 会把 p_id 抹成 ...000;
  故解析后从原始 JSON 文本用正则抓回精确数字(单测同时证明"不修会错")
- 券码:迁移 094 redeem_certificates((provider,order_id) 唯一做发券幂等)
  + DYC 券码生成 + coupons.syncV2 同步(子单号优先、父单兜底)
- 兑换:POST /api/v1/redeem/lookup|confirm,按 orderNo+IP 限流;
  核销成功后 order.message 通知买家(best-effort,失败只记错误日志)
- 退款/取消:作废未核销券;券已核销时打 WARN 资损告警(已消费不可回滚)
- 后台:GET/POST /api/v1/admin/platform-config/douyin-mashida,
  secret 出参置空 + 掩码,掩码回写不覆盖原值
- 消息路由挂在全局 body parser 之前(app.ts),验签必须用 body 原始字符串
2026-10-09 12:00:50 +08:00
yml2213 c115f5e944 fix(claim): 修复后台手动关闭任务后领取链接未失效的缺陷
1. 鉴权层激活 CLAIM_TERMINAL_STATUSES:在 getClaimContext 中增加 task 状态校验,对 closed 与 expired 终态任务实施 410 拦截并自愈更新关联 Token;
2. 仓储层新增 closeClaimTokensByTaskId():支持按 taskId 批量更新所有非 closed 状态的 Token 为 closed,彻底杜绝多 Token 或重发链接导致的历史活跃残留;
3. 后台关闭任务流程闭环:closeAdminTask 显式触发 closeClaimTokensByTaskId,确保任务关闭时关联领取链接立即失效;
4. 补充 CLAIM_TERMINAL_STATUSES 单元测试与完整排查分析方案文档。
2026-09-20 14:06:48 +08:00
yml2213 e828e677a5 fix(consignment): 打通寄卖权限鉴权、指派占库竞态与撤销守卫
- 后台权限白名单补齐 consignment.view/manage/review/fulfill,
  避免在「角色权限」页保存任意角色时静默清除寄卖权限
- 寄卖后台 19 个接口由 requireAdminRoles 改为 requireAdminPermission,
  使 view/manage/review/fulfill 四个权限真正生效
- 指派打手履约改为先原子占库(WHERE status = 'in_stock'),
  失败自动回滚库存,消除并发下同一件现货被两张工单同时认领
- 撤销寄售履约拒绝押金履约模式(worker_deposit),
  避免打手押金不释放造成资金挂账;前端同步隐藏该入口
- 撤销回库不再强制覆盖 allow_matching,保留运营手动关闭的匹配开关
- 新增 4 个回归测试:权限白名单与迁移一致性、占库/回滚条件、撤销守卫
2026-09-16 11:38:08 +08:00
yml2213andCursor 40c51e1d8e fix(admin): 订单列表默认近7天并按支付时间筛选
避免无日期过滤时展示全库,关键词搜索不受日期限制;SSE 插入裁剪并尊重筛选,新单入库优先使用平台支付时间。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 13:41:29 +08:00
yml2213andCursor b7d246e5b9 fix(admin): 任务列表商品名与执行器标签改为中文展示
建单时不再把英文 sku 写入商品名,列表按映射反查中文名,并将 Affiliate Dash 等标签本地化。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 13:03:47 +08:00
yml2213andCursor 8e996e01fb fix(pdd): 停止旧单刷匹配日志,并修复订单列表商品显示为 0
同步时已有工单/匹配结果未变不再写日志;列表按 Number(order_id) 挂 items,并补齐 PDD goods_name 回退与嵌套商品解析。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 12:05:02 +08:00
yml2213andCursor e20505bc8e style: 修复 pre-push Prettier 格式检查失败
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 10:47:38 +08:00
yml2213andCursor 4a3b4ec14d refactor(fulfillment): 固化 91 中文名→英文 SKU 权威映射表
91 继续用中文编码;解析优先查内置常量表,配置仅作临时覆盖,Admin 改为展示权威表。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 20:33:42 +08:00
yml2213andCursor 745eeaee35 fix(admin): 恢复任务重试/转人工/人工完结等后台写接口
删除咸鱼链路时误删了 retry、mark-manual-review、complete-manual-dispatch、regenerate-claim-link;现按 affiliate_dash + manual_dispatch 语义恢复,历史下线通道可人工完结但不可自动重试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 17:32:26 +08:00
yml2213andCursor b3aad0044c refactor(fulfillment): 移除飞飞/乐玩通道,仅保留 affiliate_dash
新单只路由 affiliate_dash(未命中走 manual_dispatch);历史飞飞/乐玩任务保留只读 stub,避免订单重同步失败。同步清理 cloudtentacles 调度、Admin 写路径与相关 env。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 17:29:47 +08:00
yml2213 447d501f7b 修复快手appSecret意外修改问题 2026-09-13 10:42:32 +08:00
yml2213 4544622cb3 优化后台订单列表展示并支持商品标题与SKU规格 2026-09-10 09:39:19 +08:00