9.3 KiB
9.3 KiB
FMS 权限与功能实例简化设计
1. 设计原则
- 客户按菜单查找功能,但权限不绑定菜单位置。
s_feature表示客户能理解的业务功能或页面区域,是入口和显示权限边界。s_module是技术数据对象,负责字段、数据范围和默认数据能力,不直接出现在客户菜单树中。- 同一模块被多个功能使用时,模块默认能力只配置一次。
- 某个功能使用同一模块但权限更严时,增加功能-模块例外,只能收紧,不能扩大权限。
- 同一物理表但业务语义、字段或数据范围完全不同,拆成不同逻辑模块。
- 公共 Vue 页面、路由和组件可以复用,但不同业务场景使用不同
s_feature。
2. 对象关系
菜单(既有表)
└── 引用 s_feature.b_code,只负责导航
s_feature
└── 技术配置:使用哪些 s_module、模板、页面区域或报表卡片
s_module
└── 字段、默认数据能力、默认数据范围
s_power
├── feature.* 功能入口、区域/卡片显示、功能专属动作
└── module.* 模块默认数据能力
s_user_power
└── 用户对 feature.* / module.* 的授权
s_user_feature_module_override
└── 某用户在某功能使用某模块时的收紧例外
3. 表结构
3.1 s_feature(业务功能实例)
create table dbo.s_feature (
b_code varchar(100) not null,
b_name nvarchar(200) not null,
b_feature_type varchar(20) not null, -- page / panel / report_card
b_parent_code varchar(100) null,
b_template_code varchar(100) null,
b_canuse tinyint not null default 1,
b_xh int not null default 0,
primary key (b_code)
);
菜单、模块及功能-模块关系属于既有技术配置表,本文件只约定语义,不重复定义其表结构。
3.2 s_power(权限点)
create table dbo.s_power (
b_code varchar(180) not null,
b_scope_type varchar(20) not null, -- feature / module
b_scope_code varchar(100) not null, -- feature_code 或 module_id
b_name nvarchar(200) not null,
b_capability varchar(30) not null, -- access/read/create/update/delete/export/业务动作
b_i18n varchar(220) null,
b_canuse tinyint not null default 1,
b_xh int not null default 0,
primary key (b_code)
);
业务层校验 b_code、b_scope_type、b_scope_code 和 b_capability 的组合关系。权限编码由系统生成,创建后不可修改。
3.3 s_user_power(用户默认授权)
create table dbo.s_user_power (
b_user_id varchar(50) not null,
b_power_code varchar(180) not null,
b_canuse tinyint not null default 1,
b_updatedatetime datetime2 null,
primary key (b_user_id, b_power_code),
foreign key (b_power_code) references dbo.s_power(b_code)
);
3.4 s_user_feature_module_override(功能-模块收紧例外)
create table dbo.s_user_feature_module_override (
b_user_id varchar(50) not null,
b_feature_code varchar(100) not null,
b_module_id varchar(50) not null,
b_capability varchar(30) not null, -- read/create/update/delete/export
b_canuse tinyint not null default 0, -- 0 表示在该场景禁止
b_updatedatetime datetime2 null,
primary key (b_user_id, b_feature_code, b_module_id, b_capability)
);
该表只保存例外限制,不保存默认允许记录,也不能用于突破 s_user_power 的模块权限。
字段和数据范围仍按逻辑模块配置:
s_user_field_permission(user_id, module_id, field, ...)
s_user_data_scope(user_id, module_id, operation, ...)
如果某功能需要不同字段或数据范围,可将例外表扩展为功能-模块维度;仍只允许收紧权限。
4. 权限计算
4.1 入口和显示
页面进入 = feature.<page>.access
页面区域显示 = 父页面已进入 + feature.<panel>.access
报表卡片显示 = 父看板已进入 + feature.<report_card>.access
4.2 模块操作
模块读取 = feature.access + module.<module>.read
模块新增 = feature.access + module.<module>.create
模块修改 = feature.access + module.<module>.update
模块删除 = feature.access + module.<module>.delete
模块导出 = feature.access + module.<module>.export
如果存在 s_user_feature_module_override 对应的禁止记录,则该功能场景下的能力被收紧。
最终模块能力 = 功能入口 ∩ 用户模块能力 ∩ 功能-模块例外
4.3 功能专属动作
审核、反审核、核销等不属于通用 CRUD 的动作,直接绑定功能实例:
feature.sea_detail.audit
feature.cw_fee_list.settle
5. Demo 数据
5.1 功能实例
| b_code | b_name | b_feature_type | b_parent_code | b_template_code |
|---|---|---|---|---|
| sea_detail | 海运详细 | page | null | DetailPage |
| sea_detail_container | 海运详细-装箱区域 | panel | sea_detail | DetailPanel |
| container_query | 装箱查询 | page | null | CommonListPage |
| cw_fee_list | 费用列表 | page | null | CommonListPage |
| finance_dashboard | 财务看板 | page | null | DashboardPage |
| ar_aging_card | 应收账龄 | report_card | finance_dashboard | ReportCard |
5.2 功能使用的模块
| b_feature_code | b_module_id | b_usage_type | b_required |
|---|---|---|---|
| sea_detail | sea_main | main | 1 |
| sea_detail | cw_fee | detail | 0 |
| sea_detail_container | container_main | detail | 0 |
| container_query | container_main | main | 1 |
| cw_fee_list | cw_fee | main | 1 |
| ar_aging_card | finance_main | source | 1 |
5.3 权限点
| b_code | b_scope_type | b_scope_code | b_capability | b_name |
|---|---|---|---|---|
| feature.sea_detail.access | feature | sea_detail | access | 进入海运详细 |
| feature.sea_detail.audit | feature | sea_detail | audit | 海运审核 |
| feature.sea_detail_container.access | feature | sea_detail_container | access | 显示装箱区域 |
| feature.container_query.access | feature | container_query | access | 进入装箱查询 |
| feature.cw_fee_list.access | feature | cw_fee_list | access | 进入费用列表 |
| feature.finance_dashboard.access | feature | finance_dashboard | access | 进入财务看板 |
| feature.ar_aging_card.access | feature | ar_aging_card | access | 显示应收账龄 |
| feature.ar_aging_card.export | feature | ar_aging_card | export | 导出应收账龄 |
| module.sea_main.read | module | sea_main | read | 查看海运主表 |
| module.cw_fee.read | module | cw_fee | read | 查看费用 |
| module.cw_fee.create | module | cw_fee | create | 新增费用 |
| module.cw_fee.update | module | cw_fee | update | 修改费用 |
| module.cw_fee.export | module | cw_fee | export | 导出费用 |
| module.container_main.read | module | container_main | read | 查看装箱 |
| module.container_main.export | module | container_main | export | 导出装箱 |
5.4 用户默认授权
| b_user_id | b_power_code | b_canuse |
|---|---|---|
| zhangsan | feature.sea_detail.access | 1 |
| zhangsan | feature.sea_detail_container.access | 1 |
| zhangsan | feature.container_query.access | 1 |
| zhangsan | feature.cw_fee_list.access | 1 |
| zhangsan | module.sea_main.read | 1 |
| zhangsan | module.container_main.read | 1 |
| zhangsan | module.cw_fee.read | 1 |
| zhangsan | module.cw_fee.create | 1 |
| zhangsan | module.cw_fee.update | 1 |
| lisi | feature.sea_detail.access | 1 |
| lisi | feature.sea_detail_container.access | 1 |
| lisi | feature.container_query.access | 1 |
| lisi | feature.cw_fee_list.access | 1 |
| lisi | feature.finance_dashboard.access | 1 |
| lisi | feature.ar_aging_card.access | 1 |
| lisi | module.sea_main.read | 1 |
| lisi | module.container_main.read | 1 |
| lisi | module.container_main.export | 1 |
| lisi | module.cw_fee.read | 1 |
| lisi | module.cw_fee.create | 1 |
| lisi | module.cw_fee.update | 1 |
| lisi | module.cw_fee.export | 1 |
5.5 功能-模块例外
李四可以在费用列表维护费用,但海运详细中的费用只读:
| b_user_id | b_feature_code | b_module_id | b_capability | b_canuse |
|---|---|---|---|---|
| lisi | sea_detail | cw_fee | create | 0 |
| lisi | sea_detail | cw_fee | update | 0 |
| lisi | sea_detail | cw_fee | export | 0 |
结果:
费用列表:可查看、新增、修改、导出
海运详细:可查看费用,不可新增、修改、导出
6. 运行规则
请求 -> 服务端确定 feature_code
-> 检查 feature.<feature>.access
-> 按功能配置取得允许的 module_id
-> 检查 module.<module>.<operation>
-> 检查功能-模块例外
-> 应用字段权限和数据范围
-> 执行查询、写入或导出
- 菜单只负责定位功能实例,同一功能挂在多个菜单时只授权一次。
- 同一公共页面模板对应不同功能实例时,权限按功能实例区分。
- 同一模块被多个功能使用时,模块默认能力只配置一次。
- 功能场景差异通过例外限制表达,例外只能收紧。
- 页面内可独立隐藏的区域定义为
panel功能实例;看板卡片定义为report_card。 - 前端传入的
module_id必须经过当前功能的模块白名单校验。 - 后端接口必须重复校验
access、模块操作权限和例外限制,不能只依赖前端按钮隐藏。