Files
Neo-ZQYY/docs/prd/specs/P12-gift-card-breakdown.md

11 KiB
Raw Blame History

P12赠送卡矩阵细分数据 — gift-card-breakdown

优先级P1BOARD-3 财务看板功能缺陷修复) 来源RNS1 系列审计遗留项 P1-6 预估工作量:中 依赖无新增依赖DWD 层数据已就绪)


背景

BOARD-3 财务看板的「预收资产」板块包含一个赠送卡 3×4 矩阵3 行:新增/消费/余额4 列:合计/酒水卡/台费卡/抵用券)。当前矩阵除余额行的 total 列外,所有细分单元格均返回 0。

根因DWS 层 dws_finance_recharge_summary 只存储赠送卡总额(recharge_giftgift_card_balance),未按卡类型拆分。而 DWD 层 dim_member_card_account 已通过 card_type_id 区分三种赠送卡类型,数据源完备。


需求Requirements

用户故事

  1. 作为门店管理者,我需要在财务看板中看到赠送卡按用途(酒水/台费/抵用券)拆分的余额、新增、消费数据,以便了解各类赠送卡的使用情况和资金分布。

验收标准

  • AC1dws_finance_recharge_summary 新增 6 个字段3 种卡类型 × 余额+新增ETL 任务正确填充
  • AC2BOARD-3 赠送卡矩阵「余额」行的 liquor/table_fee/voucher 列显示正确数值
  • AC3赠送卡矩阵「新增」行显示各类型赠送卡的新增金额按充值订单的 point_amount 拆分)
  • AC4赠送卡矩阵「消费」行显示各类型赠送卡的消费金额如 DWD 层可追溯)
  • AC5环比数据正确计算如启用 compare 参数)
  • AC6RLS 视图自动包含新字段(CREATE OR REPLACE VIEW 使用 SELECT * 或显式列名)
  • AC7FDW 外部表通过 IMPORT FOREIGN SCHEMA 自动同步
  • AC8GET /api/xcx/board/finance 接口返回的 gift_rows 矩阵包含正确的细分数据(非全 0
  • AC9小程序 board-finance 页面赠送卡矩阵正确渲染后端返回的细分数据(替换 mock

数据源分析

DWD 层现有数据

dwd.dim_member_card_account 通过 card_type_id 区分卡类型:

card_type_id 类型 当前记录数 当前余额
2793249295533893 储值卡 421 128,918.32
2791990152417157 台费卡(赠送) 343 246,267.50
2793266846533445 活动抵用券(赠送) 118 24,978.70
2794699703437125 酒水卡(赠送) 49 3,708.95
2791987095408517 年卡 7 7.00
2793306611533637 月卡 12 4,938.00

ETL 任务 FinanceRechargeTask._extract_card_balances() 已硬编码三个赠送卡 ID

GIFT_CARD_TYPE_IDS = [2791990152417157, 2793266846533445, 2794699703437125]

矩阵数据需求

数据来源 说明
余额 dim_member_card_accountcard_type_id 分组 当日末快照,已有数据
新增 dwd_recharge_order.point_amount 按会员卡类型拆分 需要 JOIN dim_member_card_account 确定卡类型
消费 dwd_settlement_head.gift_card_amount 总额已有,但无法按卡类型拆分(结算单不记录具体使用哪种赠送卡)

关键约束

  • 消费行拆分可能不可行dwd_settlement_head.gift_card_amount 是赠送卡消费总额,飞球上游 API 不提供按卡类型拆分的消费明细。需确认是否有 dwd_settlement_head_ex 或其他扩展表包含此信息。
  • 新增行拆分:充值订单 dwd_recharge_ordertenant_member_card_id 可关联 dim_member_card_account.tenant_member_id,从而确定充值到哪种卡类型。
  • card_type_id 硬编码:当前 ETL 已硬编码,本次扩展沿用同一套 ID。后续可考虑迁移至配置表feiqiu-data-rules 规则 6 精神)。

设计要点

DDL 变更(dws_finance_recharge_summary

新增 6 个字段:

字段名 类型 说明
gift_liquor_balance NUMERIC(14,2) 酒水卡余额(当日末)
gift_table_fee_balance NUMERIC(14,2) 台费卡余额(当日末)
gift_voucher_balance NUMERIC(14,2) 抵用券余额(当日末)
gift_liquor_recharge NUMERIC(14,2) 酒水卡新增充值(赠送部分)
gift_table_fee_recharge NUMERIC(14,2) 台费卡新增充值(赠送部分)
gift_voucher_recharge NUMERIC(14,2) 抵用券新增充值(赠送部分)

消费行拆分字段暂不新增(待确认上游数据可行性)。消费行 total 可通过 gift_card_balance 变化量 + 新增量反推(consumed = prev_balance + recharge - current_balance),但精度依赖余额快照的连续性。

ETL 任务修改

修改 FinanceRechargeTask._extract_card_balances()

  • gift_balance 拆分为 3 个细分余额
  • 新增 _extract_gift_recharge_breakdown() 方法,通过 dwd_recharge_order JOIN dim_member_card_account 按卡类型拆分赠送金额

后端接口修改

接口路径:GET /api/xcx/board/financeBOARD-3 财务看板)

  • 路由:apps/backend/app/routers/xcx_board.pyget_finance_board()
  • 权限:view_board_finance

涉及文件与修改点:

文件 修改点
apps/backend/app/services/fdw_queries.py get_finance_recharge() — SQL 新增 6 个字段的 SUM填充 gift_rows 矩阵的余额行和新增行细分数据
apps/backend/app/services/fdw_queries.py _empty_recharge_data() — 空默认值同步新增字段
apps/backend/app/services/board_service.py _build_recharge() — 环比计算已覆盖 gift_rows 所有 cell无需额外修改自动适配
apps/backend/app/schemas/xcx_board.py GiftCell / GiftRow / RechargePanel — schema 无需修改(已预留 liquor/table_fee/voucher 字段)

消费行:如果无法直接拆分,使用 余额变化量反推法 或保持 total only。

小程序页面影响

页面路径:apps/miniprogram/miniprogram/pages/board-finance/

文件 当前状态 修改点
board-finance.wxml (L316-370) 赠送卡矩阵已渲染 recharge.giftRows3 行 × 4 列(酒水卡/台费卡/抵用券) 无需修改(模板已就绪,数据绑定字段已对齐)
board-finance.ts 当前使用 mock 数据(giftRows 硬编码) 联调时替换 mock 为真实 API 调用(非本 SPEC 范围,属于联调阶段)
board-finance.wxss (L643-717) 赠送卡表格样式已完成 无需修改

字段映射关系(后端 → 小程序):

后端字段 小程序绑定
GiftRow.total.value item.total
GiftRow.liquor.value item.wine
GiftRow.table_fee.value item.table
GiftRow.voucher.value item.coupon
GiftRow.*.compare item.*Compare

小程序页面模板和样式已在 RNS1 阶段完成,本次只需后端返回正确数据即可自动渲染。联调阶段需将 mock 数据替换为真实 API 调用。

管理后台

admin-web 无涉及赠送卡/充值统计的页面,不受影响。

RLS 视图 & FDW

  • app.v_dws_finance_recharge_summary 使用 CREATE OR REPLACE VIEW,需要更新列列表
  • FDW 使用 IMPORT FOREIGN SCHEMA,需要重新导入(幂等脚本已支持)

数据流向

DWD 层
├─ dwd_recharge_order.point_amount ──→ JOIN dim_member_card_account ──→ 按 card_type_id 拆分赠送金额
├─ dim_member_card_account.balance ──→ 按 card_type_id 分组求和 ──→ 3 种赠送卡余额
└─ dwd_settlement_head.gift_card_amount ──→ 总额(无法按卡类型拆分)

    ↓ ETLFinanceRechargeTask

DWS 层dws_finance_recharge_summary+6 字段)

    ↓ RLS 视图 + FDW

业务库app.v_dws_finance_recharge_summary

    ↓ fdw_queries.get_finance_recharge()

FastAPIGET /api/xcx/board/finance → RechargePanel.gift_rows

    ↓ 小程序渲染

board-finance 页面:赠送卡矩阵 3×4 显示正确数值

待确认项

  1. 消费行拆分dwd_settlement_head_ex 或其他表是否包含赠送卡消费的卡类型明细?如果没有,消费行只能显示 total细分列保持 0 或使用反推法。
  2. card_type_id 2791987095408517 和 2793306611533637:已确认为年卡和月卡,不纳入赠送卡矩阵。
  3. 环比需求:赠送卡矩阵的每个 cell 是否需要环比数据compare 字段)?当前 schema GiftCell 已预留 compare: str | None

任务清单

数据层ETL + DDL

  • T1DDL 迁移 — dws_finance_recharge_summary 新增 6 个字段
    • 迁移脚本:db/etl_feiqiu/migrations/2026-xx-xx_add_gift_breakdown_fields.sql
    • DDL 基线同步:docs/database/ddl/etl_feiqiu__dws.sql
  • T2ETL 修改 — _extract_card_balances() 拆分赠送卡余额
    • 文件:apps/etl/connectors/feiqiu/tasks/dws/finance_recharge_task.py
    • 返回值新增 gift_liquor_balancegift_table_fee_balancegift_voucher_balance
  • T3ETL 新增 — _extract_gift_recharge_breakdown() 拆分赠送卡新增
    • 文件:同 T2
    • SQLdwd_recharge_order JOIN dim_member_card_accountcard_type_id 分组
  • T4ETL transform — transform() 方法写入新增 6 个字段到 record dict

数据库视图层

  • T5RLS 视图更新 — app.v_dws_finance_recharge_summary 重建
    • 迁移脚本:db/etl_feiqiu/migrations/db/zqyy_app/migrations/
  • T6FDW 外部表同步 — IMPORT FOREIGN SCHEMA 重新导入

后端接口层

  • T7后端修改 — fdw_queries.get_finance_recharge()
    • 文件:apps/backend/app/services/fdw_queries.py
    • SQL 新增 6 个字段的 SUM
    • 填充 gift_rows 矩阵:余额行 + 新增行的 liquor/table_fee/voucher
  • T8后端修改 — _empty_recharge_data() 空默认值同步

小程序页面层

  • T9小程序联调 — board-finance.ts 替换 mock 数据为真实 API 调用
    • 文件:apps/miniprogram/miniprogram/pages/board-finance/board-finance.ts
    • 当前状态mock 数据硬编码,模板和样式已就绪
    • 注意:字段映射 liquor→winetable_fee→tablevoucher→coupon 需在数据转换层处理

验证与文档

  • T10验证 — 跑数后对比 dim_member_card_account 余额与 DWS 汇总值
  • T11BD 手册更新 — BD_manual_dws_finance_recharge_summary.md

涉及文件汇总

模块 文件路径 操作
DDL db/etl_feiqiu/migrations/2026-xx-xx_add_gift_breakdown_fields.sql 新增
DDL 基线 docs/database/ddl/etl_feiqiu__dws.sql 修改
ETL apps/etl/connectors/feiqiu/tasks/dws/finance_recharge_task.py 修改
RLS 视图 db/etl_feiqiu/migrations/db/zqyy_app/migrations/ 新增
后端 apps/backend/app/services/fdw_queries.py 修改
小程序 apps/miniprogram/miniprogram/pages/board-finance/board-finance.ts 修改
Schema apps/backend/app/schemas/xcx_board.py 无需修改(已预留)
路由 apps/backend/app/routers/xcx_board.py 无需修改
服务 apps/backend/app/services/board_service.py 无需修改(环比自动适配)
BD 手册 apps/etl/connectors/feiqiu/docs/database/DWS/main/BD_manual_dws_finance_recharge_summary.md 修改