0. 已确认业务口径
B02:删除发生时部门列和归属方式下拉框。
B03:流水号按账户前缀--log_id生成。
B04:业务单号按场景关联,缺失显示“--”。
B05:历史渠道/操作人不可推导时显示“未知/--”。
B06:不增加冲正关联、状态和质量字段,正负金额自然汇总。
B07:无赠送账户开关,当前版本统一展示赠送账户。
1. 结论
yoshop_user_balance_log、yoshop_user_subsidy_log、yoshop_user_gift_log,只为现金流水补充 balance_after。当前有效一卡通用户不查询、不汇总、不导出,也不参与历史回填。| 一卡通配置 | 用户身份 | 访客流水查询 | 现金历史回填 |
|---|---|---|---|
| 缺失、无效或关闭 | 普通本地用户 | 适用 | 适用 |
| 缺失、无效或关闭 | 历史曾映射用户 | 按当前本地模式适用 | 适用 |
| 已开启 | 未命中当前有效映射的访客 | 适用 | 适用 |
| 已开启 | 命中 business + staff_uuid/user_id 有效映射 | 不适用 | 禁止参与 |
身份判定复用现有访客财务查询和后端 UserGuard。配置缺失、无效 JSON 或关闭时按本地模式;配置开启但 business 映射冲突、数据库读取失败时停止,不能降级为访客。
2. 本期范围
- 访客三账户统一筛选、分页和明细
- 期初、变动、变化后余额
- 总入账、总出账、净变动、分账户汇总
- 按筛选条件异步导出
- 列表无发生时部门、操作、查看和详情入口
- 当前有效一卡通用户不进入本地钱包查询
- 历史渠道/操作人不可推导时显示未知/--
- 不增加冲正关联、状态和数据质量字段
- 数据库版本不足通过SQL升级解决
部门筛选固定按当前部门;不统计业务笔数和账户变动条数。
3. 数据库变更
正式 SQL 放入 ai_api/db/<已确认版本号>.sql,版本号由发布计划确认。
ALTER TABLE `yoshop_user_balance_log` ADD COLUMN `balance_after` decimal(10,2) DEFAULT NULL COMMENT '变动后现金余额' AFTER `money`, ADD KEY `idx_store_user_time` (`store_id`, `user_id`, `create_time`, `log_id`);
首发使用 NULL。NULL 表示尚未回填或写入入口遗漏;0.00 表示真实零余额。稳定运行后再评审是否改成无默认值的 NOT NULL。
4. 访客新业务写入
balance_after = balance_before + money必须覆盖的访客入口
充值、后台充值、消费、退款、提现、提现失败返还、管理员调账、异常恢复、补偿任务、定时任务,以及 store/ai_api 中所有直接写 user_balance_log 的本地钱包入口。一卡通消费、退款和余额同步保持既有一卡通链路。
rg -n "user_balance_log.*insert|BalanceLog::add|new BalanceLog" \ zhctproject/store/application \ zhctproject/ai_api/app
5. 访客历史现金流水回填
新增 InitBalanceLogFields.php。先复用后端一卡通身份判断排除当前有效一卡通用户,再对访客反向还原。配置缺失、无效 JSON 或关闭时按本地模式;配置开启但身份数据库失败或 business 映射冲突时停止回填。
按访客 store_id + user_id 分组 cursor = yoshop_user.balance 按 create_time DESC, log_id DESC 遍历 当前流水.balance_after = cursor cursor = cursor - 当前流水.money
只处理:
WHERE balance_after IS NULL AND log_id <= :cutoff_log_id
命令至少支持 check-only、dry-run、store-id、user-id、cutoff-log-id 和 page-size。当前有效一卡通用户即使存在本地历史流水也不得参与:其余额是第三方镜像,本地流水不保证完整。
6. 访客三账户统一查询
GET /api/finance/visitor/flows 与 VisitorFlow.php 已实现身份快照、有效映射排除、高水位快照、复合游标及访客现金/补贴查询。本需求复用其身份范围与分页设计,不改变既有第三方接口契约。| 统一字段 | 现金 | 补贴 | 赠送 |
|---|---|---|---|
| account_type | cash | subsidy | gift |
| balance_before | balance_after - money | subsidy_balance_after - money | 原字段 |
| balance_after | 新增字段 | subsidy_balance_after | 原字段 |
| create_time | Unix 转 datetime | Unix 转 datetime | datetime |
PC 服务只提供列表、汇总和导出,不提供详情接口;列表没有操作列或查看入口。异步导出复用 ydy_export_log。
一卡通独立入口
若管理端需要查看一卡通资金记录,应读取 ydy_one_card_trade_order、ydy_one_card_trade_attempt_log 和 ydy_one_card_trade_repair_log,展示第三方返回的现金/补贴前后余额、交易单号、状态和补偿记录。
7. 上线步骤
批次一:兼容 DDL
备份、只读预检后增加可空字段和索引,并回读确认实际状态。
批次二:访客代码发布
发布 store、ai_api 和受影响的 Work/定时任务代码。验证一卡通四模式身份矩阵;只要访客新流水仍有 NULL,就禁止回填。
批次三:访客维护窗口回填
暂停所有访客现金写入口、补偿与相关任务;冻结一卡通配置和映射变化,避免身份范围漂移。访客范围两次查询不再变化后记录 cutoff,先单用户、再单门店、最后分批全量。
批次四:校验与恢复
验证访客 NULL 为零、最新流水等于当前余额、相邻流水连续;同时验证有效一卡通用户未进入回填结果。通过后恢复业务并复验。
批次五:开放访客查询
后端身份过滤 → 接口 → 菜单权限 → PC 页面 → 异步导出 → 内部账号 → 正式角色。
8. 验收标准
- 所有新增访客现金流水写入正确 balance_after。
- 访客回填范围内历史现金流水无 NULL,余额链连续。
- 访客三账户可统一筛选、分页和导出,汇总与明细一致。
- 一卡通开启且命中有效映射的用户不进入访客查询、汇总、导出和回填。
- 一卡通关闭时,历史映射用户仍按本地模式适用。
- 一卡通开启但未命中映射的访客仍可使用本功能。
- 配置开启但身份数据库失败或 business 映射冲突时停止;配置缺失、无效或关闭保持本地模式。
- 复用既有访客身份和高水位分页设计,/api/finance/visitor/flows 第三方契约不变。
- 充值、消费、退款、提现、补贴、赠送及一卡通四模式回归通过。
9. 回滚与停止规则
| 场景 | 处理 |
|---|---|
| 代码异常 | 回滚代码,保留可空字段。 |
| 回填异常 | 停止当前批次,按批次/门店/用户/流水 ID 续跑,不全表清空。 |
| 页面异常 | 关闭菜单或功能入口,不回退正确余额数据。 |
| 硬停止 | 无备份、目标库不符、部分结构冲突、新代码仍写 NULL、无法真正停写。 |
10. 开发前待办
- 确认正式 SQL 的目标发布版本号。
- 确认维护窗口及受影响 Work/定时任务清单。
- 确认回填异常负责人、处理时限和是否允许部分门店先恢复。
- 确认稳定运行多久后评审 balance_after NOT NULL。
业务方案:已收口 当前状态:待开发准备