Files
order_site/docs/寄卖库存功能设计与实施方案.md
T
yml2213 632dddc4c3 fix(consignment): 下线 H5 收集链接渠道并封闭寄卖履约状态机
下线定向收集链接(H5 填报)整条线,提报统一走接单平台打手端:
- 删除前端 ConsignmentCollectPage、consignment-public 服务与 /consignment-collect/:token 路由
- 删除后端公开路由 routes/consignment.ts、consignment-public-service 与管理端 /consignment/links 三接口
- 迁移 079 删表 consignment_collect_links、删列 consignment_submissions.link_id,
  source_type 的 collection_link 归并为 worker_portal 并替换 CHECK

修复手工入库/编辑的凭据与截图静默丢失:后端统一按 credentialsJson ?? credentials、
screenshotsJson ?? screenshots 读取(入库/编辑/审核入库三个入口)。

按"已验收一律禁止撤销"封闭状态机:
- 撤销寄售履约加状态白名单(in_progress|pending_acceptance|problem)+ 事务内 FOR UPDATE
  锁单 + UPDATE 带 status 条件(0 行 409)+ 原因必填 + 清空指派/时限/验收草稿痕迹
- 库存改状态一律带条件:撤销要求 bound_work_order_id 命中本工单;作废/回库要求未被
  进行中工单占用(被挡时提示具体工单号);079 加部分唯一索引并清理历史重复绑定
- 工单终止统一解绑回库:打手撤单/取消指派/退回大厅/撤单/打手退单申请/超时处置接入
  releaseConsignmentInventoryBindingForWorkOrderWithClient(售后不改工单状态,无需接入)
- 回库路径保留运营的 allow_matching 开关设置(不再强制开启),前端文案同步更正

顺带修掉资金与归属的同源缺陷:
- 押金归属与重冻金额改取不可变的冻结核销行,审核改派不再"退给错人/向错人扣款"
- 新增 assigned_worker_id 拆开"卖家"与"被指派履约人",占库不再覆盖卖家
- PUT /inventories/:id 禁止直接改 status;发布接口补 requireActiveWorker
- 押金冻结/释放后补推钱包实时事件;迁移 079 给发布冻结加台账幂等唯一索引

验证:后端 401 测试/398 通过/3 skip(新增 5 例回归),前端 16 通过;
两侧 typecheck、lint:check、format:check 与 check:sql、build 全绿。
迁移 079 未经真实数据库执行(本环境无 Postgres),上库前请先 dry-run。
2026-09-16 20:05:49 +08:00

20 KiB
Raw Blame History

和平精英寄售仓库 · 系统设计与实施方案

文档定位:功能技术与产品设计方案(推荐实现标准)
核心游戏:和平精英(地铁逃生模式 / 账号与物资寄售)
更新时间:2026-09-13


一、 业务定位与设计原则

本模块针对 《和平精英》(重点针对地铁逃生模式的苏尔南手枪、极品附魔武器与排位账号)建设专属的 「寄售仓库」,取代原有的线下手工 Excel 台账,并深度融入订单与接单履约链路:

核心设计原则:

  1. 去繁就简、数据结构化:吸取线下台账对“收购成本、收购人、卖家账号/付款凭证、排号/出库店铺”的核心关注点,将杂乱的手工记录转化为规范清晰的系统实体。
  2. 高度自动化,告别手工录入:
    • 履约出库时,系统自动提取并反向回填订单号、快手/拼多多店铺名、出库时间,无需人工再去登记“安排到哪张单”;
    • 客服创建/审核时,系统自动绑定当前登录人员为收购人,自动记录操作时间。
  3. 闭环降本:在工单发布到打手大厅前,系统通过规则引擎智能比对内部在库物品,支持一键直接履约结单,直接省去外部打手赏金(¥15~¥80/单)。
  4. 风控自主可控:每一件入库物品提供独立的 【允许匹配开关】,随手一关即可排除在自动匹配推荐之外,便于自用、高价单卖或线下保留。
  5. 逆向容错(支持撤单与回库重选):全链路支持买家退款、客服选错或账号异常时的一键撤单解绑,库存安全退回复库,工单可随时重新匹配或转推大厅。

二、 核心数据模型设计

将原本 Excel 的离散字段归纳为清晰的三层架构:基础规格属性、收货与卖家资料、流转履约与匹配控制。

数据表:consignment_inventories(寄售仓库主表)

分类 字段名 类型 默认值 业务含义与说明
主键标识 id BIGSERIAL 自增 内部唯一自增 ID
inventory_no TEXT 唯一 系统自动生成的业务编号(如 INV26091312345)
规格属性 game_name TEXT 和平精英 游戏名称
(多维匹配) category_id BIGINT NULL 关联的大类(如 苏尔南手枪)
item_name TEXT 必填 规范物品标题(如 安卓微信区 暗潮 1钻)
system TEXT "" 操作系统:苹果 / 安卓(硬约束)
server_zone TEXT "" 游戏大区:微信区 / QQ区(硬约束)
series TEXT "" 附魔系列:暗潮 / 怒嚎 / 血宴 等(硬约束)
diamond_level INTEGER 1 钻级:1 ~ 6 钻
brilliance_count INTEGER 0 璀璨数:0(无)、1、2 等
收货采购信息 cost_price_fen INTEGER 0 收货成本价(单位分,如 10500 代表 105 元)
(财务与人效) buyer_name TEXT "" 收购人(如 王斌、周杰雄、周顺,默认取当前登录客服)
inbound_batch TEXT "" 收货批次/班次代码(如 8.30-1、8.30-4,便于交接对账)
inbound_at TIMESTAMPTZ NOW() 正式入库时间
卖家与凭据 seller_contact TEXT "" 卖家微信号 / 联系电话
(留痕防纠纷) seller_game_id TEXT "" 卖家游戏角色名 / UID
seller_payment_info TEXT "" 卖家收款抬头与卡号(如 王大锤商行 331682...)
credentials_json JSONB {} 敏感交付信息(游戏账号、密码、换绑辅助),权限保护
screenshots_json JSONB [] 截图凭证数组(卖家ID主页图、词条属性图、名片图等)
remark TEXT "" 运营其他备注说明
履约与状态 allow_matching BOOLEAN TRUE ★ 允许匹配开关(开:参与匹配;关:暂停匹配)
(出库流转) status TEXT in_stock 资产状态:in_stock(在库待匹配) / consumed(已出库) / archived(已作废)
bound_order_id BIGINT NULL 履约绑定的内部系统订单 ID(出库时系统自动写入)
bound_work_order_id BIGINT NULL 履约绑定的接单工单 ID(出库时系统自动写入)
bound_platform_order_id TEXT "" 外部订单号(如快手/拼多多单号 260830-085784...,出库自动回填)
shop_name TEXT "" 售出店铺名称(如 拼多多向日葵、稚嫩游戏,出库自动回填)
consumed_at TIMESTAMPTZ NULL 出库履约结单时间

三、 三大核心业务场景与操作流

1. 定向收集链接生成与用户填报(自动化收货渠道) —— 已下线

2026-09 起:寄卖提报统一走接单平台打手端提报(/api/v1/worker/consignment/publish), 对外收集链接(H5 填报页、consignment_collect_links、consignment_submissions.link_id) 已整条移除,详见迁移 079_drop_consignment_collect_links.sql。本节保留仅作历史记录。

[客服后台] ──► 点击【新建收集链接】
                ├── 勾选目标:分类=苏尔南手枪 / 系统=安卓 / 区服=微信
                ├── 勾选品质:系列=暗潮 / 钻级=1钻 / 璀璨=0
                ├── 输入协商收货价:如 105 元,输入批次号:如 8.30-1
                └── 点击【生成链接】 ──► 复制专属 H5 链接发给卖家
                            │
[卖家手机] ◄────────────────┘
  - 打开 H5:顶部显示《和平精英 安卓微信区 暗潮 1钻 回收单》(规格锁定只读)
  - 填入:游戏账号、密码、角色ID
  - 上传:角色主页图、暗潮与1钻属性截图
  - 填入:收款卡号/抬头(如 王大锤商行...)、卖家联系电话
  - 点击提交
                            │
[后台审核工作台] ◄──────────┘ (状态:pending_review)
  - 客服打开「寄卖审核」弹窗,核查截图无误
  - 可修正实收价格与字段
  - 点击【审核通过并入库】 ──► 正式存入寄售仓库(in_stock,允许匹配=开)

2. 线下人工快速录入(直接收货登记)

对于客服在线下直接谈好的现货:

  • 在「寄售仓库」面板点击 【快速手工录入】。
  • 录入表单模块化聚合:
    • 商品规格:点选 系统、区服、系列(暗潮/怒嚎/血宴)、钻级(1~6)、璀璨数。
    • 采购成本与批次:输入收购价、当前收购人(默认填入当前操作员)、批次代码(如 8.30-1)。
    • 卖家与凭据:输入卖家联系方式、收款方式、上传品质截图、填入账号密码。
  • 保存后直接进入在库列表,即刻就绪,参与工单匹配。

3. 订单发布前拦截与一键内部履约(降本核心)

[买家下单] ──► 拼多多向日葵 店铺进单,工单状态为 unassigned (待发布大厅)
                   │
                   ▼ 匹配引擎实时计算 (仅扫描 allow_matching = true 的在库库存)
[工单列表行] ──► 醒目标记 Tag:🟢 匹配内部库存(2件)
                   │
                   ▼ 客服点击「发布并核销」
[发布拦截弹窗] ──► 拦截并弹出《检测到可用寄售库存》推荐卡片:
                   ├── 卡片 A:【全部匹配】安卓微信 暗潮 1钻 0璀璨(成本 ¥105,收购人:周杰雄)
                   └── 卡片 B:【部分匹配】安卓微信 暗潮 1钻 1璀璨(成本 ¥128,多出【1璀璨】,高配充低配)
                   │
       ┌───────────┴───────────┐
       ▼                       ▼
【选用内部库存直接履约】   【忽略并继续发布到大厅】
  1. 选中卡片 A 点击确认      维持原有逻辑,推送到大厅由打手抢单
  2. 系统原子事务操作:
     - 工单直接 completed(不发大厅,0 赏金支出!)
     - 自动顺带核销快手电子凭证
     - 库存状态变为 consumed
     - 自动回填:
       bound_platform_order_id = 买家平台订单号
       shop_name = 拼多多向日葵
       consumed_at = 当前时间

四、 智能匹配引擎逻辑(全部匹配 vs 部分匹配)

1. 过滤基准条件(必须满足,否则不匹配)

  • 资产状态必须为 in_stock(在库可用);
  • 【允许匹配开关】必须为 TRUE(若为 FALSE 则完全跳过,绝不打扰);
  • 系统与区服必须完全一致(苹果不能配安卓,微信不能配QQ);
  • 词条系列必须完全一致(暗潮 只能配 暗潮,不能拿 怒嚎 充数)。

2. 钻级与璀璨的匹配算法

  • 全部匹配(Exact Match,得分 100 分):
    • 钻级完全相同(如 订单=1钻,库存=1钻);
    • 璀璨完全相同(如 订单=0璀璨,库存=0璀璨)。
    • 推荐标为绿色,无降级风险。
  • 部分匹配 / 超集匹配(Partial Match,得分 80 分):
    • 核心特征全部满足,但库存规格更高(如 订单=1钻无璀璨,库存=1钻1璀璨,或钻级更高)。
    • 推荐标为黄色,并提示 “⚠️ 该库存品质更高(多出 1 璀璨),属于高配充低配,请确认是否愿意降级使用”,由客服做最终决断。

3. 排序策略

  1. 优先全部匹配(100分) \gt 部分匹配(80分)。
  2. 同等匹配度下,收购成本最低优先(毛利最大化)。
  3. 同等成本下,入库时间最早优先(FIFO 快速清库存)。

五、 异常撤单与库存回退重选机制(退款 / 选错 / 无法发货)

在实际运营中,若发生买家退款、客服选错或账号异常,系统提供完整的逆向撤销与回库重选闭环:

                    【 已寄售履约工单 (completed) 】
                                │
                    点击【撤销寄售履约】
                                │
       ┌────────────────────────┼────────────────────────┐
       ▼                        ▼                        ▼
【场景 1:选错库存重新选】   【场景 2:买家退款取消工单】 【场景 3:物资账号异常作废】
  - 原库存解绑 ──► in_stock   - 原库存解绑 ──► in_stock   - 原库存变更为 ──► archived
  - 工单回退 ────► unassigned - 工单状态 ────► cancelled  - 工单回退 ────► unassigned
  - 客服可重新选用新库存       - 终止发货,库存回库继续卖  - 客服选用其他正常库存发货
    或直接点击发布到大厅

1. 工单视角:【撤销寄售履约 / 重新选择】

在工单列表或工单详情页,对「已通过内部库存履约、且尚未验收」的工单(状态为 in_progress / pending_acceptance / problem)提供 【撤销履约】 操作:

  • 前置约束(2027-02-21 加固):已验收(accepted)与已取消(cancelled)的工单一律禁止撤销 —— 钱已结算、货已交付,撤销会造成同一件现货二次出货并重新冻结已退还的押金;买家退款/纠纷改走售后流程。服务端在事务内 FOR UPDATE 重新读单并校验状态白名单,撤销原因必填,前端按钮同样按状态 + consignment.fulfill 权限渲染。
  • 分支 A:【回退为未分配(重新选库存 或 发大厅)】
    • 原库存处理:状态从 consumed 自动恢复为 in_stock,清除绑定的订单号与售出店铺,重新进入待匹配池(仅当该行仍绑定本工单时才允许改写,否则 409)。
    • 工单处理:状态安全回退为 unassigned(未分配),清空指派人、时限、验收草稿与本次发货记录。
    • 操作结果:客服可以立即再次点击「发布并核销」选择其他匹配库存,或者直接发布到大厅由打手抢单!
  • 分支 B:【买家申请退款(取消工单并退库)】
    • 原库存处理:安全解绑并自动回退为在库 in_stock,避免资产报废损失。
    • 工单处理:状态流转为 cancelled(已取消),不再继续履约。
  • 分支 C:【物资账号异常(作废该库存并重新选)】
    • 原库存处理:该把手枪/账号密码失效或被封,直接变更为 archived(已作废),记录作废原因,不再参与匹配,并释放发布押金。
    • 工单处理:工单回退为 unassigned,供客服挑选另一把正常手枪继续履约。

2. 仓库视角:【退回复库 / 重新上架】

在「寄售仓库」管理列表中,对状态为 consumed(已出库)的物品行,提供 【退回复库】 按钮:

  • 客服可手动将某件出库的物品解绑原订单,直接重置为 in_stock 在库待匹配状态;适合线下沟通中买家临时更换需求、跑单或线下对账异常时的人工修正。
  • 前置约束(2027-02-21 加固):若该物品仍被一张「进行中的工单」占用(bound_work_order_id 指向的工单状态不是 accepted/cancelled),【退回复库】与【下架作废】都会被拒绝,并提示先撤销履约或撤单 —— 避免把别的工单正在交付的现货抢走。
  • 匹配开关语义:回库不再强制打开 allow_matching,而是保留运营的手动设置(该开关是"暂停匹配"的运营闸门,自动回库不应替运营做决定)。编辑接口也不再接受直接改 status,状态只能经由带守卫的动作变更。

2.1 工单终止时的自动解绑(2027-02-21 新增)

工单进入「不再交付」的状态时,会在同一事务内把占用的现货放回在库池(releaseConsignmentInventoryBindingForWorkOrderWithClient),不再依赖运营手工退库:

  • 覆盖路径:打手撤单(cancelled_by_worker)、后台取消指派(unassigned_by_admin)、后台退回大厅(returned_to_hall_by_admin)、后台撤单取消订单(cancelled_by_admin)、打手退单申请审核通过、超时处置(timeout_reopen / timeout_cancel_release / timeout_cancel_deduct)、已取消工单重新启用(兜底清理历史绑定)。
  • 售后处置不在其列:售后(resolveAdminAfterSalesCase)只对已验收工单做资金追缴/退赔,工单状态保持 accepted,货物已交付,无需解绑。若买家退回实物,由运营在寄售仓库执行【退回复库】(已验收工单不再是"进行中",守卫会放行)并填写原因。
  • 发布押金保持冻结:现货回到在库池等同于"重新挂卖",符合「发布冻结、驳回/验收释放」的既有口径;卖家要彻底取回物品,由运营执行【下架作废】后释放押金。

3. 数据安全与事务保障

  • 撤单过程全部置于数据库事务(withTransaction)中,确保库存状态与工单状态原子同步,绝不会出现“工单回退了但库存未恢复”的错乱。
  • 撤销时事务内对工单行 SELECT ... FOR UPDATE,库存 UPDATE 带 status = 'consumed' AND bound_work_order_id = $工单 条件,命中 0 行即 409,防止与「验收」并发时丢失更新或抢占其他工单的绑定。
  • 一件现货同一时刻最多绑定一张工单:迁移 079 增加部分唯一索引 uniq_consignment_inventories_bound_work_order 兜底。
  • 每次撤单操作均在工单事件(work_order_events)中留下完整审计轨迹(记录撤销人、撤回时间、原绑定单号与原因)。

六、 自动化统计报表规划(告别手工 Excel 汇总)

在后台提供清晰的统计看板,解决运营与财务的核心诉求:

  1. 收购人人效统计(Buyer Stats):
    • 维度:王斌、周杰雄、周顺 等。
    • 指标:收货总量(件)、收货总花费(元)、已售出件数、库存去化率(%)、平均单价。
  2. 店铺出库贡献统计(Shop Stats):
    • 维度:拼多多向日葵、稚嫩游戏、佳佳游戏、小鱼儿 等。
    • 指标:各店铺消耗寄售库存单数、直接节省的打手赏金总额(元)、平均履约时效。
  3. 批次核算统计(Batch Stats):
    • 维度:按 8.30-1、8.30-4 等批次代码汇总。
    • 指标:批次总支出、已回款金额、剩余未售资产成本,便于每天下班对账。
  4. 品类规格周转(Spec Stats):
    • 统计 暗潮、怒嚎、血宴 各钻级手枪的在库均价、库存留存天数与断货预警。

七、 界面交互与原型设计

1. 接单平台 · 寄售仓库管理页(ConsignmentInventoryPanel)

  • 顶部数据指标卡:
    • 【在库总数】 / 【在库总成本】 / 【累计节省赏金】 / 【本月出库单数】。
  • 高级筛选工具条:
    • 下拉筛选:收购人(王斌/周杰雄等)、售出店铺(拼多多向日葵等)、批次(如 8.30-1)。
    • 点选切换:系统(全部/苹果/安卓)、区服(全部/微信/QQ)、系列(全部/暗潮/怒嚎/血宴)、钻级(全部/1钻~6钻)。
    • 状态标签切换:【全部】/【在库待匹配】/【已出库】/【已作废】。
  • 表格列表:
    • 支持彩色 Badge:收购人(王斌-紫色、周杰雄-粉色等)、店铺名(拼多多向日葵-橙色等)。
    • 行内 Switch 开关:【允许匹配】随手可切,切换即刻生效。
    • 凭据与截图:支持点击缩略图查看大图(包含角色主页图、手枪词条图)。
    • 敏感交付信息:点击【查看账号密码】,弹窗显示并带有一键复制。
    • 操作:【编辑】、【作废】、针对已出库物品提供【退回复库】。

2. 工单列表与撤销重选(WorkOrdersPanel)

  • 发布前拦截:点击「发布并核销」时,弹窗推荐匹配库存,支持一键选用内部履约结单。
  • 撤销履约入口:对已完成内部履约的工单,提供操作按钮【撤销寄售履约】:
    • 弹出确认弹窗,选择“选错重选 / 买家退款 / 物资作废”;
    • 点击确认后原子回退状态,工单即刻变回未分配状态,支持重新选或发大厅。

3. 客服创建收集链接弹窗(CreateCollectLinkModal) —— 已下线

随收集链接渠道一并移除,客服不再生成对外链接;提报入口为接单平台打手端页面。

4. 寄卖提报审核面板(ConsignmentSubmissionsPanel)

  • 展示卖家提交的待审单据。
  • 审核弹窗:双栏布局,左边看截图(支持放大看词条),右边核对资料,一键【审核入库】或【驳回】。

八、 技术落地与阶段划分

  1. 阶段一:数据库与模型层
    • 创建数据表 consignment_inventories、consignment_collect_links、consignment_submissions。
    • 配置对应 RBAC 权限(consignment.view, consignment.manage, consignment.review, consignment.fulfill)。
  2. 阶段二:后端核心服务与匹配引擎
    • 实现库存 CRUD、多维筛选及统计报表查询;
    • 实现和平精英规格匹配算法(暗潮/怒嚎/血宴 + 16钻 + 16璀璨 + allow_matching 开关判断);
    • 实现发布拦截检测接口与一键内部履约原子事务;
    • 实现工单撤销履约与库存回退重选服务(revokeConsignmentFulfillment)。
  3. 阶段三:前端管理后台
    • 接单平台新增「寄售仓库」面板(包含多维筛选、彩色标签、Switch 开关、卡密查看、退回复库);
    • 新增「寄售审核」面板(提报来源为接单平台打手端);
    • 改造工单发布拦截与履约弹窗;
    • 增加工单列表/详情中的「撤销寄售履约」弹窗与重选逻辑。
  4. 阶段四:移动端 H5 填报端 —— 已下线
    • 原设计为移动端极简收集页;实际改为接单平台打手端提报,H5 页面已删除。