Files
rent/docs/features/finance-system.md
2026-05-26 21:27:48 +08:00

28 KiB
Raw Permalink Blame History

财务系统设计文档

版本v3.0(合并版)
最后更新2024-01-XX
状态 已实现并优化


📋 目录

  1. 概述
  2. 账户体系
  3. 资金流转
  4. 结算周期
  5. 服务费计算
  6. 核心服务
  7. 数据库表结构
  8. 前端展示
  9. API接口
  10. 扩展方案
  11. 安全保障
  12. 数据一致性保证
  13. 测试验证
  14. 部署说明
  15. 常见问题
  16. 更新日志

概述

本文档描述了租房平台的财务系统架构,包括账户体系、资金流转、结算逻辑和安全保障机制。

核心特性

  • 四层账户体系(系统总账户、平台账户、商家账户、用户账户)
  • 资金守恒验证机制
  • 订单支付、结算、退款、提现完整流程
  • 自动周结算(每周一凌晨2点)
  • 邀请返现机制
  • 多重安全保障(事务、悲观锁、乐观锁、复式记账)
  • 完整的交易流水记录

账户体系

账户名称常量说明

为了提高代码可维护性和国际化支持,系统账户名称采用英文常量存储,前端显示时映射为中文。

账户名称映射表:

英文常量 (数据库存储) 中文显示名称 说明
SYSTEM_MAIN 系统总账户 记录整个系统的资金流入流出,用于资金守恒验证
PLATFORM_MAIN 平台主账户 平台的主要收益账户,记录服务费收入和邀请返现支出
PLATFORM_BACKUP 平台备用账户 平台的备用账户(可选)

后端使用:

// 导入常量
import { ACCOUNT_NAMES } from '@/constants/account.constant';

// 使用常量查询
const systemAccount = await this.systemAccountRepo.findOne({
  where: { account_name: ACCOUNT_NAMES.SYSTEM_MAIN }
});

const platformAccount = await this.platformAccountRepo.findOne({
  where: { account_name: ACCOUNT_NAMES.PLATFORM_MAIN }
});

前端使用:

// 导入映射工具
import { getAccountDisplayName } from '@/utils/accountNameMap';

// 将英文常量转换为中文显示
const displayName = getAccountDisplayName('SYSTEM_MAIN'); // 返回:系统总账户
const displayName2 = getAccountDisplayName('PLATFORM_MAIN'); // 返回:平台主账户

四层账户结构

系统采用四层账户结构,确保资金流转清晰、职责明确:

1. 系统总账户 (System Account)

职责:记录平台内所有未提现的资金总额

计算公式

系统总账户余额 = 用户实付总额 - 累计退款 - 累计提现

字段说明

  • balance: 当前余额
  • total_income: 累计收入(用户实付总额)
  • total_refund: 累计退款
  • total_withdrawn: 累计提现

数据表system_accounts

2. 平台账户 (Platform Account)

职责:记录平台净收益(服务费收入 - 邀请返现支出)

计算公式

平台账户余额 = 累计服务费收入 - 累计邀请返现支出

字段说明

  • balance: 当前余额
  • total_income: 累计收入(服务费收入)
  • total_expense: 累计支出(邀请返现支出)

数据表platform_accounts

3. 商家账户 (Merchant Account)

职责:记录商家的订单收入和提现

计算公式

商家账户余额 = 累计订单收入 - 累计提现
订单收入 = 订单金额 - 服务费

字段说明

  • balance: 可用余额
  • frozen_balance: 冻结余额(提现申请中)
  • total_income: 累计收入
  • total_expense: 累计支出(提现)

数据表merchant_accounts

4. 用户账户 (User Account)

职责:记录用户的邀请返现收入和提现

计算公式

用户账户余额 = 累计邀请返现 - 累计提现

字段说明

  • balance: 可用余额
  • frozen_balance: 冻结余额(提现申请中)
  • total_income: 累计收入(邀请返现)
  • total_expense: 累计支出(提现)

数据表user_accounts

资金守恒验证

系统通过以下公式验证资金守恒:

系统总账户余额 = 商家账户余额总和 + 用户账户余额总和 + 平台账户余额

这个公式确保平台内所有资金都有明确的归属,不会出现资金丢失或凭空产生的情况。

资金流转

1. 订单支付流程

用户支付订单
  ↓
系统总账户 +实付金额
  ↓
订单状态:pending_pay → pending_confirm

涉及文件

  • apps/server/src/modules/app/order/order.service.ts (payByOrderNo, pay 方法)
  • apps/server/src/modules/shared/finance/account.service.ts (addSystemIncome 方法)

关键代码

// 记录系统总账户收入(用户实付金额)
await this.accountService.addSystemIncome(
  order.payAmount,
  transactionNo,
  'order_payment',
  order.id,
  order.orderNo,
  `用户支付订单:${order.orderNo}`,
);

2. 订单结算流程

订单完成(用户离店)
  ↓
商家账户 +(实付金额 - 服务费)
  ↓
平台账户 +服务费
  ↓
如果有邀请关系:
  用户账户(邀请人)+返现金额
  平台账户 -返现金额

涉及文件

  • apps/server/src/modules/shared/finance/settlement.service.ts (createSettlement 方法)
  • apps/server/src/modules/app/activity/activity.service.ts (handleOrderCompleted 方法)

关键代码

// 给商家账户增加余额
await this.accountService.addMerchantBalance(
  merchantId,
  settlementAmount, // 订单金额 - 服务费
  transactionNo,
  'settlement',
  settlement.id,
  settlementNo,
  `商家周结算:${periodStart} ~ ${periodEnd}`
);

// 给平台账户增加服务费收入
await this.accountService.addPlatformBalance(
  serviceFee,
  transactionNo,
  'settlement',
  settlement.id,
  settlementNo,
  `商家 ${merchantId} 周结算服务费:${periodStart} ~ ${periodEnd}`
);

// 邀请返现(如果有)
await this.accountService.addUserBalance(
  invitation.inviterId,
  amount,
  transactionNo,
  'invite_cashback',
  cashback.id,
  order.orderNo,
  `邀请返现 - 订单${order.orderNo}${orderIndex}单`,
);

await this.accountService.deductPlatformCashback(
  amount,
  transactionNo,
  'invite_cashback',
  cashback.id,
  order.orderNo,
  `邀请返现支出 - 用户${invitation.inviterId}订单${order.orderNo}`,
);

3. 订单退款流程

用户申请退款
  ↓
调用第三方支付退款API
  ↓
系统总账户 +退款金额
  ↓
订单状态:pending_confirm/pending_checkin → refunded

涉及文件

  • apps/server/src/modules/shared/finance/refund.service.ts (processRefund 方法)

关键代码

// 记录系统总账户退款
await this.accountService.addSystemRefund(
  order.payAmount,
  transactionNo,
  'order_refund',
  order.id,
  order.orderNo,
  `订单退款 - ${order.orderNo}`,
);

4. 提现流程

用户提现

用户申请提现
  ↓
用户账户:balance → frozen_balance
  ↓
管理员审核通过
  ↓
管理员确认打款
  ↓
用户账户 -提现金额(从frozen_balance扣减)
系统总账户 +提现金额
  ↓
提现状态:pending → approved → paid

商家提现

商家申请提现
  ↓
商家账户:balance → frozen_balance
  ↓
管理员审核通过
  ↓
管理员确认打款
  ↓
商家账户 -提现金额(从frozen_balance扣减)
系统总账户 +提现金额
  ↓
提现状态:pending → approved → paid

涉及文件

  • apps/server/src/modules/shared/finance/withdrawal.service.ts (payUserWithdrawal, payMerchantWithdrawal 方法)

关键代码

// 扣减用户账户余额
await this.accountService.deductUserBalance(
  withdrawal.userId,
  Number(withdrawal.actualAmount),
  transactionNo,
  'withdraw',
  withdrawal.id,
  withdrawal.withdrawNo,
  `用户提现 - ${withdrawal.paymentChannel}`
);

// 记录系统总账户提现
await this.accountService.addSystemWithdrawal(
  Number(withdrawal.actualAmount),
  transactionNo,
  'user_withdraw',
  withdrawal.id,
  withdrawal.withdrawNo,
  `用户 ${withdrawal.userId} 提现 - ${withdrawal.paymentChannel}`,
);

结算周期

周结算机制

执行时间:每周一凌晨 2:00
结算周期:上周一 00:00:00 ~ 上周日 23:59:59
结算对象:状态为 completed 的订单
判断依据:订单的 checkout_at(离店时间)字段

定时任务配置

文件位置apps/server/src/schedule/settlement.schedule.ts

@Cron('0 2 * * 1') // 每周一凌晨2点
async handleWeeklySettlement() {
  await this.settlementService.handleWeeklySettlement();
}

结算逻辑

  1. 查询上周已完成订单

    const orders = await this.orderRepo
      .createQueryBuilder('o')
      .where('o.status = :status', { status: 'completed' })
      .andWhere('o.checkout_at BETWEEN :start AND :end', {
        start: `${lastWeekStart} 00:00:00`,
        end: `${lastWeekEnd} 23:59:59`
      })
      .getMany();
    
  2. 按商家分组统计

    • 订单数量:orderCount
    • 订单总额:orderAmount
    • 服务费总额:serviceFee
    • 结算金额:settlementAmount = orderAmount - serviceFee
  3. 生成结算单

    • 创建 Settlement 记录
    • 创建 SettlementItem 记录
  4. 执行资金转账

    • 商家账户增加
    • 平台账户增加(服务费)
    • 复式记账

防止重复结算

// 检查该周期是否已经结算过
const existingSettlements = await this.settlementRepo.count({
  where: {
    periodStart: lastWeekStart,
    periodEnd: lastWeekEnd
  }
});

if (existingSettlements > 0) {
  throw new Error(`该周期 ${lastWeekStart} ~ ${lastWeekEnd} 已经结算过,无法重复结算`);
}

服务费计算

计算公式

// 用户实付金额
payAmount = totalAmount - couponDiscount

// 服务费
serviceFee = Math.round(payAmount * serviceFeeRate * 100) / 100

// 商家实收金额
merchantIncome = payAmount - serviceFee

服务费率配置

默认值5% (0.05)
配置位置platform_configs
配置键service_fee_rate

示例计算

房费总额:1000元
优惠券抵扣:100元
服务费率:5%

用户实付:1000 - 100 = 900元
服务费:900 × 0.05 = 45元
商家实收:900 - 45 = 855元
平台收入:45元

核心服务

AccountService

账户操作核心服务,提供所有账户的增减操作。

位置apps/server/src/modules/shared/finance/account.service.ts

主要方法

系统总账户操作

  • getSystemAccount() - 获取系统总账户
  • addSystemIncome(amount, ...) - 记录用户实付收入
  • addSystemRefund(amount, ...) - 记录退款
  • addSystemWithdrawal(amount, ...) - 记录提现

平台账户操作

  • addPlatformBalance(serviceFee, ...) - 记录服务费收入
  • deductPlatformCashback(amount, ...) - 记录邀请返现支出

核心代码示例

// 平台账户增加余额(服务费收入)
async addPlatformBalance(
  amount: number,
  transactionNo: string,
  businessType: string,
  businessId: number,
  businessNo: string,
  remark: string,
): Promise<void> {
  const queryRunner = this.dataSource.createQueryRunner();
  await queryRunner.connect();
  await queryRunner.startTransaction();

  try {
    // 使用悲观锁查询账户
    const account = await queryRunner.manager.findOne(PlatformAccount, {
      where: { account_name: '主账户' },
      lock: { mode: 'pessimistic_write' },
    });

    // 金额精度控制
    const amountNum = Number(amount);
    const balanceBefore = Number(account.balance);
    const balanceAfter = parseFloat((balanceBefore + amountNum).toFixed(2));

    // 更新账户
    account.balance = balanceAfter;
    account.total_income = parseFloat((Number(account.total_income) + amountNum).toFixed(2));
    account.version += 1;

    await queryRunner.manager.save(account);

    // 记录交易流水
    const transaction = queryRunner.manager.create(PlatformTransaction, {
      transactionNo,
      accountId: account.id,
      direction: 'income',
      amount: amountNum,
      balanceBefore,
      balanceAfter,
      transactionType: 'service_fee',
      businessType,
      businessId,
      businessNo,
      remark,
    });

    await queryRunner.manager.save(transaction);
    await queryRunner.commitTransaction();
  } catch (error) {
    await queryRunner.rollbackTransaction();
    throw error;
  } finally {
    await queryRunner.release();
  }
}

商家账户操作

  • addMerchantBalance(merchantId, amount, ...) - 增加商家余额
  • deductMerchantBalance(merchantId, amount, ...) - 扣减商家余额
  • freezeMerchantBalance(merchantId, amount) - 冻结商家余额
  • unfreezeMerchantBalance(merchantId, amount) - 解冻商家余额

用户账户操作

  • addUserBalance(userId, amount, ...) - 增加用户余额
  • deductUserBalance(userId, amount, ...) - 扣减用户余额
  • freezeUserBalance(userId, amount) - 冻结用户余额
  • unfreezeUserBalance(userId, amount) - 解冻用户余额

安全机制

  • 使用数据库事务确保操作原子性
  • 使用悲观锁(pessimistic_write)防止并发修改
  • 使用乐观锁(version 字段)检测并发冲突
  • 所有金额计算使用 Number()toFixed(2) 确保精度

SettlementService

订单结算服务,负责商家的周结算。

位置apps/server/src/modules/shared/finance/settlement.service.ts

主要功能

  • 每周一凌晨2点自动执行周结算
  • 统计上周已完成订单
  • 按商家分组计算结算金额
  • 更新商家账户和平台账户

RefundService

退款服务,负责订单退款处理。

位置apps/server/src/modules/shared/finance/refund.service.ts

主要功能

  • 调用第三方支付退款API(微信支付、支付宝)
  • 更新订单状态
  • 记录系统总账户退款

WithdrawalService

提现服务,负责用户和商家的提现申请、审核、打款。

位置apps/server/src/modules/shared/finance/withdrawal.service.ts

主要功能

  • 提现申请(冻结余额)
  • 提现审核(通过/拒绝)
  • 提现打款(扣减余额,记录系统总账户提现)

ReportService

财务报表服务,提供财务数据统计。

位置apps/server/src/modules/shared/finance/report.service.ts

主要功能

  • 财务总览(系统总账户、平台账户、商家账户、用户账户统计)
  • 财务趋势(按日统计收入支出)
  • 资金守恒验证

数据库表结构

system_accounts(系统总账户表)

CREATE TABLE `system_accounts` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `account_name` VARCHAR(50) NOT NULL COMMENT '账户名称',
  `balance` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '可用余额',
  `total_income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计收入(用户实付总额)',
  `total_refund` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计退款',
  `total_withdrawn` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计提现',
  `version` INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_account_name` (`account_name`)
) COMMENT='系统总账户表';

system_transactions(系统总账户交易流水表)

CREATE TABLE `system_transactions` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `transaction_no` VARCHAR(64) NOT NULL COMMENT '交易流水号',
  `account_id` BIGINT UNSIGNED NOT NULL COMMENT '账户ID',
  `direction` ENUM('income','expense') NOT NULL COMMENT '交易方向',
  `amount` DECIMAL(12,2) NOT NULL COMMENT '交易金额',
  `balance_before` DECIMAL(12,2) NOT NULL COMMENT '交易前余额',
  `balance_after` DECIMAL(12,2) NOT NULL COMMENT '交易后余额',
  `transaction_type` VARCHAR(50) NOT NULL COMMENT '交易类型',
  `business_type` VARCHAR(50) NOT NULL COMMENT '业务类型',
  `business_id` BIGINT UNSIGNED NOT NULL COMMENT '业务ID',
  `business_no` VARCHAR(64) NOT NULL COMMENT '业务单号',
  `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_transaction_no` (`transaction_no`),
  KEY `idx_account_id` (`account_id`),
  KEY `idx_business` (`business_type`, `business_id`),
  KEY `idx_created_at` (`created_at`)
) COMMENT='系统总账户交易流水表';

platform_accounts(平台账户表)

CREATE TABLE `platform_accounts` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `account_name` VARCHAR(50) NOT NULL COMMENT '账户名称',
  `balance` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '可用余额',
  `total_income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计收入(服务费收入)',
  `total_expense` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计支出(邀请返现支出)',
  `version` INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_account_name` (`account_name`)
) COMMENT='平台账户表';

前端展示

1. 财务总览页面

位置apps/platform-admin/src/pages/finance/Dashboard.tsx

展示内容

  1. 系统总账户金额(突出显示)

    • 计算公式:用户实付 - 退款 - 提现
    • 资金守恒验证:= 商家账户余额 + 用户账户余额 + 平台净收益
  2. 平台净收益

    • 服务费收入 - 邀请返现支出
  3. 用户总余额

    • 所有用户账户余额总和
    • 用户账户数量
  4. 商家总余额

    • 所有商家账户余额总和
    • 商家账户数量
  5. 今日统计

    • 今日订单数
    • 今日收入
    • 今日支出
    • 今日净收益

2. 平台钱包页面

位置apps/platform-admin/src/pages/finance/PlatformWallet.tsx

功能特性

  • 钱包余额、可提现金额、冻结金额、服务费收入展示
  • 账户总收入、总支出、其他收入统计
  • 钱包详情查看
  • 申请提现功能(集成在页面内)

3. 平台交易记录

位置apps/platform-admin/src/pages/finance/PlatformTransactions.tsx

功能特性

  • 交易流水查询(按流水号、方向、类型、时间筛选)
  • 交易详情展示
  • 分页展示

4. 结算管理

位置apps/platform-admin/src/pages/finance/Settlements.tsx

功能特性

  • 结算单列表查询
  • 结算单详情查看
  • 预览周结算数据
  • 手动执行周结算

5. 商家提现审核

位置apps/platform-admin/src/pages/finance/Withdrawals.tsx

功能特性

  • 商家提现申请列表
  • 审核通过/拒绝
  • 确认打款

API接口

平台钱包接口

1. 查询平台账户

接口GET /api/admin/finance/platform-accounts
权限:平台管理员

响应示例

{
  "id": 1,
  "account_name": "主账户",
  "balance": 40.00,
  "frozen_balance": 0.00,
  "total_income": 1000.00,
  "total_expense": 960.00,
  "status": "active"
}

2. 平台申请提现

接口POST /api/admin/finance/platform-withdrawals
权限:平台管理员

请求参数

{
  "amount": 30.00,
  "bankName": "中国工商银行",
  "bankAccount": "6222021234567890123",
  "accountName": "某某科技有限公司",
  "remark": "提现备注"
}

结算管理接口

3. 预览周结算

接口GET /api/admin/finance/settlements/preview-weekly
权限:平台管理员

响应示例

{
  "periodStart": "2026-05-13",
  "periodEnd": "2026-05-19",
  "totalOrders": 45,
  "totalAmount": 35000.00,
  "totalServiceFee": 1750.00,
  "totalSettlementAmount": 33250.00,
  "merchants": [...]
}

4. 执行周结算

接口POST /api/admin/finance/settlements/execute-weekly
权限:平台管理员


扩展方案

未来增加其他收入

1. 数据库增加字段

ALTER TABLE platform_accounts 
ADD COLUMN total_ad_revenue DECIMAL(12,2) DEFAULT 0 COMMENT '累计广告收入',
ADD COLUMN total_membership_fee DECIMAL(12,2) DEFAULT 0 COMMENT '累计会员费收入',
ADD COLUMN total_other_income DECIMAL(12,2) DEFAULT 0 COMMENT '累计其他收入';

2. 后端增加方法

// 广告收入
async addPlatformAdRevenue(amount: number, ...): Promise<void> {
  account.balance += amount;
  account.total_income += amount;
  account.total_ad_revenue += amount;
}

// 会员费收入
async addPlatformMembershipFee(amount: number, ...): Promise<void> {
  account.balance += amount;
  account.total_income += amount;
  account.total_membership_fee += amount;
}

3. 前端增加展示

<Statistic
  title="广告收入"
  value={account.total_ad_revenue}
  precision={2}
  suffix="元"
/>

<Statistic
  title="会员费收入"
  value={account.total_membership_fee}
  precision={2}
  suffix="元"
/>

4. 调整可提现计算

// 方案1:继续使用各项收入累加
const withdrawableAmount = (
  total_service_fee + 
  total_ad_revenue + 
  total_membership_fee
) - frozen_balance;

// 方案2:直接使用钱包余额(推荐)
const withdrawableAmount = balance - frozen_balance;

推荐方案2,因为:

  • balance 已经包含了所有收入和支出
  • 不需要每次增加新收入类型都修改代码
  • 更简洁、更易维护

前端展示

安全保障

1. 数据库事务

所有涉及账户操作的方法都使用数据库事务,确保操作的原子性:

const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();

try {
  // 账户操作
  await queryRunner.commitTransaction();
} catch (error) {
  await queryRunner.rollbackTransaction();
  throw error;
} finally {
  await queryRunner.release();
}

2. 悲观锁

在查询账户时使用悲观锁,防止并发修改:

const account = await queryRunner.manager.findOne(SystemAccount, {
  where: { account_name: '系统总账户' },
  lock: { mode: 'pessimistic_write' },
});

3. 乐观锁

使用 version 字段实现乐观锁,检测并发冲突:

account.version += 1;
await queryRunner.manager.save(account);

4. 金额精度控制

所有金额计算都使用 Number() 转换和 toFixed(2) 保留两位小数:

const amountNum = Number(amount);
const balanceBefore = Number(account.balance);
const balanceAfter = parseFloat((balanceBefore + amountNum).toFixed(2));

5. 余额校验

在扣减余额前检查余额是否足够:

if (balanceBefore < amount) {
  throw new BadRequestException('账户余额不足');
}

6. 交易流水

所有账户操作都记录详细的交易流水,包括:

  • 交易流水号(唯一)
  • 交易前后余额
  • 交易类型和业务类型
  • 关联的业务ID和业务单号
  • 备注信息

测试验证

资金守恒验证

定期执行以下查询验证资金守恒:

-- 查询系统总账户余额
SELECT balance FROM system_accounts WHERE account_name = '系统总账户';

-- 查询商家账户余额总和
SELECT SUM(balance) FROM merchant_accounts;

-- 查询用户账户余额总和
SELECT SUM(balance) FROM user_accounts;

-- 查询平台账户余额
SELECT balance FROM platform_accounts WHERE account_name = '主账户';

-- 验证:系统总账户余额 = 商家账户余额 + 用户账户余额 + 平台账户余额

完整流程测试

  1. 订单支付测试

    • 创建订单并支付
    • 验证系统总账户余额增加
  2. 订单结算测试

    • 订单完成后触发结算
    • 验证商家账户余额增加
    • 验证平台账户余额增加(服务费)
    • 如果有邀请关系,验证用户账户余额增加(返现)
  3. 订单退款测试

    • 申请退款
    • 验证系统总账户退款金额增加
  4. 提现测试

    • 申请提现
    • 审核通过
    • 确认打款
    • 验证账户余额扣减
    • 验证系统总账户提现金额增加
  5. 资金守恒测试

    • 执行多个订单流程
    • 验证资金守恒公式始终成立

部署说明

数据库初始化

  1. 执行数据库迁移脚本:
# 重新初始化数据库(会清空所有数据)
mysql -u root -p < database/migrations/001_init_schema.sql
  1. 初始化系统总账户:
INSERT INTO system_accounts (account_name, balance, total_income, total_refund, total_withdrawn, status)
VALUES ('SYSTEM_MAIN', 0.00, 0.00, 0.00, 0.00, 'active');
  1. 初始化平台账户:
INSERT INTO platform_accounts (account_name, balance, frozen_balance, total_income, total_expense, status)
VALUES ('PLATFORM_MAIN', 0.00, 0.00, 0.00, 0.00, 'active');

或者直接执行种子数据脚本:

mysql -u root -p rent_platform < database/seeds/001_init_data.sql

服务启动

# 安装依赖
pnpm install

# 启动后端服务
cd apps/server
pnpm run start:dev

# 启动平台管理后台
cd apps/platform-admin
pnpm run dev

常见问题

Q1: 为什么要分系统总账户和平台账户?

A: 系统总账户记录的是平台内所有未提现的资金总额,用于验证资金守恒。平台账户记录的是平台的净收益(服务费 - 邀请返现),用于计算平台的实际盈利。两者职责不同,分开管理更清晰。

Q2: 订单支付时为什么只更新系统总账户,不更新商家账户?

A: 订单支付时资金进入平台,但还未分配给商家。只有订单完成(用户离店)后才进行结算,将资金分配给商家。这样可以防止用户退款时出现商家已收款的情况。

Q3: 邀请返现为什么要从平台账户扣减?

A: 邀请返现是平台的营销成本,应该从平台的收益中扣除。平台的净收益 = 服务费收入 - 邀请返现支出。

Q4: 如何确保资金安全?

A: 系统采用多重安全机制:

  • 数据库事务确保操作原子性
  • 悲观锁和乐观锁防止并发问题
  • 详细的交易流水记录
  • 资金守恒验证
  • 余额校验

Q5: 如果发现账户余额不对怎么办?

A:

  1. 查看交易流水,定位问题操作
  2. 检查是否有并发操作导致的问题
  3. 验证资金守恒公式是否成立
  4. 如果是数据错误,需要手动调整并记录原因

更新日志

2024-01-XX - 账户体系重构

重大变更

  • 新增系统总账户,记录平台内所有未提现的资金
  • 修改平台账户职责,只记录平台净收益
  • 修改订单支付逻辑,更新系统总账户
  • 修改订单结算逻辑,同时更新商家账户和平台账户
  • 修改邀请返现逻辑,从平台账户扣减
  • 修改退款逻辑,更新系统总账户
  • 修改提现逻辑,更新系统总账户
  • 修改财务报表,使用新的账户数据
  • 修改前端页面,展示新的账户结构

影响范围

  • 数据库表结构变更,需要重新初始化数据库
  • 所有涉及账户操作的代码都需要更新
  • 前端页面需要更新

升级步骤

  1. 备份现有数据库
  2. 执行新的数据库迁移脚本
  3. 更新后端代码
  4. 更新前端代码
  5. 重启服务
  6. 验证资金守恒

联系方式

如有问题,请联系开发团队。


相关文档


版本v3.0(合并版)
最后更新2024-01-XX
维护团队:开发团队