23 KiB
财务系统集成方案
状态:现行方案(未实施)。本文描述
finance_*总账层;当前代码尚未建表,现有财务页仍是UNION ALL业务事件拼装。 最后校准:2026-10-18 代码基线:main @ 7542d547前置:商品主数据、渠道 SKU 映射、成本中心与销售事实必须先完成;商品映射与成本中心已完成 P0,销售事实仍待实施。实施顺序以 README.md §三 为准。 目标:在不破坏现有抢单、押金、结算、寄卖、提现链路的前提下,为 order_site 增加一套可对账、可关账、可追溯的财务系统。 结论先说:不要直接在worker_wallets/worker_wallet_ledgers上继续加字段。 现有表是业务钱包与流水,不是会计总账;正确做法是新增复式记账底座,让现有钱包成为它的“余额投影”。如果只想知道“影子总账”是什么、为什么先跑影子账:先读 影子总账说明.md。
〇、当前实施状态
| 能力 | 状态 |
|---|---|
客服备用金台账(fund_* / 备用金 manual_expenses) |
已实施 P0,见 客服备用金台账实施方案 |
| 商品主数据 / 渠道 SKU 映射 / 成本中心 | 已实施 P0,迁移 102/103/104,见 成本中心与三块履约模型 |
finance_accounts / finance_business_events / finance_journal_* |
未实施 |
finance_settlements / finance_reconciliations |
未实施 |
| 订单级收入/成本/毛利 | 未实施;成本中心已完成,仍需销售事实与收入分摊 |
现有 admin-finance-service.ts |
仍是业务事件 UNION ALL,不是总账 |
不要复用客服备用金的 manual_expenses 作为公司人工支出表。 两者口径不同;公司人工支出应使用 manual_expense_records,并通过 fund_expense_id 关联备用金支出。
一、现有财务能力盘点
1.1 已有表
| 表 | 作用 | 现状 |
|---|---|---|
worker_wallets |
打手资金汇总 | available_amount / frozen_deposit_amount / pending_unfreeze_amount / frozen_withdraw_amount / total_credited_amount / total_settled_amount |
worker_wallet_ledgers |
打手资金流水 | ledger_type / amount / balance_after / frozen_after / audit_status / payload_json |
worker_deposit_unfreezes |
押金/报酬延迟解冻队列 | 到点后由调度任务入账 |
worker_finance_requests |
充值/提现申请 | request_type / status / amount / frozen_amount |
worker_withdrawal_accounts |
提现账户 | 多渠道、二维码、黑名单 |
worker_after_sales_cases / worker_after_sales_debts |
售后追责与欠款 | 欠款可从后续报酬抵扣 |
worker_wallet_ledgers.payload_json |
寄卖发布押金等扩展信息 | kind / consignmentSubmissionId 等 |
consignment_submissions / consignment_inventories |
寄卖发布押金与货款 | 押金冻结/释放/没收、供货货款结算 |
1.2 已有后台财务页
apps/backend/src/services/admin/admin-finance-service.ts 目前用一条大 UNION ALL 把订单收款、退款、打手报酬、提现、充值、售后追缴拼成“财务事件”,输出日汇总与流水。
这不是总账:
- 没有借贷方向,无法验证每笔业务是否平衡。
- 没有会计科目、期间、关账。
- 没有平台侧账单与对账差异。
- 没有订单级收入/成本/毛利。
- 没有业务事件幂等键,重放可能重复统计。
- 余额是可变字段,无法从流水独立重算并校验。
1.3 现有资金动作(必须全部纳入财务)
| 业务动作 | 代码入口 | 财务性质 |
|---|---|---|
| 订单支付 | services/order/order-service.ts |
收入/预收 + 平台应收 |
| 订单退款 | 订单状态回流、售后 | 冲减收入/应收 |
| 工单验收结算 | repositories/worker-platform/work-order-settlement-repo.ts |
履约成本 + 应付打手 |
| 抢单冻结押金 | work-order-grab-repo.ts |
打手余额 → 押金负债 |
| 验收释放押金 | work-order-settlement-repo.ts |
押金负债 → 打手余额 |
| 取消/超时没收押金 | work-order-cancel-repo.ts |
押金负债 → 违约金收入 |
| 拼单份额结算 | work-order-settlement-repo.ts |
按份额拆分成本/押金 |
| 售后扣款/欠款抵扣 | after-sales-repo.ts |
冲减应付打手 / 其他应收 |
| 充值审核通过 | worker-finance-request-service.ts |
银行存款 → 打手余额 |
| 提现申请/审核 | 同上 | 打手余额 → 银行存款 |
| 寄卖发布押金 | consignment-deposit-repo.ts |
打手余额 → 押金负债 |
| 寄卖货款结算 | consignment-deposit-repo.ts |
采购成本/存货 → 应付卖家 |
| 平台服务费/通道费 | 目前未单独建模 | 销售费用/财务费用 |
1.4 三块履约与成本中心的前置关系
财务总账不是孤立存在的,它需要先知道“这笔钱属于哪个商品、哪个店铺、哪个执行载体、用了哪个成本版本”:
| 块 | 载体 | 成本来源 | 财务侧 |
|---|---|---|---|
| 自动发货 | affiliate_dash |
上游固定 cost_amount → cost_versions |
采购成本 |
| 接单平台 | work_orders |
模板价格 → cost_versions / 工单实际报酬快照 |
履约成本 + 押金负债 |
| 人工客服 | manual_fulfillment_cases |
按单/按小时人工成本 | 人工成本 + 履约完成 |
因此建议顺序是:
商品主数据 + 渠道SKU映射
-> 成本中心(cost_items / cost_versions / cost_snapshots)
-> 销售事实(sales_daily_facts)
-> 影子总账(finance_*)
-> 对账 / 转正
详细设计见 成本中心与三块履约模型.md。
二、建设原则
- 复式记账:每笔业务至少两行分录,借方合计 = 贷方合计;不平不允许提交。
- 不可变:已过账分录禁止 UPDATE / DELETE;冲正用反向分录。
- 业务事件幂等:每个业务动作有唯一
business_event_id,重复投递只入账一次。 - 金额只用整数分:数据库
BIGINT,禁止浮点。 - 钱包是投影:
worker_wallets的余额必须能由总账分录重算出来;差异告警。 - 同一事务:业务状态变更与会计分录在同一数据库事务内提交,避免“货发了、账没记”。
- 期间可关账:关账后禁止补记;必须用调整分录并留原因。
- 对账优先:先做影子账 + 对账,再切换钱包读模型,不做一次性大爆炸迁移。
三、目标架构
flowchart LR
BIZ["业务动作<br/>订单/工单/寄卖/提现/售后"] --> OUTBOX["finance_business_events<br/>幂等事件"]
OUTBOX --> POST["finance-posting-service<br/>借贷规则"]
POST --> JE["finance_journal_entries"]
JE --> JL["finance_journal_lines"]
JL --> ACC["finance_accounts<br/>科目表"]
JL --> PROJ["余额投影<br/>worker_wallets / 平台应收应付"]
EXT["平台账单 / 支付流水"] --> REC["finance_reconciliations"]
PROJ --> REC
REC --> REPORT["试算平衡 / 利润表 / 订单损益"]
3.1 科目表(建议)
| 编码 | 科目 | 类型 | 正常方向 |
|---|---|---|---|
| 1001 | 银行存款 | 资产 | 借 |
| 1002 | 支付通道待结算 | 资产 | 借 |
| 1101 | 应收账款-平台 | 资产 | 借 |
| 1201 | 预付账款-供货平台 | 资产 | 借 |
| 1301 | 其他应收-打手欠款 | 资产 | 借 |
| 2001 | 应付打手报酬 | 负债 | 贷 |
| 2002 | 应付卖家货款 | 负债 | 贷 |
| 2003 | 打手押金 | 负债 | 贷 |
| 2004 | 打手可提现余额 | 负债 | 贷 |
| 2005 | 其他应付-垫付人 | 负债 | 贷 |
| 2101 | 应付平台服务费 | 负债 | 贷 |
| 2201 | 预收账款 | 负债 | 贷 |
| 3001 | 本年利润 | 权益 | 贷 |
| 4001 | 商品销售收入 | 收入 | 贷 |
| 4101 | 平台服务费收入 | 收入 | 贷 |
| 4201 | 违约金/没收押金收入 | 收入 | 贷 |
| 5001 | 商品采购成本 | 成本 | 借 |
| 5101 | 履约成本-打手报酬 | 成本 | 借 |
| 5102 | 履约成本-人工客服 | 成本 | 借 |
| 5201 | 支付通道费 | 费用 | 借 |
| 5301 | 售后损失 | 费用 | 借 |
| 5401 | 平台服务费 | 费用 | 借 |
科目可按实际业务裁剪,但“资产/负债/权益/收入/成本费用”五类与借贷方向必须先定死。
3.2 核心表
-- 科目
CREATE TABLE finance_accounts (
id BIGSERIAL PRIMARY KEY,
account_code TEXT NOT NULL UNIQUE,
account_name TEXT NOT NULL,
account_type TEXT NOT NULL CHECK (account_type IN ('asset','liability','equity','revenue','expense')),
normal_side TEXT NOT NULL CHECK (normal_side IN ('debit','credit')),
parent_id BIGINT REFERENCES finance_accounts(id),
status TEXT NOT NULL DEFAULT 'active',
created_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL
);
-- 业务事件收件箱:幂等闸门
CREATE TABLE finance_business_events (
id BIGSERIAL PRIMARY KEY,
business_event_id TEXT NOT NULL UNIQUE,
event_type TEXT NOT NULL,
source_type TEXT NOT NULL,
source_id TEXT NOT NULL,
occurred_at TIMESTAMPTZ NOT NULL,
payload_json JSONB NOT NULL DEFAULT '{}'::jsonb,
status TEXT NOT NULL DEFAULT 'received'
CHECK (status IN ('received','posted','failed','ignored')),
attempts INTEGER NOT NULL DEFAULT 0,
last_error TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL,
processed_at TIMESTAMPTZ
);
-- 结算单(打手报酬 / 卖家货款 / 平台服务费)
CREATE TABLE finance_settlements (
id BIGSERIAL PRIMARY KEY,
settlement_no TEXT NOT NULL UNIQUE,
counterparty_type TEXT NOT NULL CHECK (counterparty_type IN ('worker','supplier','platform','other')),
counterparty_id TEXT NOT NULL DEFAULT '',
period_key TEXT NOT NULL,
amount_fen BIGINT NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending','approved','paid','cancelled')),
approved_at TIMESTAMPTZ,
paid_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL
);
CREATE TABLE finance_settlement_items (
id BIGSERIAL PRIMARY KEY,
settlement_id BIGINT NOT NULL REFERENCES finance_settlements(id) ON DELETE CASCADE,
source_type TEXT NOT NULL,
source_id TEXT NOT NULL,
amount_fen BIGINT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL
);
-- 凭证头
CREATE TABLE finance_journal_entries (
id BIGSERIAL PRIMARY KEY,
entry_no TEXT NOT NULL UNIQUE,
business_event_id TEXT NOT NULL UNIQUE REFERENCES finance_business_events(business_event_id),
entry_type TEXT NOT NULL,
occurred_at TIMESTAMPTZ NOT NULL,
posted_at TIMESTAMPTZ NOT NULL,
period_key TEXT NOT NULL,
currency TEXT NOT NULL DEFAULT 'CNY',
memo TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'posted' CHECK (status IN ('draft','posted','reversed')),
reversal_of_id BIGINT REFERENCES finance_journal_entries(id),
created_by TEXT NOT NULL DEFAULT 'system',
created_at TIMESTAMPTZ NOT NULL
);
-- 凭证行
CREATE TABLE finance_journal_lines (
id BIGSERIAL PRIMARY KEY,
entry_id BIGINT NOT NULL REFERENCES finance_journal_entries(id) ON DELETE RESTRICT,
line_no INTEGER NOT NULL,
account_id BIGINT NOT NULL REFERENCES finance_accounts(id),
debit_fen BIGINT NOT NULL DEFAULT 0,
credit_fen BIGINT NOT NULL DEFAULT 0,
order_id BIGINT,
work_order_id BIGINT,
worker_id BIGINT,
shop_id TEXT NOT NULL DEFAULT '',
provider TEXT NOT NULL DEFAULT '',
settlement_id BIGINT REFERENCES finance_settlements(id),
memo TEXT NOT NULL DEFAULT '',
dimensions_json JSONB NOT NULL DEFAULT '{}'::jsonb,
CHECK (debit_fen >= 0 AND credit_fen >= 0),
CHECK ((debit_fen > 0) <> (credit_fen > 0)),
UNIQUE (entry_id, line_no)
);
-- 会计期间
CREATE TABLE finance_periods (
period_key TEXT PRIMARY KEY, -- 2026-10
starts_at TIMESTAMPTZ NOT NULL,
ends_at TIMESTAMPTZ NOT NULL,
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open','closed')),
closed_at TIMESTAMPTZ,
closed_by TEXT NOT NULL DEFAULT ''
);
-- 对账批次 / 明细
CREATE TABLE finance_reconciliations (
id BIGSERIAL PRIMARY KEY,
channel TEXT NOT NULL, -- 91 / kuaishou / pdd / douyin / affiliate_dash / alipay
period_key TEXT NOT NULL,
expected_fen BIGINT NOT NULL DEFAULT 0,
actual_fen BIGINT NOT NULL DEFAULT 0,
diff_fen BIGINT NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending','matched','diff','resolved')),
created_at TIMESTAMPTZ NOT NULL,
resolved_at TIMESTAMPTZ
);
CREATE TABLE finance_reconciliation_items (
id BIGSERIAL PRIMARY KEY,
reconciliation_id BIGINT NOT NULL REFERENCES finance_reconciliations(id) ON DELETE CASCADE,
source_type TEXT NOT NULL,
source_id TEXT NOT NULL,
external_no TEXT NOT NULL DEFAULT '',
expected_fen BIGINT NOT NULL DEFAULT 0,
actual_fen BIGINT NOT NULL DEFAULT 0,
diff_fen BIGINT NOT NULL DEFAULT 0,
resolution TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL
);
3.3 业务事件 → 分录规则(建议)
冲正不修改原凭证:新建一条
business_event_id = <原ID>:reverse的反向凭证,并让reversal_of_id指向原凭证;原凭证保持posted不变。
| 事件 | 借方 | 贷方 | 备注 |
|---|---|---|---|
| 订单支付 | 1002 支付通道待结算 / 1101 应收平台 | 2201 预收账款 | 金额 = 用户实付(已确认);确认时点待拍板 |
| 履约完成/验收 | 2201 预收账款 | 4001 商品销售收入 | 或按交付时点确认 |
| 工单验收结算 | 5101 履约成本 | 2001 应付打手报酬 | 按份额逐笔 |
| 打手报酬转可提现 | 2001 应付打手报酬 | 2004 打手可提现余额 | 与现有 reward_settlement 对齐 |
| 抢单冻结押金 | 2004 打手可提现余额 | 2003 打手押金 | 不产生损益 |
| 释放押金 | 2003 打手押金 | 2004 打手可提现余额 | 不产生损益 |
| 没收押金 | 2003 打手押金 | 4201 违约金收入 | 需原因与审计 |
| 提现审核通过 | 2004 打手可提现余额 | 1001 银行存款 | 先冻结后扣减 |
| 充值审核通过 | 1001 银行存款 | 2004 打手可提现余额 | 需支付流水号 |
| 售后扣款 | 2001/2004 | 1301 其他应收-打手欠款 | 欠款不足转 worker_after_sales_debts |
| 寄卖发布押金 | 2004 打手可提现余额 | 2003 打手押金 | 与普通押金分维度 |
| 寄卖验收货款 | 5001 商品采购成本 | 2002 应付卖家货款 | 货款金额取 `cost_price_fen |
| 支付卖家货款 | 2002 应付卖家货款 | 1001 银行存款 | 需结算单 |
| 平台服务费 | 5401 平台服务费 | 2101 应付平台服务费 | 从平台账单导入 |
| 人工支出登记通过(垫付) | 5102 履约成本-人工客服(按 cost_item_id 映射科目) |
2005 其他应付-垫付人 | 付款项目/订单号/付款人必填;见 人工支出登记草案 |
| 人工垫付报销 | 2005 其他应付-垫付人 | 1001 银行存款 | 需凭证与审批留痕 |
| 退款冲正(预留) | 反向凭证 reversal_of_id 指向原凭证 |
— | 退款/仲裁暂未接入,先预留不实现 |
已确认(2026-10-17):收入金额口径 = 用户实付;打手报酬 = 支出(总额法);退款/仲裁先预留;人工支出以登记表为入口。 仍待拍板:收入确认时点(付款 / 发货 / 验收 / 售后期结束),它直接影响利润表与预收账款。
四、与现有代码的接入方式
4.1 唯一记账入口
新增 apps/backend/src/services/finance/finance-posting-service.ts:
postBusinessEvent({
businessEventId, // 业务唯一键,如 work_order:123:settle
eventType, // work_order_settled
sourceType, // work_order
sourceId, // 123
occurredAt,
lines: [...], // 借贷行
})
约束:
- 在业务事务内调用;使用同一个
PoolClient。 finance_business_events先INSERT ... ON CONFLICT DO NOTHING。- 已存在则直接返回,不重复入账。
- 校验借贷平衡;不平抛错并回滚业务事务。
- 写入
finance_journal_entries/finance_journal_lines。 - 更新钱包投影(或由投影任务异步更新,但同一事务更安全)。
4.2 需要改造的写入点
| 位置 | 改造 |
|---|---|
services/order/order-service.ts |
订单支付/退款发事件 |
repositories/worker-platform/work-order-settlement-repo.ts |
验收结算、押金释放、报酬入账发事件 |
work-order-grab-repo.ts |
抢单冻结押金发事件 |
work-order-cancel-repo.ts |
取消/超时没收押金发事件 |
after-sales-repo.ts |
售后扣款/欠款抵扣发事件 |
worker-finance-request-service.ts |
充值/提现审核发事件 |
consignment-deposit-repo.ts |
发布押金、货款结算发事件 |
新增 services/finance/manual-expense-service.ts(未来) |
公司人工支出 approved / reimbursed / reversed 发事件;通过 fund_expense_id 关联备用金支出 |
admin-finance-service.ts |
改为读总账/试算平衡,不再用 UNION ALL 拼报表 |
4.3 钱包投影一致性
第一阶段保留现有钱包更新逻辑,同时写总账;第二阶段再切换:
- 影子期:业务照旧改钱包,同时写总账;每日比较“钱包余额”与“总账重算余额”。
- 校验期:差异为 0 连续 N 天后,后台展示“总账余额”为准。
- 切换期:钱包读接口改为读投影;旧字段保留一个版本用于回滚。
- 清理期:删除重复的余额更新代码,只保留总账 + 投影。
五、后台页面与 API
5.1 页面
| 页面 | 内容 |
|---|---|
| 财务总览 | 收入、成本、毛利、押金负债、可提现余额、待结算 |
| 凭证簿 | 按期间/事件/科目/订单筛选;查看借贷行 |
| 科目表 | 科目树、启用/停用、期初余额 |
| 结算中心 | 打手报酬、卖家货款、平台服务费结算单 |
| 对账中心 | 平台账单导入、差异明细、处理状态 |
| 期间关账 | 月末检查、关账、反关账(需高权限) |
| 订单损益 | 单笔订单收入、采购成本、打手报酬、退款、毛利 |
| 试算平衡 / 利润表 | 按期间导出 |
5.2 API
建议新增前缀 /api/v1/admin/finance:
GET /accounts
POST /accounts
GET /journal?period=&eventType=&orderId=&workOrderId=
GET /journal/:id
GET /trial-balance?period=
GET /profit-loss?period=
GET /order-profit/:orderId
GET /settlements
POST /settlements/:id/approve
GET /reconciliations
POST /reconciliations/import
POST /reconciliations/:id/resolve
GET /periods
POST /periods/:key/close
权限建议新增:
finance.post:手工分录finance.close:关账finance.reconcile:对账处理- 现有
finance.view / review / config / export继续使用
所有写操作必须写 admin_audit_logs;关账、手工分录、冲正必须填原因。
六、总账层分期
项目级顺序以 README.md §三 为准;本节只描述“总账层”内部阶段。 进入 P0 前应已完成:商品主数据、渠道 SKU 映射、成本中心、销售事实、公司人工支出登记(
manual_expense_records)。
P0:影子总账(1–2 周)
前置:先完成商品主数据、渠道 SKU 映射、成本中心与销售事实(见 成本中心与三块履约模型.md)。否则影子总账只能记“总额”,无法按店铺/皮肤/成本版本出毛利。
- 建
finance_accounts / business_events / journal_entries / journal_lines / periods。 - 先接高频且核心的事件:订单支付、工单结算、押金冻结/释放/没收、提现,以及公司人工支出的
approved / reimbursed。 - 写总账但不改现有钱包逻辑。
- 每日对账:钱包余额 vs 总账余额。
- 补金额守恒与幂等测试。
P1:寄卖、售后、充值与结算(1–2 周)
- 接寄卖发布押金、货款结算、售后欠款/抵扣、打手充值。
- 建
finance_settlements/finance_settlement_items。 - 后台增加凭证簿与试算平衡。
P2:平台对账(2–3 周)
- 接 91 / 快手 / PDD / 抖音 / affiliate-dash 账单或导出。
- 建
finance_reconciliations/finance_reconciliation_items。 - 差异必须能定位到订单/工单/提现单。
- 对账差异不自动改账,必须人工确认后生成调整分录。
P3:报表与关账(2 周)
- 利润表、订单损益、现金流量简表。
- 期间关账、反关账、期初余额。
- 导出与权限审计。
P4:钱包切换(1 周,需灰度)
- 钱包读模型切到总账投影。
- 旧字段保留一个版本;差异告警。
- 回滚方案:关闭投影读开关,回到旧钱包字段。
七、必须补的测试
- 每笔凭证借方合计 = 贷方合计。
- 同一
business_event_id重复投递只入账一次。 - 冲正后原凭证 + 反向凭证净额为 0。
- 钱包余额 = 总账重算余额。
- 抢单冻结 / 验收释放 / 取消没收的押金守恒。
- 拼单多份额:份额报酬 + 押金 + 欠款抵扣 = 钱包变化。
- 提现:申请冻结、审核通过、拒绝解冻三条路径。
- 寄卖:发布押金、驳回释放、验收货款、撤销处置。
- 售后:扣款、欠款、后续报酬抵扣。
- 关账后禁止补记;调整分录必须留原因。
- 对账:平台金额、订单金额、钱包金额三方差异可定位。
八、需要业务拍板的问题
2026-10-17 已确认 4 条口径,明细见 成本中心与三块履约模型.md §11。
| # | 问题 | 状态 | 影响 |
|---|---|---|---|
| 1 | 收入金额口径 | ✅ 已确认:收入 = 用户实付(orders.total_amount),与快手 paymentFen 数据核验 100% 一致 |
收入基数 |
| 2 | 收入确认时点:付款 / 发货 / 验收 / 售后期结束? | ⏳ 待定(金额口径已定) | 决定利润表与预收账款 |
| 3 | 平台结算周期与账单口径(91、快手、PDD、抖音、affiliate-dash) | ⏳ 待定 | 决定对账与应收 |
| 4 | 打手报酬是“成本”还是“代收代付”? | ✅ 已确认:支出/成本(最终提现打款),按总额法 | 收入总额法/净额法 |
| 5 | 寄卖货款的采购成本确认时点 | ⏳ 待定 | 决定存货/成本 |
| 6 | 提现通道费、平台服务费由谁承担 | ⏳ 待定 | 决定费用科目与结算 |
| 7 | 退款、拒付、仲裁的冲减规则 | ✅ 已确认:暂未接入,先预留(字段 + reversal_of_id + 事件类型,不实现逻辑) |
决定售后与收入冲回 |
| 8 | 人工支出如何入账 | ✅ 已确认:以「人工支出登记」为入口(付款项目/金额/订单号/付款人/凭证),SLA 监管延后 | 决定人工成本科目与总账事件 |
| 9 | 是否需要发票/税务 | ⏳ 待定 | 决定发票表与税额 |
| 10 | 是否多币种 | ⏳ 待定(当前 CNY) | 若否则需汇率与汇兑损益 |
九、一句话结论
财务系统应作为“总账层”接入,而不是继续扩展业务钱包。 先把商品主数据、成本中心、人工 case 与销售事实补齐,再以影子总账 + 幂等业务事件 + 每日对账落地;确认钱包与总账长期一致后,再切换余额读模型。这样既能保护现有抢单/押金/寄卖链路,也能为平台结算、订单损益和关账留出正确底座。