From 19267be58d71ec1879a49d7d74e2105a66a3a334 Mon Sep 17 00:00:00 2001 From: oneao Date: Wed, 9 Sep 2026 22:40:13 +0800 Subject: [PATCH] 20260909224013 --- code/fms/FMS新系统核心表结构设计.md | 568 +++++++++--------- code/fms/demo.html | 360 ++++++++---- code/fms/demo2.html | 831 +++++++++++++++++++++++++++ code/fms/字段权限与用户个性化设计.md | 151 +---- 4 files changed, 1372 insertions(+), 538 deletions(-) create mode 100644 code/fms/demo2.html diff --git a/code/fms/FMS新系统核心表结构设计.md b/code/fms/FMS新系统核心表结构设计.md index dfe5002f..4f9685f7 100644 --- a/code/fms/FMS新系统核心表结构设计.md +++ b/code/fms/FMS新系统核心表结构设计.md @@ -1,49 +1,38 @@ # FMS 新系统核心表结构 -> 目标结构基于 2026-09-04 只读拉取的 `FMS-NEW` 数据库整理。 -> 平台配置使用字符串业务键;未来业务数据表使用 `bigint` 雪花 ID。 - -## 0. SQL 驱动与动态配置 - -本系统是 SQL 驱动的内部 ERP。能通过 SQL 完成的查询、关联、过滤、排序、分页、聚合、权限过滤和数据范围过滤,优先在 SQL 层完成,不在业务代码中加载大量数据后再处理。 - -- 模块、字段、查询条件、排序、字段权限和数据范围等规则,优先从本文件定义的配置表读取,由通用查询逻辑动态生成 SQL; -- 动态 SQL 的表名、字段名和操作符只能来自受控的模块元数据、字段定义和白名单,业务值使用参数传递; -- 配置驱动的动态 SQL 不等于保存任意 SQL 字符串。不得把未审查的前端字符串或整段 SQL 直接保存后执行; -- 固定 SQL 仅用于稳定且明确的特殊业务逻辑,且应保持通用,不为单个页面或单个用户复制一套查询接口; -- 前端权限控制只负责界面展示,模块操作、字段访问和数据范围必须在后端查询或写入 SQL 中落实;用户个性化只能调整布局,不能放宽权限。 - ## 1. 用户表 ```sql +-- 用户表 create table dbo.b_user ( - b_id varchar(50) not null primary key, -- 用户账号本身 - b_name nvarchar(100) null, - b_bz nvarchar(400) null, - b_password nvarchar(255) not null, - b_canuse tinyint not null default 1, - b_logintime tinyint not null default 0 + b_id varchar(50) not null primary key, -- 用户编码(业务键主键) + b_name nvarchar(100) null, -- 用户名 + b_bz nvarchar(400) null, -- 备注 + b_password nvarchar(255) not null, -- 密码 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_logintime tinyint not null default 0 -- 登录次数 ); ``` ## 2. 模块 ```sql +-- 模块配置表 create table dbo.s_module ( - b_id varchar(50) not null primary key, -- 模块编码本身,创建后不可修改 - b_parent_id varchar(50) null, - b_name nvarchar(200) not null, - b_i18n varchar(150) null, - b_module_type varchar(20) not null, - b_viewtable varchar(128) null, - b_savetable varchar(128) null, - b_keyfield varchar(50) null, - b_orderfield varchar(500) null, - b_delete_policy varchar(20) null, - b_canuse tinyint not null default 1, - b_xh int not null default 0, - b_bz nvarchar(2000) null, - b_edit_mode varchar(10) null + b_id varchar(50) not null primary key, -- 模块编码(业务键主键) + b_parent_id varchar(50) null, -- 父级模块编码,NULL 表示根节点 + b_name nvarchar(200) not null, -- 模块名称 + b_i18n varchar(150) null, -- 多语言资源键 + b_module_type varchar(20) not null, -- 模块类型 + b_viewtable varchar(128) null, -- 视图表名(列表查询主表) + b_savetable varchar(128) null, -- 保存表名(写入目标表) + b_keyfield varchar(50) null, -- 主键字段 + b_orderfield varchar(500) null, -- 排序字段 + b_delete_policy varchar(20) null, -- 删除策略 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_xh int not null default 0, -- 显示顺序 + b_bz nvarchar(2000) null, -- 备注 + b_edit_mode varchar(10) null -- 编辑模式 ); create index ix_s_module_parent @@ -58,42 +47,42 @@ create index ix_s_module_savetable ## 3. 字段和字段布局 -> 状态字段统一使用 `tinyint` 保存 0/1,由业务层负责校验取值。`b_canuse` 表示记录或配置是否启用、是否参与运行;`b_visible` 表示当前列表或编辑场景是否展示,二者语义不同,不互相替代。 - ```sql +-- 字段定义表 create table dbo.s_field ( - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_name nvarchar(200) not null, - b_i18n varchar(150) null, - b_type varchar(30) not null, - b_dbtype varchar(30) not null, - b_length int null, - b_precision int null, - b_scale int null, - b_nullable tinyint not null default 1, - b_default_value nvarchar(1000) null, - b_db_default nvarchar(1000) null, - b_writemode varchar(20) not null default 'direct', - b_options nvarchar(max) null, - b_canuse tinyint not null default 1, - b_xh int not null default 0, -- 字段定义顺序:模块「同步字段」时按查询视图列序(10 起步)重排 + b_module_id varchar(50) not null, -- 所属模块编码 + b_field varchar(50) not null, -- 字段名 + b_name nvarchar(200) not null, -- 字段名称 + b_i18n varchar(150) null, -- 多语言资源键 + b_type varchar(30) not null, -- 字段类型(业务类型) + b_dbtype varchar(30) not null, -- 数据库类型 + b_length int null, -- 长度 + b_precision int null, -- 精度 + b_scale int null, -- 小数位 + b_nullable tinyint not null default 1, -- 是否可空(0/1) + b_default_value nvarchar(1000) null, -- 默认值 + b_db_default nvarchar(1000) null, -- 数据库默认值 + b_writemode varchar(20) not null default 'direct', -- 写入模式 + b_options nvarchar(max) null, -- 选项(下拉等) + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_xh int not null default 0, -- 显示顺序(同步字段时按视图列序重排,10 起步) primary key (b_module_id, b_field) ); create index ix_s_field_module_order on dbo.s_field (b_module_id, b_xh, b_field); +-- 字段分组表 create table dbo.s_field_group ( - b_id varchar(50) not null, -- 分组编码本身,模块内唯一,创建后不可修改 - b_module_id varchar(50) not null, - b_parent_id varchar(50) null, -- 父分组编码,NULL 表示根分组 - b_title nvarchar(200) not null, - b_i18n varchar(150) null, - b_xh int not null default 0, - b_canuse tinyint not null default 1, - b_colspan int not null default 48, - b_layout_direction varchar(10) null default 'vertical', + b_id varchar(50) not null, -- 分组编码 + b_module_id varchar(50) not null, -- 所属模块编码 + b_parent_id varchar(50) null, -- 父级分组编码,NULL 表示根节点 + b_title nvarchar(200) not null, -- 分组标题 + b_i18n varchar(150) null, -- 多语言资源键 + b_xh int not null default 0, -- 显示顺序 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_colspan int not null default 48, -- 列跨度 + b_layout_direction varchar(10) null default 'vertical', -- 布局方向(vertical/horizontal) primary key (b_module_id, b_id) ); @@ -103,47 +92,50 @@ create index ix_s_field_group_parent create index ix_s_field_group_order on dbo.s_field_group (b_module_id, b_xh, b_id); +-- 列表视图字段配置表 create table dbo.s_field_view ( - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_group_id varchar(50) null, -- 引用同模块 s_field_group.b_id - b_visible tinyint not null default 1, - b_xh int not null default 0, - b_width int null, + b_module_id varchar(50) not null, -- 所属模块编码 + b_field varchar(50) not null, -- 字段名 + b_group_id varchar(50) null, -- 所属分组(同模块 s_field_group.b_id) + b_visible tinyint not null default 1, -- 是否展示(0/1) + b_xh int not null default 0, -- 显示顺序 + b_width int null, -- 列宽 primary key (b_module_id, b_field) ); create index ix_s_field_view_order on dbo.s_field_view (b_module_id, b_xh, b_field); +-- 编辑字段配置表 create table dbo.s_field_edit ( - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_group_id varchar(50) null, -- 引用同模块 s_field_group.b_id - b_visible tinyint not null default 1, - b_required tinyint not null default 0, - b_readonly tinyint not null default 0, - b_disabled tinyint not null default 0, - b_xh int not null default 0, - b_width int null, - b_placeholder nvarchar(400) null, - b_colspan int not null default 12, - b_height int null, + b_module_id varchar(50) not null, -- 所属模块编码 + b_field varchar(50) not null, -- 字段名 + b_group_id varchar(50) null, -- 所属分组(同模块 s_field_group.b_id) + b_visible tinyint not null default 1, -- 是否展示(0/1) + b_required tinyint not null default 0, -- 是否必填(0/1) + b_readonly tinyint not null default 0, -- 是否只读(0/1) + b_disabled tinyint not null default 0, -- 是否禁用(0/1) + b_xh int not null default 0, -- 显示顺序 + b_width int null, -- 宽度 + b_placeholder nvarchar(400) null, -- 占位提示 + b_colspan int not null default 12, -- 列跨度 + b_height int null, -- 高度 primary key (b_module_id, b_field) ); create index ix_s_field_edit_order on dbo.s_field_edit (b_module_id, b_xh, b_field); +-- 查询字段配置表 create table dbo.s_field_query ( - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_component varchar(30) null, - b_condition_no int not null default 1, - b_operator varchar(20) not null, - b_default_value nvarchar(1000) null, - b_canuse tinyint not null default 1, - b_xh int not null default 0, + b_module_id varchar(50) not null, -- 所属模块编码 + b_field varchar(50) not null, -- 字段名 + b_component varchar(30) null, -- 查询组件 + b_condition_no int not null default 1, -- 条件序号 + b_operator varchar(20) not null, -- 操作符 + b_default_value nvarchar(1000) null, -- 默认值 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_xh int not null default 0, -- 显示顺序 primary key (b_module_id, b_field, b_condition_no) ); @@ -153,31 +145,31 @@ create index ix_s_field_query_order ## 4. 用户个性化 -> 用户个性化只作用于列表布局和普通查询收起态,不改变模块级默认配置。权限过滤优先于个人偏好,个人偏好不能越过字段权限或字段 `b_canuse` 限制。 - ```sql +-- 用户字段偏好表 create table dbo.s_user_field_pref ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_mode varchar(10) not null, -- 'view' 查看列表 / 'edit' 可编辑列表 - b_visible tinyint not null default 1, - b_xh int not null default 0, - b_width int null, - b_updatedatetime datetime2 null, + b_user_id varchar(50) not null, -- 用户编码 + b_module_id varchar(50) not null, -- 模块编码 + b_field varchar(50) not null, -- 字段名 + b_mode varchar(10) not null, -- 模式(view / edit) + b_visible tinyint not null default 1, -- 是否展示(0/1) + b_xh int not null default 0, -- 显示顺序 + b_width int null, -- 列宽 + b_updatedatetime datetime2 null, -- 最后更新时间 primary key (b_user_id, b_module_id, b_field, b_mode) ); create index ix_s_user_field_pref_order on dbo.s_user_field_pref (b_user_id, b_module_id, b_mode, b_xh, b_field); +-- 用户查询字段偏好表 create table dbo.s_user_query_field_pref ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_quick_visible tinyint not null default 1, -- 普通查询收起态是否显示 - b_xh int not null default 0, -- 普通查询字段顺序 - b_updatedatetime datetime2 null, + b_user_id varchar(50) not null, -- 用户编码 + b_module_id varchar(50) not null, -- 模块编码 + b_field varchar(50) not null, -- 字段名 + b_quick_visible tinyint not null default 1, -- 普通查询收起态是否显示(0/1) + b_xh int not null default 0, -- 显示顺序 + b_updatedatetime datetime2 null, -- 最后更新时间 primary key (b_user_id, b_module_id, b_field) ); @@ -185,29 +177,22 @@ create index ix_s_user_query_field_pref_order on dbo.s_user_query_field_pref (b_user_id, b_module_id, b_xh, b_field); ``` -说明: - -- `s_user_field_pref` 的 `b_mode` 区分查看列表和可编辑列表两套个人布局; -- `s_user_query_field_pref` 不区分普通查询/高级查询模式,因为两者使用同一批查询字段; -- 查询偏好只影响普通查询收起态,展开态和高级查询仍展示所有有权限且启用的查询字段; -- 没有个人偏好时回落到对应的 `s_field_view` / `s_field_edit` / `s_field_query` 默认配置; -- “恢复默认”删除当前用户、当前模块对应的个人偏好记录。 - ## 5. 自动编码 ```sql +-- 自动编码表 create table dbo.s_autocode ( - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_prefix nvarchar(200) not null default N'', - b_dateformat varchar(30) not null default 'yyyyMM', - b_separator nvarchar(20) not null default N'-', - b_seqwidth int not null default 5, - b_resettype varchar(10) not null default 'month', - b_startvalue bigint not null default 1, - b_currentperiod varchar(8) null, - b_currentvalue bigint not null default 0, - b_canuse tinyint not null default 1, + b_module_id varchar(50) not null, -- 模块编码 + b_field varchar(50) not null, -- 字段名 + b_prefix nvarchar(200) not null default N'', -- 编码前缀 + b_dateformat varchar(30) not null default 'yyyyMM', -- 日期格式 + b_separator nvarchar(20) not null default N'-', -- 分隔符 + b_seqwidth int not null default 5, -- 序号宽度 + b_resettype varchar(10) not null default 'month', -- 重置类型 + b_startvalue bigint not null default 1, -- 起始值 + b_currentperiod varchar(8) null, -- 当前周期 + b_currentvalue bigint not null default 0, -- 当前值 + b_canuse tinyint not null default 1, -- 是否启用(0/1) primary key (b_module_id, b_field) ); ``` @@ -215,23 +200,24 @@ create table dbo.s_autocode ( ## 6. 模块关系 ```sql +-- 模块关系表 create table dbo.s_relation ( - b_module_id varchar(50) not null, - b_target_module_id varchar(50) not null, - b_relation_type varchar(20) not null, - b_field varchar(50) not null, - b_target_field varchar(50) not null, - b_foreign_side varchar(10) null, - b_junction_module_id varchar(50) null, - b_junction_field varchar(50) null, - b_junction_target_field varchar(50) null, - b_ownership varchar(20) not null default 'reference', - b_owner_side varchar(10) null, - b_delete_policy varchar(20) null, - b_order_module_id varchar(50) null, - b_order_field varchar(50) null, - b_canuse tinyint not null default 1, - b_xh int not null default 0, + b_module_id varchar(50) not null, -- 源模块编码 + b_target_module_id varchar(50) not null, -- 目标模块编码 + b_relation_type varchar(20) not null, -- 关系类型 + b_field varchar(50) not null, -- 源字段 + b_target_field varchar(50) not null, -- 目标字段 + b_foreign_side varchar(10) null, -- 外键侧 + b_junction_module_id varchar(50) null, -- 中间表模块编码 + b_junction_field varchar(50) null, -- 中间表字段 + b_junction_target_field varchar(50) null, -- 中间表目标字段 + b_ownership varchar(20) not null default 'reference', -- 归属关系 + b_owner_side varchar(10) null, -- 属主侧 + b_delete_policy varchar(20) null, -- 删除策略 + b_order_module_id varchar(50) null, -- 排序模块编码 + b_order_field varchar(50) null, -- 排序字段 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_xh int not null default 0, -- 显示顺序 primary key (b_module_id, b_field, b_target_module_id, b_target_field) ); @@ -245,17 +231,17 @@ create index ix_s_relation_target ## 7. 菜单 ```sql +-- 菜单表 create table dbo.s_menu ( - b_id varchar(50) not null primary key, -- 菜单编码本身 - b_parent_id varchar(50) null, - b_name nvarchar(200) not null, - b_i18n varchar(150) null, - b_menu_type varchar(20) not null, - b_route varchar(200) null, - b_module_id varchar(50) null, - b_icon varchar(50) null, - b_xh int not null default 0, - b_canuse tinyint not null default 1 + b_id varchar(50) not null primary key, -- 菜单编码(业务键主键) + b_parent_id varchar(50) null, -- 父级菜单编码,NULL 表示根节点 + b_name nvarchar(200) not null, -- 菜单名称 + b_i18n varchar(150) null, -- 多语言资源键 + b_menu_type varchar(20) not null, -- 菜单类型 + b_route varchar(200) null, -- 路由 + b_icon varchar(50) null, -- 图标 + b_xh int not null default 0, -- 显示顺序 + b_canuse tinyint not null default 1 -- 是否启用(0/1) ); create index ix_s_menu_parent @@ -264,71 +250,104 @@ create index ix_s_menu_parent create index ix_s_menu_order on dbo.s_menu (b_xh, b_id); -create index ix_s_menu_module - on dbo.s_menu (b_module_id); - create index ix_s_menu_route on dbo.s_menu (b_route, b_canuse, b_id); ``` ## 8. 权限 -> 权限直接授予用户,不引入角色继承。`s_power.b_id` 是权限编码本身(业务键即主键),格式 `类型.对象[.能力]`,例如 `menu.cw_fee`、`module.cw_fee`、`action.cw_fee.audit`;完整规范见《字段权限与用户个性化设计.md》「权限编码规范」。字段授权使用独立的字段访问策略表。 +权限定义与用户授权分开,但不增加菜单等级或权限计算中间表: + +- `s_power` 是权限点字典,定义系统中可以授予的权限。菜单入口权限使用 `menu.<菜单编码>.access`,模块权限使用 `module.<模块编码>.`;菜单权限仍然通过 `s_power` 定义,不另建菜单权限字典; +- `s_menu_module` 只描述一个业务页面使用哪些模块,不直接授予用户权限;页面与模块的父子授权关系由授权界面统一处理,不在关系表中增加额外的必需标记或权限等级。 +- `s_user_power` 保存用户直接拥有的权限记录,客户授权界面可以维护这张表;菜单页面只是按业务场景组织这些权限,不产生另一套授权来源; +- 同一个模块被多个菜单引用时,页面中展示的是同一个模块权限。模块权限记录只保存一份,撤销某个菜单入口不会自动删除该模块权限。 +- 授权界面按“菜单 → 页面模块 → 模块能力”展示父子层级,使用父子级联勾选和半选状态;级联只是配置交互,最终仍保存为各权限点对应的 `s_user_power` 记录。 ```sql +-- 菜单模块关联表 +create table dbo.s_menu_module ( + b_menu_id varchar(50) not null, -- 菜单编码,引用 s_menu.b_id + b_module_id varchar(50) not null, -- 模块编码,引用 s_module.b_id + b_xh int not null default 0, -- 页面内模块顺序 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + primary key (b_menu_id, b_module_id) +); + +create index IX_s_menu_module_module + on dbo.s_menu_module (b_module_id, b_canuse, b_menu_id); +``` + +```sql +-- 权限表 create table dbo.s_power ( - b_id varchar(100) not null, -- 权限编码即主键:menu.cw_fee / module.cw_fee / action.cw_fee.audit - b_name nvarchar(200) not null, - b_i18n varchar(150) null, - b_power_type varchar(20) not null, -- page/menu/module/action/report - b_owner_type varchar(20) not null, -- 归属对象类型:page/menu/module/report;action 时为所属模块或页面 - b_owner_id varchar(50) not null, -- 归属对象编码:菜单/模块/页面/报表编码 - b_capability varchar(30) null, -- action 的操作或动作编码:create/update/delete/export/audit...;入口类为 null - b_operation varchar(30) null, -- 兼容列:access/execute,由 b_power_type 派生 - b_canuse tinyint not null default 1, - b_xh int not null default 0, + b_id varchar(100) not null, -- 权限编码即主键 + b_name nvarchar(200) not null, -- 权限名称 + b_i18n varchar(150) null, -- 多语言资源键 + b_power_type varchar(20) not null, -- 权限类型(page / menu / module / action / report) + b_owner_type varchar(20) not null, -- 归属类型(menu / module) + b_owner_id varchar(50) not null, -- 归属对象编码 + b_operation varchar(30) not null, -- 权限操作(access / read / create / update / delete / export / audit...) + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_xh int not null default 0, -- 显示顺序 primary key (b_id) ); create index ix_s_power_owner - on dbo.s_power (b_power_type, b_owner_type, b_owner_id, b_capability, b_canuse); + on dbo.s_power (b_power_type, b_owner_type, b_owner_id, b_operation, b_canuse); +``` +```sql +-- 用户权限表 create table dbo.s_user_power ( - b_user_id varchar(50) not null, - b_power_id varchar(100) not null, -- s_power.b_id,即权限编码 - b_canuse tinyint not null default 1, - b_updatedatetime datetime2 null, + b_user_id varchar(50) not null, -- 用户编码 + b_power_id varchar(100) not null, -- 权限编码(s_power.b_id) + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_updatedatetime datetime2 null, -- 最后更新时间 primary key (b_user_id, b_power_id) ); create index ix_s_user_power_user on dbo.s_user_power (b_user_id, b_canuse, b_power_id); +``` +`s_user_power` 的授权约定: + +- 菜单入口权限由 `s_power` 定义为 `menu.<菜单编码>.access`,授权时直接写入对应用户的 `s_user_power`; +- 模块查看、新增、修改、删除、导出及业务动作同样由 `s_power` 定义,授权时直接写入对应用户的 `s_user_power`; +- 客户界面可以在菜单页面下同时勾选入口权限和页面所用模块的权限,但保存的仍是同一张 `s_user_power` 表; +- 页面只是配置展示层,后端执行时按权限编码和 `s_menu_module` 校验当前菜单使用的模块;角色表暂不在本阶段引入。 + +```sql +-- 用户字段权限表 create table dbo.s_user_field_permission ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_field varchar(128) not null, - b_access_mode varchar(10) not null, -- hidden / view / edit - b_allow_query tinyint not null default 0, - b_allow_export tinyint not null default 0, - b_canuse tinyint not null default 1, - b_updatedatetime datetime2 null, + b_user_id varchar(50) not null, -- 用户编码 + b_module_id varchar(50) not null, -- 模块编码 + b_field varchar(128) not null, -- 字段名 + b_access_mode varchar(10) not null, -- 访问模式(hidden / view / edit) + b_allow_query tinyint not null default 0, -- 是否允许查询(0/1) + b_allow_export tinyint not null default 0, -- 是否允许导出(0/1) + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_updatedatetime datetime2 null, -- 最后更新时间 primary key (b_user_id, b_module_id, b_field) ); create index ix_s_user_field_permission_module on dbo.s_user_field_permission (b_user_id, b_module_id, b_canuse, b_field); +``` +```sql +-- 用户数据范围表 create table dbo.s_user_data_scope ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_operation varchar(30) not null, -- * / read / create / update / delete / export;* 表示模块默认范围 - b_scope_level varchar(10) not null default 'default', -- default / override - b_scope_no int not null default 1, - b_scope_type varchar(30) not null, -- own / department / department_tree / all / custom - b_scope_field varchar(50) null, -- 业务数据中的归属用户/部门字段 - b_scope_value varchar(100) null, -- custom 时每个用户/部门值一行 - b_updatedatetime datetime2 null, + b_user_id varchar(50) not null, -- 用户编码 + b_module_id varchar(50) not null, -- 模块编码 + b_operation varchar(30) not null, -- 操作(* / read / create / update / delete / export) + b_scope_level varchar(10) not null default 'default', -- 范围级别(default / override) + b_scope_no int not null default 1, -- 范围序号 + b_scope_type varchar(30) not null, -- 范围类型(own / department / department_tree / all / custom) + b_scope_field varchar(50) null, -- 业务数据中的归属用户/部门字段 + b_scope_value varchar(100) null, -- custom 时每个用户/部门值一行 + b_updatedatetime datetime2 null, -- 最后更新时间 primary key (b_user_id, b_module_id, b_operation, b_scope_level, b_scope_no), constraint ck_s_user_data_scope_level check (b_scope_level in ('default','override')), constraint ck_s_user_data_scope_operation check ( @@ -341,51 +360,27 @@ create index ix_s_user_data_scope_module on dbo.s_user_data_scope (b_user_id, b_module_id, b_operation, b_scope_level, b_scope_type); ``` -权限点约定: - -- `page.<页面编码>` / `menu.<菜单编码>` / `report.<报表编码>`:入口访问权限,报表列表中的每个报表可作为一个资源; -- `module.<模块编码>`:模块访问(≈ read,能否查看该模块数据); -- `action.<模块编码>.<操作或动作>`:数据操作(`create` / `update` / `delete` / `export`)与业务动作(`audit` / `settle` 等)统一为动作权限; -- `s_user_field_permission`:字段 `hidden/view/edit` 访问级别,以及独立的查询/导出能力; -- `b_power_type` 和 `b_capability` 是可扩展编码,新增资源类型不新增权限表,但需要补充权限定义和前端/后端校验规则; -- 动作必须带所属模块命名空间,例如 `action.cw_fee.audit`,不得使用裸 `action.audit`;**动作归属模块而非菜单**,避免同一个动作在不同菜单下被重复配置。 - -权限计算约定: - -- 入口权限默认拒绝:`page.*`、`menu.*`、`report.*` 与 `action.*` 必须存在有效的 `s_user_power` 授权记录;停用的权限点或授权记录不生效; -- 模块操作 `action.<模块编码>.<操作>` 在没有授权记录时**默认放行还是默认拒绝尚未最终确定**,见《字段权限与用户个性化设计.md》「待确认事项」第 1 条;`s_power` 权限点或用户授权记录存在 `b_canuse = 0` 时视为明确禁用; -- 字段没有有效用户策略记录时不增加限制,按 `s_field`、`s_field_view`、`s_field_edit`、`s_field_query` 等模块默认配置执行;有效的 `s_user_field_permission` 只能收紧权限;`hidden` 表示不可见,`view` 表示可见只读,`edit` 表示可见可编辑; -- `hidden` 字段不可查询、不可导出;`b_allow_query` / `b_allow_export` 不能突破字段访问级别; -- 模块数据操作权限与数据范围同时生效:先判断操作权限,再按 `s_user_data_scope` 限制数据行;数据范围没有配置时视为 `all`; -- 数据范围优先使用当前操作的 `override`,没有 `override` 时使用 `operation = '*'` 的 `default`;同一层级的多条范围按 OR 合并; -- `read`、`export`、`update`、`delete` 在 SQL 行条件中应用数据范围;`create` 在写入前校验新增数据是否符合数据范围; -- 菜单/页面/报表访问权限只控制入口和访问,不能替代模块、字段或数据范围权限。 - ## 9. 多语言 ```sql --- b_i18n / b_key 保存完整资源键,不追加 .name 或 .title 后缀: --- s_module.b_i18n = module. --- s_field.b_i18n = field.. --- s_field_group.b_i18n = field_group.. --- s_menu.b_i18n = menu. - +-- 多语言类型表 create table dbo.s_i18n_type ( - b_id varchar(20) not null primary key, -- 语言编码本身 - b_name nvarchar(200) not null, - b_canuse tinyint not null default 1, - b_default tinyint not null default 0, - b_xh int not null default 0 + b_id varchar(20) not null primary key, -- 类型编码 + b_name nvarchar(200) not null, -- 类型名称 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_default tinyint not null default 0, -- 是否默认(0/1) + b_xh int not null default 0 -- 显示顺序 ); +-- 多语言资源表 create table dbo.s_i18n ( - b_id varchar(200) not null primary key, -- b_key + ':' + b_locale - b_key varchar(150) not null, - b_locale varchar(20) not null, - b_value nvarchar(1000) not null, - b_i18ntype varchar(20) null, - b_canuse tinyint not null default 1, - b_module_id varchar(50) null, + b_id varchar(200) not null primary key, -- 资源编码(b_key + ':' + b_locale) + b_key varchar(150) not null, -- 资源键 + b_locale varchar(20) not null, -- 语言区域 + b_value nvarchar(1000) not null, -- 值 + b_i18ntype varchar(20) null, -- 多语言类型 + b_canuse tinyint not null default 1, -- 是否启用(0/1) + b_module_id varchar(50) null, -- 模块编码 unique (b_key, b_locale) ); @@ -398,81 +393,83 @@ create index ix_s_i18n_locale ## 10. 日志 -> 日志主键由业务层统一生成 UUIDv7。UUID 主键使用非聚集索引;技术、登录、审计日志按发生时间建立聚集索引,审计字段明细按审计事件建立聚集索引。日志顺序以 `b_occurdatetime` 为准,不依赖 UUID 排序。 - ```sql +-- 技术日志表 create table dbo.s_log_technical ( - b_id uniqueidentifier not null, -- 业务层生成的 UUIDv7 - b_user_id varchar(50) null, -- 稳定用户/账号标识;未认证请求时为 NULL - b_sourcetype varchar(20) null, - b_loglevel varchar(16) not null, - b_logcategory varchar(64) null, - b_operation varchar(100) null, - b_module_id varchar(50) null, - b_request_id varchar(64) null, - b_trace_id varchar(64) null, - b_server_node varchar(128) null, - b_duration_ms bigint null, - b_result_code varchar(50) null, - b_error_code varchar(50) null, - b_error_message nvarchar(4000) null, - b_exception_text nvarchar(max) null, - b_context_text nvarchar(max) null, - b_occurdatetime datetime2 default sysutcdatetime(), + b_id uniqueidentifier not null, -- 日志ID(UUIDv7) + b_user_id varchar(50) null, -- 用户编码(未认证请求时为 NULL) + b_sourcetype varchar(20) null, -- 来源类型 + b_loglevel varchar(16) not null, -- 日志级别 + b_logcategory varchar(64) null, -- 日志分类 + b_operation varchar(100) null, -- 操作 + b_module_id varchar(50) null, -- 模块编码 + b_request_id varchar(64) null, -- 请求ID + b_trace_id varchar(64) null, -- 链路ID + b_server_node varchar(128) null, -- 服务器节点 + b_duration_ms bigint null, -- 耗时(毫秒) + b_result_code varchar(50) null, -- 结果码 + b_error_code varchar(50) null, -- 错误码 + b_error_message nvarchar(4000) null, -- 错误信息 + b_exception_text nvarchar(max) null, -- 异常文本 + b_context_text nvarchar(max) null, -- 上下文文本 + b_occurdatetime datetime2 default sysutcdatetime(), -- 发生时间 constraint pk_s_log_technical primary key nonclustered (b_id) ); +-- 登录日志表 create table dbo.s_log_login ( - b_id uniqueidentifier not null, -- 业务层生成的 UUIDv7 - b_user_id varchar(50) null, -- 当前系统中账号即用户稳定标识;登录失败且账号不存在时为 NULL - b_login_type varchar(20) not null, - b_login_result tinyint not null default 0, - b_fail_reason nvarchar(400) null, - b_ip varchar(50) null, - b_ip_location nvarchar(400) null, - b_browser varchar(100) null, - b_browser_version varchar(50) null, - b_os varchar(100) null, - b_os_version varchar(50) null, - b_device_type varchar(20) null, - b_user_agent nvarchar(max) null, - b_session_id varchar(50) null, - b_request_id varchar(64) null, - b_trace_id varchar(64) null, - b_occurdatetime datetime2 default sysutcdatetime(), + b_id uniqueidentifier not null, -- 日志ID(UUIDv7) + b_user_id varchar(50) null, -- 用户编码(账号不存在时为 NULL) + b_login_type varchar(20) not null, -- 登录类型 + b_login_result tinyint not null default 0, -- 登录结果(0/1) + b_fail_reason nvarchar(400) null, -- 失败原因 + b_ip varchar(50) null, -- IP + b_ip_location nvarchar(400) null, -- IP 归属地 + b_browser varchar(100) null, -- 浏览器 + b_browser_version varchar(50) null, -- 浏览器版本 + b_os varchar(100) null, -- 操作系统 + b_os_version varchar(50) null, -- 系统版本 + b_device_type varchar(20) null, -- 设备类型 + b_user_agent nvarchar(max) null, -- UserAgent + b_session_id varchar(50) null, -- 会话ID + b_request_id varchar(64) null, -- 请求ID + b_trace_id varchar(64) null, -- 链路ID + b_occurdatetime datetime2 default sysutcdatetime(), -- 发生时间 constraint pk_s_log_login primary key nonclustered (b_id) ); +-- 审计日志表 create table dbo.s_log_audit ( - b_id uniqueidentifier not null, -- 业务层生成的 UUIDv7 - b_event_code varchar(50) not null, - b_module_id varchar(50) null, - b_data_id varchar(50) null, - b_business_no varchar(50) null, - b_operation varchar(100) null, - b_operator_id varchar(50) null, - b_operator_name nvarchar(200) null, - b_source_type varchar(20) not null default 'user', - b_visibility varchar(20) not null default 'internal', - b_request_id varchar(64) null, - b_trace_id varchar(64) null, - b_payload_text nvarchar(max) null, - b_occurdatetime datetime2 default sysutcdatetime(), + b_id uniqueidentifier not null, -- 日志ID(UUIDv7) + b_event_code varchar(50) not null, -- 事件编码 + b_module_id varchar(50) null, -- 模块编码 + b_data_id varchar(50) null, -- 数据ID + b_business_no varchar(50) null, -- 业务单号 + b_operation varchar(100) null, -- 操作 + b_operator_id varchar(50) null, -- 操作人ID + b_operator_name nvarchar(200) null, -- 操作人名称 + b_source_type varchar(20) not null default 'user', -- 来源类型 + b_visibility varchar(20) not null default 'internal', -- 可见性 + b_request_id varchar(64) null, -- 请求ID + b_trace_id varchar(64) null, -- 链路ID + b_payload_text nvarchar(max) null, -- 载荷文本 + b_occurdatetime datetime2 default sysutcdatetime(), -- 发生时间 constraint pk_s_log_audit primary key nonclustered (b_id) ); +-- 审计字段明细表 create table dbo.s_log_audit_field ( - b_id uniqueidentifier not null, -- 业务层生成的 UUIDv7 - b_event_id uniqueidentifier not null, - b_module_id varchar(50) null, - b_data_id varchar(50) null, - b_field varchar(50) not null, - b_field_label nvarchar(200) null, - b_before_value nvarchar(max) null, - b_after_value nvarchar(max) null, - b_before_display nvarchar(1000) null, - b_after_display nvarchar(1000) null, - b_visibility varchar(20) not null default 'internal', + b_id uniqueidentifier not null, -- 日志ID(UUIDv7) + b_event_id uniqueidentifier not null, -- 审计事件ID + b_module_id varchar(50) null, -- 模块编码 + b_data_id varchar(50) null, -- 数据ID + b_field varchar(50) not null, -- 字段名 + b_field_label nvarchar(200) null, -- 字段标签 + b_before_value nvarchar(max) null, -- 变更前值 + b_after_value nvarchar(max) null, -- 变更后值 + b_before_display nvarchar(1000) null, -- 变更前显示值 + b_after_display nvarchar(1000) null, -- 变更后显示值 + b_visibility varchar(20) not null default 'internal', -- 可见性 constraint pk_s_log_audit_field primary key nonclustered (b_id) ); @@ -501,9 +498,10 @@ create index ix_s_log_audit_module ## 11. 业务表主键约定 ```sql +-- 业务表示例 create table dbo.b_example ( - b_id bigint not null primary key, -- 应用层雪花 ID - b_inputuser_id varchar(50) null, -- 引用 b_user.b_id - b_inputdatetime datetime2 default sysutcdatetime() + b_id bigint not null primary key, -- 主键(应用层雪花 ID) + b_inputuser_id varchar(50) null, -- 录入用户ID + b_inputdatetime datetime2 default sysutcdatetime() -- 录入时间 ); ``` diff --git a/code/fms/demo.html b/code/fms/demo.html index 5c8ba71c..3dd21a63 100644 --- a/code/fms/demo.html +++ b/code/fms/demo.html @@ -1,129 +1,269 @@ - - - FMS 权限中心 · 功能实例授权 + + + FMS 权限分配原型 + - -
-
-
-
- F -
FMS 权限中心
功能实例授权 · 一客户一库
+ +
+
+
+
+
F
+
+
FMS 权限中心
+
岗位授权 · 菜单化配置,模块化执行
+
+
+ + +
+ + + +
+
IT
+ +
+
- -
系统管理员
DEMO-FWD
IT
-
-
+ -
-
-
授权对象
- -
未授权 = 拒绝 · 功能权限独立生效
-
- -
- - -
-
-

{{ currentFeature.name }}

{{ typeName(currentFeature.type) }}
{{ currentFeature.code }}
{{ currentUser.name }} · 当前授权
模板:{{ currentFeature.template }}
-
页面内功能
-
使用模块
{{ currentFeature.modules.join(' · ') || '无' }}
所属功能
{{ currentFeature.parent || '顶层功能' }}
授权原则
未勾选即不可用
-
-
模块默认能力
同一模块只配置一次,所有功能默认继承
{{ module }}全局默认
该功能不直接读取业务数据
-
本功能例外
仅能收紧模块默认能力
{{ module }}禁止本场景操作
-
功能专属动作
审核、核销等动作单独授权
-
+
+ + 未授权 = 拒绝 · 个人设置不能扩大岗位权限
-
字段与数据范围
仍按技术模块配置,个人设置只能收紧
{{ module }}
字段策略:跟随模块默认
数据范围:全部数据
该功能不直接读取业务数据
- -
- +
+
岗位角色
5
+
当前岗位成员
12
+
已配置业务菜单
6
+
待保存变更
0
+
-
IT CONFIGURATION

功能实例与权限生成

技术人员维护业务功能、公共模板和模块依赖,客户只负责授权。

功能实例
{{ features.length }}
公共模板
{{ templateCount }}
权限点
{{ allPowers.length }}
功能实例清单
功能入口与模块默认能力分层维护
功能类型公共模板使用模块功能权限
{{ feature.name }}
{{ feature.code }}
{{ typeName(feature.type) }}{{ feature.template }}{{ module }}无{{ powersFor(feature).length }}
技术配置详情
{{ configFeature.code }}
功能名称
{{ configFeature.name }}
模板
{{ configFeature.template }}
模块白名单
{{ module }}
无数据模块
自动生成权限
{{ power.code }}{{ capabilityName(power.capability) }}
- +
+ - - +
+
+
+
+

费用会计

已启用
+
负责费用录入、核对和结算·12 名成员·主岗位
+
+
+
+
+
+
业务菜单权限
权限等级会自动展开为模块动作;“自定义”仅在特殊场景使用
+
+ + +
+
+ + +
+ + + + + diff --git a/code/fms/demo2.html b/code/fms/demo2.html new file mode 100644 index 00000000..a83d07fb --- /dev/null +++ b/code/fms/demo2.html @@ -0,0 +1,831 @@ + + + + + +FMS 权限分配 · 交互原型 + + + + +
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+ +
+ +
+
+
+ 权限配置树 + 菜单 → 模块 → { 操作 · 敏感信息 · 数据范围 } +
+
+
+ + +
+ + + + diff --git a/code/fms/字段权限与用户个性化设计.md b/code/fms/字段权限与用户个性化设计.md index 6413e8b4..b1da358c 100644 --- a/code/fms/字段权限与用户个性化设计.md +++ b/code/fms/字段权限与用户个性化设计.md @@ -113,24 +113,12 @@ ## 1. 表结构 +> 权限相关表的完整 DDL、索引与业务层约束统一维护在《FMS新系统核心表结构设计.md》「8. 权限」;用户个性化偏好表见同文档「4. 用户个性化」。本章只保留设计说明与计算规则。 + ### 1.1 s_menu_module(菜单-模块关系表) 菜单页面与业务模块是多对多关系。菜单记录既表示导航入口,也表示对应的逻辑页面;Vue 路由和公共组件只作为技术实现,不参与权限标识。 -```sql -create table dbo.s_menu_module ( - b_menu_id varchar(100) not null, - b_module_id varchar(50) not null, - b_main bit not null default 0, - b_xh int not null default 0, - b_canuse tinyint not null default 1, - primary key (b_menu_code, b_module_id) -); - -create index IX_s_menu_module_module - on dbo.s_menu_module (b_module_id, b_canuse, b_menu_code); -``` - 业务层约束: - `b_menu_code`、`b_module_id` 必须引用已启用的菜单和模块; @@ -141,114 +129,19 @@ create index IX_s_menu_module_module ### 1.2 s_power(权限定义表) -```sql -create table dbo.s_power ( - b_id varchar(100) not null, -- menu.cw_fee_list.access / module.cw_fee.access / action.cw_fee.audit - b_name nvarchar(200) not null, - b_i18n varchar(150) null, - b_power_type varchar(20) not null, -- menu/module/action - b_owner_type varchar(20) not null, -- menu / module - b_owner_id varchar(50) not null, -- 菜单或模块编码 - b_capability varchar(30) null, -- action 的操作或动作编码;menu/module 为 access - b_operation varchar(30) null, -- 兼容列:access/execute,由 b_power_type 派生,后续可移除 - b_canuse tinyint not null default 1, - b_xh int not null default 0, - constraint PK_s_power primary key (b_id) -); - -create index IX_s_power_owner - on dbo.s_power (b_power_type, b_owner_type, b_owner_id, b_capability, b_canuse); -``` - -业务层约束(数据库不建 check 约束,由业务层校验): - -- `b_id` 由 `类型.对象[.能力]` 规则生成(见「权限编码规范」),**生成后不可编辑**,变更时删除重建; -- `b_power_type` 只能取 `menu / module / action`; -- `menu` 类型编码为 `menu.<菜单编码>.access`,`b_owner_type = 'menu'`,`b_capability = 'access'`,`b_operation = 'access'`; -- `module` 类型编码为 `module.<模块编码>.access`,`b_owner_type = 'module'`,`b_capability = 'access'`,`b_operation = 'access'`; -- `action` 类型 `b_owner_type` 固定为 `module`,`b_owner_id` 和 `b_capability` 必填,`b_operation` 固定为 `execute`; -- **动作归属模块、不归属菜单**:同一个模块动作只配置一次;页面是否允许使用该动作由 `s_menu_module.b_allow_*` 限制; -- `b_id` 与 `(b_power_type, b_owner_type, b_owner_id, b_capability)` 一一对应,新建前先按组合查重。 - -> 与现有库(FMS-NEW)的差异:现有 `s_power` 已采用 `b_id varchar(50)` 编码主键,并含 `b_resource`、`b_module_id`、`b_operation` 列。迁移时把 `b_id` 放宽到 `varchar(100)`,补 `b_owner_type` / `b_owner_id` / `b_capability` 三列;兼容列可保留,但新代码统一按上述权限编码和归属规则读写。 +定义见《FMS新系统核心表结构设计.md》「8. 权限」。 ### 1.3 s_user_power(用户权限授权表) -```sql -create table dbo.s_user_power ( - b_user_id varchar(50) not null, - b_power_id varchar(100) not null, -- 引用 s_power.b_id,即权限编码:menu.cw_fee / action.cw_fee.audit - b_canuse tinyint not null default 1, - b_updatedatetime datetime2 null, - constraint PK_s_user_power primary key (b_user_id, b_power_id) -); - -create index IX_s_user_power_user - on dbo.s_user_power (b_user_id, b_canuse, b_power_id); -``` - -业务层约束: - -- `b_power_id` 存权限**编码**而非内部 ID,可直接阅读与按前缀查询,判断时无需 join `s_power`; -- 统一采用默认拒绝策略:只保存 `b_canuse = 1` 的授权记录,没有记录即无权限; -- 权限点本身 `b_canuse = 0` 时,所有用户的该权限一律不生效。 +定义见《FMS新系统核心表结构设计.md》「8. 权限」。 ### 1.4 s_user_field_permission(用户字段访问策略表) -```sql -create table dbo.s_user_field_permission ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_access_mode varchar(10) not null, -- hidden / view / edit - b_allow_query tinyint not null default 0, - b_allow_export tinyint not null default 0, - b_canuse tinyint not null default 1, - b_updatedatetime datetime2 null, - constraint PK_s_user_field_permission - primary key (b_user_id, b_module_id, b_field) -); - -create index IX_s_user_field_permission_module - on dbo.s_user_field_permission (b_user_id, b_module_id, b_canuse, b_field); -``` - -业务层约束(数据库不建 check 约束,由业务层校验): - -- `b_access_mode` 只能取 `hidden / view / edit`; -- `b_access_mode = 'hidden'` 时,`b_allow_query` 和 `b_allow_export` 必须同时为 `0`; -- 没有 `b_canuse = 1` 的有效记录时,该字段按模块字段默认配置执行,不视为 `hidden`。 +定义见《FMS新系统核心表结构设计.md》「8. 权限」。 ### 1.5 s_user_data_scope(用户数据范围授权表) -```sql -create table dbo.s_user_data_scope ( - b_user_id varchar(50) not null, - - b_module_id varchar(50) not null, - - b_operation varchar(30) not null, - -- * / read / create / update / delete / export - -- * 表示模块默认范围,仅 b_scope_level = 'default' 时允许使用 - -- 值域与 action.<模块编码>.<操作> 的 capability 一致,用于把「操作」和「该操作的行范围」串起来 - - b_scope_level varchar(10) not null default 'default', - -- default / override;default 使用 b_operation='*',override 为操作级覆盖 - - b_scope_no int not null default 1, - b_scope_type varchar(30) not null, - -- own / department / department_tree / all / custom - - b_scope_field varchar(50) null, - b_scope_value varchar(100) null, - - b_updatedatetime datetime2 null, - primary key (b_user_id, b_module_id, b_operation, b_scope_level, b_scope_no) -); - -create index IX_s_user_data_scope_module - on dbo.s_user_data_scope (b_user_id, b_module_id, b_operation, b_scope_level, b_scope_type); -``` +定义见《FMS新系统核心表结构设计.md》「8. 权限」。 数据范围计算规则: @@ -276,39 +169,11 @@ create index IX_s_user_data_scope_module ### 1.6 s_user_field_pref(非权限:用户列表布局偏好表) -```sql -create table dbo.s_user_field_pref ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_mode varchar(10) not null, -- view / edit - b_visible tinyint not null default 1, - b_xh int not null default 0, - b_width int null, - b_updatedatetime datetime2 null, - primary key (b_user_id, b_module_id, b_field, b_mode) -); - -create index IX_s_user_field_pref_order - on dbo.s_user_field_pref (b_user_id, b_module_id, b_mode, b_xh, b_field); -``` +定义见《FMS新系统核心表结构设计.md》「4. 用户个性化」。 ### 1.7 s_user_query_field_pref(非权限:用户查询布局偏好表) -```sql -create table dbo.s_user_query_field_pref ( - b_user_id varchar(50) not null, - b_module_id varchar(50) not null, - b_field varchar(50) not null, - b_quick_visible tinyint not null default 1, - b_xh int not null default 0, - b_updatedatetime datetime2 null, - primary key (b_user_id, b_module_id, b_field) -); - -create index IX_s_user_query_field_pref_order - on dbo.s_user_query_field_pref (b_user_id, b_module_id, b_xh, b_field); -``` +定义见《FMS新系统核心表结构设计.md》「4. 用户个性化」。 用户个性化规则: