发布于 

用户资金账户表设计

本文档记录在做项目资金账户模块时的设计思路,主要考虑如何在变动中保持用户资金账户余额的一致性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
-- 用户账户表
-- 余额、可用余额可通过其他字段计算,因此考虑不需要冗余保留
-- 余额 = 总收入 - 已提现金额
-- 可用余额 = 余额 - 冻结金额 = 总收入 - 已提现金额 - 冻结金额
drop table if exists partner_account;
CREATE TABLE `partner_account` (
`partner_id` bigint(20) NOT NULL COMMENT '用户id',
`total_income` decimal(10,2) DEFAULT '0.00' COMMENT '总收入(已确认收入汇总)',
`withdraw_amount` decimal(10,2) DEFAULT '0.00' COMMENT '已提现金额',
`to_withdraw_amount` decimal(10,2) DEFAULT '0.00' COMMENT '冻结金额(提现待确认金额)',
`to_income_amount` decimal(10,2) DEFAULT '0.00' COMMENT '充值待确认金额',
`uniq_hash` varchar(200) DEFAULT NULL COMMENT '交易校验值(总收入+提现金额+冻结金额+充值待确认金额+最后更新时间的哈希值)',
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`partner_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户账户表';

-- 用户资金变动申请表
CREATE TABLE `partner_account_apply` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`code` varchar(32) DEFAULT NULL COMMENT '唯一流水编号',
`partner_id` bigint(20) DEFAULT NULL COMMENT '关联用户id',
`seq_num` varchar(32) DEFAULT NULL COMMENT '收入流水号',
`debit_card_no` varchar(32) DEFAULT NULL COMMENT '提现的借记卡号',
`type` varchar(2) DEFAULT NULL COMMENT '交易流水类型$$$1-充值 2-提现',
`status` varchar(2) DEFAULT NULL COMMENT '流水状态$$$1-新建;2-审批通过;3-审批拒绝;4-客户取消',
`amount` decimal(10,2) DEFAULT NULL COMMENT '申请金额',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
PRIMARY KEY (`id`),
UNIQUE KEY `i_code` (`code`),
KEY `i_partner_id` (`partner_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户资金变动申请表';

-- 用户资金变动流水表
CREATE TABLE `partner_account_apply_journal` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`apply_id` bigint(20) NOT NULL COMMENT '关联申请表id',
`status` varchar(10) NOT NULL COMMENT '流水状态$$$1-新建;2-审批通过;3-审批拒绝;4-客户取消',
`pre_total_income` decimal(10,2) DEFAULT NULL COMMENT '操作前:总收入(累计已入账确认金额)',
`pre_withdraw_amount` decimal(10,2) DEFAULT NULL COMMENT '操作前:已提现金额',
`pre_to_withdraw_amount` decimal(10,2) DEFAULT NULL COMMENT '操作前:冻结金额,即累计提现待确认金额',
`pre_to_income_amount` decimal(10,2) DEFAULT NULL COMMENT '操作前:充值待确认金额',
`post_total_income` decimal(10,2) DEFAULT NULL COMMENT '操作后:总收入(累计已入账确认金额)',
`post_withdraw_amount` decimal(10,2) DEFAULT NULL COMMENT '操作后:已提现金额',
`post_to_withdraw_amount` decimal(10,2) DEFAULT NULL COMMENT '操作后:冻结金额,即累计提现待确认金额',
`post_to_income_amount` decimal(10,2) DEFAULT NULL COMMENT '操作后:充值待确认金额',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人,后台操作时为后台登录名,前端申请时为空',
`partner_id` bigint(20) DEFAULT NULL COMMENT '创建合伙人,后台操作时为空,前端申请时为合伙人id(考虑是否保留)',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `i_apply_id` (`apply_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户资金变动流水表';

...

业务规则

  1. 对账户表的所有操作,都需要创建或更新申请记录,并创建操作流水,且在一个事务内进行,表现如下:
  • 申请提现时,需创建提现申请(status=待审批),同步创建操作流水(提现申请-申请)并关联提现申请, 并更新账户信息冻结金额)(冻结操作)
  • 提现审批通过时,需更新提现申请(status=通过),同步创建操作流水(提现申请-确认)并关联提现申请,并更新账户信息(已提现金额,冻结金额)(解冻并提现操作)
  • 提现申请拒绝时,需更新提现申请(status=拒绝),同步创建操作流水(提现申请-拒绝)并关联提现申请,并更新账户信息(冻结金额)(解冻操作)
  • 充值时,需要创建充值申请(status=待审批),同步创建操作流水(充值申请-申请)并关联充值申请,并更新账户信息充值待确认金额
  • 充值确认时,需要更新充值申请(status=通过),同步创建操作流水(充值申请-确认)并关联充值申请,并更新账户信息(充值待确认金额,总收入)
  • 充值拒绝时,需要更新充值申请(status=拒绝),同步创建操作流水(充值申请-拒绝)并关联充值申请,并更新账户信息(充值待确认金额)
  1. 对账户表的所有操作,都需要在事务内进行,且对账户加锁;更新账户数据时,需要计算新的uniq_hash值,并判断原uniq_hash值是否正确;