# 账户库管理设计方案 ## 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_latest`、`analysis_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 草案 ```sql 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='账户主表'; ``` ```sql 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 列表页 #### 查询区 - 员工姓名 - 归属类型:本人 / 亲属 - 关系类型 - 关系人姓名 - 账户类型 - 开户机构 - 风险等级 - 状态 #### 操作区 - 新增 - 导入 - 导出 #### 表格字段 - 员工姓名 - 归属类型 - 关系类型 - 关系人姓名 - 账户号码 - 账户名称 - 账户类型 - 开户机构 - 币种 - 是否本人账户 - 月均交易笔数 - 月均交易金额 - 交易频率等级 - 交易风险等级 - 生效日期 - 状态 - 创建时间 - 操作 #### 列表页低保真线框 ```text +----------------------------------------------------------------------------------+ | 账户库管理 | +----------------------------------------------------------------------------------+ | 员工姓名 [________] 归属类型 [本人/亲属] 关系类型 [____] 关系人姓名 [________] | | 账户类型 [____] 开户机构 [________] 风险等级 [____] 状态 [有效/无效] | | [搜索] [重置] | +----------------------------------------------------------------------------------+ | [新增] [导入] [导出] | +----------------------------------------------------------------------------------+ | 员工姓名 | 归属类型 | 关系类型 | 关系人姓名 | 账号 | 账户名称 | 账户类型 | ... | |----------------------------------------------------------------------------------| | 张三 | 本人 | - | - | 6222 | 工资卡 | BANK | ... | | 张三 | 亲属 | 配偶 | 李四 | 6217 | 储蓄卡 | BANK | ... | | ... | +----------------------------------------------------------------------------------+ | 分页 | +----------------------------------------------------------------------------------+ ``` ### 7.3 新增/编辑弹窗 #### 一、归属信息 - 归属类型 - 员工选择 - 关系人选择 - 关系类型 - 是否本人账户 交互规则: - 归属类型为“本人”时,关系人选择和关系类型隐藏 - 归属类型为“亲属”时,先选员工,再加载该员工亲属列表 - 是否本人账户根据归属类型自动带出,只读显示 #### 二、账户信息 - 账户号码 - 账户类型 - 账户名称 - 开户机构 - 银行代码 - 币种 - 生效日期 - 失效日期 - 状态 - 备注 #### 三、分析信息 - 统计月数 - 统计开始日期 - 统计结束日期 - 月均交易笔数 - 月均交易金额 - 交易频率等级 - 借方单笔最高额 - 贷方单笔最高额 - 借方日累计最高额 - 贷方日累计最高额 - 交易风险等级 - 分析备注 #### 弹窗低保真线框 ```text +--------------------------------------------------------------+ | 新增账户 [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 草案 ```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` 主档结构。