Files
ccdi/docs/plans/fullstack/2026-04-09-account-library-design.md

17 KiB
Raw Blame History

账户库管理设计方案

1. 背景与目标

当前系统在“信息维护”下已具备员工信息维护、员工亲属关系维护等基础档案能力,但尚未形成独立的“账户库管理”。现有员工表 ccdi_base_staff 与员工亲属关系表 ccdi_staff_fmy_relation 中均不承载完整账户信息,无法满足后续账户台账维护、手工补录、导入和账户分析展示的需要。

本次设计目标如下:

  • 在“信息维护”菜单下新增“账户库管理”
  • 支持维护员工本人账户与员工亲属账户
  • 账户静态档案与分析结果分表存储
  • 页面风格沿用现有维护页交互方式
  • 第一版仅考虑当前有效账户分析结果,不保留多版本分析历史

本次明确不做以下事项:

  • 不扩展朋友、同事、司机、秘书等非亲属关系
  • 不修改“员工亲属关系维护”现有业务命名
  • 不增加额外脱敏展示字段
  • 不展开后端实现设计

2. 设计原则

  • 主表只描述“谁持有了什么账户”
  • 分析表只描述“该账户的交易画像和风险等级”
  • 员工本人账户依附员工表
  • 亲属账户依附员工亲属关系表
  • 页面录入时允许在一个弹窗中同时维护主表和分析表信息
  • 第一版以人工维护为主,分析字段允许手工录入或后续导入覆盖

3. 数据模型

3.1 关系说明

  • 员工主表:ccdi_base_staff
  • 员工亲属关系表:ccdi_staff_fmy_relation
  • 账户主表:ccdi_account_info
  • 账户分析表:ccdi_account_analysis

关系约束如下:

  • 一个员工可有多个本人账户
  • 一个员工亲属关系记录可有多个账户
  • 一个账户仅归属于一个员工或一个亲属关系记录
  • 一个账户在第一版仅对应一条当前分析记录

3.2 归属规则

  • is_self_account = 1 时:
    • staff_id 必填
    • relation_id 为空
  • is_self_account = 0 时:
    • staff_id 必填
    • relation_id 必填
    • relation_id 对应的亲属记录应属于该 staff_id

4. 表结构设计

4.1 账户主表 ccdi_account_info

用途:存储账户静态档案、开户信息、归属关系和生效状态。

字段名 类型 必填 默认值 说明
id BIGINT 自增 主键
staff_id BIGINT - 员工ID对应 ccdi_base_staff.staff_id
relation_id BIGINT NULL 亲属关系ID对应 ccdi_staff_fmy_relation.id
account_no VARCHAR(200) - 账户号码,按业务要求加密存储
account_type VARCHAR(30) - BANK/SECURITIES/PAYMENT/OTHER
account_name VARCHAR(100) - 账户名称
open_bank VARCHAR(100) - 开户银行、证券公司或支付平台
bank_code VARCHAR(20) NULL 金融机构代码
currency CHAR(3) CNY 币种ISO 4217 标准
is_self_account BOOLEAN TRUE 是否本人账户
status INT 1 状态1-有效0-无效
effective_date DATE 当前日期 生效日期
invalid_date DATE NULL 失效日期
data_source VARCHAR(30) MANUAL 数据来源MANUAL、IMPORT、SYNC
remark VARCHAR(500) NULL 备注
create_by VARCHAR(64) - 创建人
create_time DATETIME 当前时间 创建时间
update_by VARCHAR(64) NULL 更新人
update_time DATETIME 当前时间 更新时间

说明:

  • relation_id 为空表示员工本人账户
  • relation_id 不为空表示员工亲属账户
  • 本次不增加账户号码 hash 字段与脱敏展示字段

4.2 账户分析表 ccdi_account_analysis

用途:存储账户交易画像、金额特征和风险等级。

字段名 类型 必填 默认值 说明
id BIGINT 自增 主键
account_id BIGINT - 账户ID对应 ccdi_account_info.id
analysis_months INT 6 统计月数
stat_start_date DATE NULL 统计开始日期
stat_end_date DATE NULL 统计结束日期
avg_month_txn_count INT 0 月均交易笔数
avg_month_txn_amount DECIMAL(18,2) 0.00 月均交易金额
txn_frequency_level VARCHAR(20) MEDIUM 交易频率LOW、MEDIUM、HIGH
debit_single_max_amount DECIMAL(18,2) NULL 借方单笔交易最高额
credit_single_max_amount DECIMAL(18,2) NULL 贷方单笔交易最高额
debit_daily_max_amount DECIMAL(18,2) NULL 借方日累计交易最高额
credit_daily_max_amount DECIMAL(18,2) NULL 贷方日累计交易最高额
txn_risk_level VARCHAR(10) MEDIUM 交易风险等级
remark VARCHAR(500) NULL 分析备注
create_by VARCHAR(64) - 创建人
create_time DATETIME 当前时间 创建时间
update_by VARCHAR(64) NULL 更新人
update_time DATETIME 当前时间 更新时间

说明:

  • 第一版以“一户一条当前分析记录”为目标
  • 后续如果需要保留历史分析版本,可新增 is_latestanalysis_batch_no 或改造唯一约束

5. 索引与约束建议

5.1 ccdi_account_info

  • 主键:PRIMARY KEY (id)
  • 索引:idx_staff_id (staff_id)
  • 索引:idx_relation_id (relation_id)
  • 索引:idx_account_type (account_type)
  • 索引:idx_open_bank (open_bank)
  • 索引:idx_is_self_account (is_self_account)
  • 索引:idx_status (status)

5.2 ccdi_account_analysis

  • 主键:PRIMARY KEY (id)
  • 唯一索引:uk_account_id (account_id)
  • 索引:idx_txn_risk_level (txn_risk_level)

5.3 校验规则

  • invalid_date 不得早于 effective_date
  • analysis_months 应大于 0
  • 金额字段不得为负数
  • 若账户为本人账户,则不允许选择亲属
  • 若账户为亲属账户,则必须选定亲属关系记录

6. DDL 草案

CREATE TABLE IF NOT EXISTS `ccdi_account_info` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `staff_id` BIGINT(20) NOT NULL COMMENT '员工ID',
  `relation_id` BIGINT(20) DEFAULT NULL COMMENT '员工亲属关系ID员工本人账户为空',
  `account_no` VARCHAR(200) NOT NULL COMMENT '账户号码(加密存储)',
  `account_type` VARCHAR(30) NOT NULL COMMENT '账户类型BANK/SECURITIES/PAYMENT/OTHER',
  `account_name` VARCHAR(100) NOT NULL COMMENT '账户名称',
  `open_bank` VARCHAR(100) NOT NULL COMMENT '开户银行/证券公司/支付平台',
  `bank_code` VARCHAR(20) DEFAULT NULL COMMENT '金融机构代码',
  `currency` CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种',
  `is_self_account` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否本人账户1-是 0-否',
  `status` INT(11) NOT NULL DEFAULT 1 COMMENT '状态1-有效 0-无效',
  `effective_date` DATE NOT NULL COMMENT '生效日期',
  `invalid_date` DATE DEFAULT NULL COMMENT '失效日期',
  `data_source` VARCHAR(30) NOT NULL DEFAULT 'MANUAL' COMMENT '数据来源',
  `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
  `create_by` VARCHAR(64) NOT NULL COMMENT '创建人',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_staff_id` (`staff_id`),
  KEY `idx_relation_id` (`relation_id`),
  KEY `idx_account_type` (`account_type`),
  KEY `idx_open_bank` (`open_bank`),
  KEY `idx_is_self_account` (`is_self_account`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账户主表';
CREATE TABLE IF NOT EXISTS `ccdi_account_analysis` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `account_id` BIGINT(20) NOT NULL COMMENT '账户ID',
  `analysis_months` INT(11) NOT NULL DEFAULT 6 COMMENT '统计月数',
  `stat_start_date` DATE DEFAULT NULL COMMENT '统计开始日期',
  `stat_end_date` DATE DEFAULT NULL COMMENT '统计结束日期',
  `avg_month_txn_count` INT(11) DEFAULT 0 COMMENT '月均交易笔数',
  `avg_month_txn_amount` DECIMAL(18,2) DEFAULT 0.00 COMMENT '月均交易金额',
  `txn_frequency_level` VARCHAR(20) DEFAULT 'MEDIUM' COMMENT '交易频率等级',
  `debit_single_max_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '借方单笔最高额',
  `credit_single_max_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '贷方单笔最高额',
  `debit_daily_max_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '借方日累计最高额',
  `credit_daily_max_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '贷方日累计最高额',
  `txn_risk_level` VARCHAR(10) DEFAULT 'MEDIUM' COMMENT '交易风险等级',
  `remark` VARCHAR(500) DEFAULT NULL COMMENT '分析备注',
  `create_by` VARCHAR(64) NOT NULL COMMENT '创建人',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_account_id` (`account_id`),
  KEY `idx_txn_risk_level` (`txn_risk_level`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账户分析表';

7. 页面原型设计

7.1 菜单位置

新增菜单:

  • 父级:信息维护
  • 名称:账户库管理
  • 建议顺序:放在“员工亲属关系维护”后、“招聘信息管理”前

7.2 列表页

查询区

  • 员工姓名
  • 归属类型:本人 / 亲属
  • 关系类型
  • 关系人姓名
  • 账户类型
  • 开户机构
  • 风险等级
  • 状态

操作区

  • 新增
  • 导入
  • 导出

表格字段

  • 员工姓名
  • 归属类型
  • 关系类型
  • 关系人姓名
  • 账户号码
  • 账户名称
  • 账户类型
  • 开户机构
  • 币种
  • 是否本人账户
  • 月均交易笔数
  • 月均交易金额
  • 交易频率等级
  • 交易风险等级
  • 生效日期
  • 状态
  • 创建时间
  • 操作

列表页低保真线框

+----------------------------------------------------------------------------------+
| 账户库管理                                                                       |
+----------------------------------------------------------------------------------+
| 员工姓名 [________] 归属类型 [本人/亲属] 关系类型 [____] 关系人姓名 [________]   |
| 账户类型 [____]    开户机构 [________]  风险等级 [____] 状态 [有效/无效]         |
| [搜索] [重置]                                                                   |
+----------------------------------------------------------------------------------+
| [新增] [导入] [导出]                                                             |
+----------------------------------------------------------------------------------+
| 员工姓名 | 归属类型 | 关系类型 | 关系人姓名 | 账号 | 账户名称 | 账户类型 | ...   |
|----------------------------------------------------------------------------------|
| 张三     | 本人     | -        | -          | 6222 | 工资卡   | BANK     | ...   |
| 张三     | 亲属     | 配偶     | 李四       | 6217 | 储蓄卡   | BANK     | ...   |
| ...                                                                              |
+----------------------------------------------------------------------------------+
| 分页                                                                             |
+----------------------------------------------------------------------------------+

7.3 新增/编辑弹窗

一、归属信息

  • 归属类型
  • 员工选择
  • 关系人选择
  • 关系类型
  • 是否本人账户

交互规则:

  • 归属类型为“本人”时,关系人选择和关系类型隐藏
  • 归属类型为“亲属”时,先选员工,再加载该员工亲属列表
  • 是否本人账户根据归属类型自动带出,只读显示

二、账户信息

  • 账户号码
  • 账户类型
  • 账户名称
  • 开户机构
  • 银行代码
  • 币种
  • 生效日期
  • 失效日期
  • 状态
  • 备注

三、分析信息

  • 统计月数
  • 统计开始日期
  • 统计结束日期
  • 月均交易笔数
  • 月均交易金额
  • 交易频率等级
  • 借方单笔最高额
  • 贷方单笔最高额
  • 借方日累计最高额
  • 贷方日累计最高额
  • 交易风险等级
  • 分析备注

弹窗低保真线框

+--------------------------------------------------------------+
| 新增账户                                               [X]   |
+--------------------------------------------------------------+
| 一、归属信息                                                |
| 归属类型   [本人/亲属]                                      |
| 员工       [请选择员工____________________]                  |
| 关系人     [请选择关系人__________________]                  |
| 关系类型   [自动带出______________________]                  |
| 是否本人   [是/否,只读]                                    |
+--------------------------------------------------------------+
| 二、账户信息                                                |
| 账户号码   [____________________________]                    |
| 账户类型   [BANK/SECURITIES/PAYMENT/OTHER]                  |
| 账户名称   [____________________________]                    |
| 开户机构   [____________________________]                    |
| 银行代码   [________________] 币种 [CNY]                    |
| 生效日期   [yyyy-MM-dd] 失效日期 [yyyy-MM-dd]               |
| 状态       [有效/无效]                                      |
| 备注       [____________________________________________]    |
+--------------------------------------------------------------+
| 三、分析信息                                                |
| 统计月数   [6]                                              |
| 开始日期   [yyyy-MM-dd] 结束日期 [yyyy-MM-dd]               |
| 月均笔数   [____]         月均金额 [__________]             |
| 频率等级   [LOW/MEDIUM/HIGH] 风险等级 [LOW/MEDIUM/HIGH]     |
| 借方单笔最高 [________]    贷方单笔最高 [________]          |
| 借方日累计最高 [________]  贷方日累计最高 [________]        |
| 分析备注   [____________________________________________]    |
+--------------------------------------------------------------+
|                                   [取消] [确定]             |
+--------------------------------------------------------------+

7.4 详情弹窗

详情页建议与新增/编辑弹窗结构一致,全部字段只读展示,避免维护两套信息布局。

8. 导入模板建议

建议导入模板字段如下:

  • 员工柜员号
  • 员工姓名
  • 归属类型
  • 关系人姓名
  • 关系类型
  • 账户号码
  • 账户类型
  • 账户名称
  • 开户机构
  • 银行代码
  • 币种
  • 生效日期
  • 失效日期
  • 统计月数
  • 月均交易笔数
  • 月均交易金额
  • 交易频率等级
  • 借方单笔最高额
  • 贷方单笔最高额
  • 借方日累计最高额
  • 贷方日累计最高额
  • 交易风险等级
  • 备注

导入校验建议:

  • 本人账户时,不允许填写关系人姓名
  • 亲属账户时,关系人姓名不能为空
  • 若员工不存在,则导入失败
  • 若亲属不存在,则导入失败

9. 菜单 SQL 草案

SET @parent_menu_id = (
  SELECT menu_id
  FROM sys_menu
  WHERE menu_name = '信息维护' AND parent_id = 0
  LIMIT 1
);

INSERT INTO sys_menu (
  menu_name, parent_id, order_num, path, component, is_frame, is_cache,
  menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark
) VALUES (
  '账户库管理', @parent_menu_id, 5, 'accountInfo', 'ccdiAccountInfo/index', 1, 0,
  'C', '0', '0', 'ccdi:accountInfo:list', 'money', 'admin', NOW(), '', NULL, '账户库管理菜单'
);

SET @menu_id = LAST_INSERT_ID();

INSERT INTO sys_menu (
  menu_name, parent_id, order_num, path, component, is_frame, is_cache,
  menu_type, visible, status, perms, icon, create_by, create_time, remark
) VALUES
('账户查询', @menu_id, 1, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:query', '#', 'admin', NOW(), ''),
('账户新增', @menu_id, 2, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:add', '#', 'admin', NOW(), ''),
('账户修改', @menu_id, 3, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:edit', '#', 'admin', NOW(), ''),
('账户删除', @menu_id, 4, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:remove', '#', 'admin', NOW(), ''),
('账户导入', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:import', '#', 'admin', NOW(), ''),
('账户导出', @menu_id, 6, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:export', '#', 'admin', NOW(), '');

10. 后续落地建议

如果本方案确认,可按以下顺序实施:

  1. 先建两张表并补菜单 SQL
  2. 再补前端列表页与弹窗原型
  3. 最后对接后端接口与导入导出

当前方案适合作为第一版基础模型,后续若需要接入自动打标或保留历史分析结果,可在 ccdi_account_analysis 上继续扩展,而不破坏 ccdi_account_info 主档结构。