878 lines
23 KiB
Markdown
878 lines
23 KiB
Markdown
# FMS 权限体系设计文档
|
||
|
||
## 1. 设计目标
|
||
|
||
本权限体系用于 FMS / ERP 元数据驱动架构,核心目标:
|
||
|
||
1. 操作权限与数据权限分离。
|
||
2. 权限直接绑定菜单、动作、模块、字段、页面、报表等资源。
|
||
3. Power ID 不要求人工维护,直接由资源类型、资源 ID 和操作组成。
|
||
4. 用户直接授权,不引入角色继承。
|
||
5. 数据权限独立于菜单,不因为用户从哪个菜单进入而改变数据范围。
|
||
6. 用户个性化设置不能突破权限。
|
||
7. 权限默认拒绝(Default Deny)。
|
||
|
||
---
|
||
|
||
## 2. 权限模型总览
|
||
|
||
整个权限体系分为两条线:
|
||
|
||
```text
|
||
┌──────────────┐
|
||
│ 资源定义 │
|
||
└──────┬───────┘
|
||
│
|
||
┌──────────┼──────────┐
|
||
│ │ │
|
||
菜单/动作 模块/字段 页面/报表
|
||
│ │ │
|
||
└──────────┼──────────┘
|
||
↓
|
||
s_power
|
||
↓
|
||
s_user_power
|
||
↓
|
||
用户操作权限
|
||
|
||
|
||
┌──────────────┐
|
||
│ 数据模块 │
|
||
└──────┬───────┘
|
||
↓
|
||
s_data_scope
|
||
↓
|
||
s_user_data_scope
|
||
↓
|
||
数据范围
|
||
```
|
||
|
||
因此:
|
||
|
||
- `s_power`:定义「能做什么」
|
||
- `s_user_power`:定义「用户能做什么」
|
||
- `s_data_scope`:定义「能看到 / 操作哪些数据」
|
||
- `s_user_data_scope`:定义「用户在某个模块、某个操作下使用哪个数据范围」
|
||
|
||
---
|
||
|
||
## 3. Power ID 设计
|
||
|
||
### 3.1 核心原则
|
||
|
||
`b_id` 不再使用随机 ID,也不要求人工创建类似:
|
||
|
||
```text
|
||
power_cw_fee_update
|
||
power_cw_fee_audit
|
||
power_cw_fee_amount_edit
|
||
```
|
||
|
||
而是直接使用稳定、可解析的权限编码。
|
||
|
||
统一格式:
|
||
|
||
```text
|
||
menu.<MenuID>
|
||
action.<ActionID>
|
||
module.<ModuleID>.<Operation>
|
||
field.<ModuleID>.<Field>.<Operation>
|
||
page.<PageID>
|
||
report.<ReportID>
|
||
```
|
||
|
||
### 3.2 Power ID 示例
|
||
|
||
**菜单权限**
|
||
|
||
```text
|
||
menu.cw_fee
|
||
```
|
||
|
||
表示:可以进入 / 使用费用管理菜单。
|
||
|
||
**动作权限**
|
||
|
||
```text
|
||
action.cw_fee_audit
|
||
```
|
||
|
||
表示:可以执行费用审核动作。
|
||
|
||
**模块权限**
|
||
|
||
```text
|
||
module.cw_fee.read
|
||
module.cw_fee.create
|
||
module.cw_fee.update
|
||
module.cw_fee.delete
|
||
module.cw_fee.export
|
||
```
|
||
|
||
**字段权限**
|
||
|
||
```text
|
||
field.cw_fee.mx_amount.view
|
||
field.cw_fee.mx_amount.edit
|
||
field.cw_fee.mx_amount.query
|
||
field.cw_fee.mx_amount.export
|
||
```
|
||
|
||
**页面权限**
|
||
|
||
```text
|
||
page.cw_fee
|
||
```
|
||
|
||
**报表权限**
|
||
|
||
```text
|
||
report.cw_fee_summary
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Power 类型
|
||
|
||
| b_power_type | 用途 | ID 格式 |
|
||
| ------------ | ------------ | --------------------------------------- |
|
||
| menu | 菜单入口 | `menu.<MenuID>` |
|
||
| action | 业务动作 | `action.<ActionID>` |
|
||
| module | 数据模块操作 | `module.<ModuleID>.<Operation>` |
|
||
| field | 字段能力 | `field.<ModuleID>.<Field>.<Operation>` |
|
||
| page | 页面入口 | `page.<PageID>` |
|
||
| report | 报表入口 | `report.<ReportID>` |
|
||
|
||
---
|
||
|
||
## 5. 操作权限语义
|
||
|
||
### 5.1 menu
|
||
|
||
```text
|
||
menu.cw_fee
|
||
```
|
||
|
||
用于判断用户是否拥有菜单入口权限。
|
||
|
||
菜单权限只解决:
|
||
|
||
- 用户能不能进入这个菜单。
|
||
|
||
不负责:
|
||
|
||
- 数据范围
|
||
- 字段权限
|
||
- 审核权限
|
||
- 删除权限
|
||
|
||
### 5.2 action
|
||
|
||
例如:
|
||
|
||
```text
|
||
action.cw_fee_audit
|
||
action.cw_fee_unaudit
|
||
action.cw_fee_writeoff
|
||
```
|
||
|
||
统一使用:
|
||
|
||
- `b_power_type = action`
|
||
- `b_operation = execute`
|
||
|
||
动作权限解决:用户能不能执行这个具体业务动作。
|
||
|
||
### 5.3 module
|
||
|
||
例如:
|
||
|
||
```text
|
||
module.cw_fee.read
|
||
module.cw_fee.create
|
||
module.cw_fee.update
|
||
module.cw_fee.delete
|
||
module.cw_fee.export
|
||
```
|
||
|
||
模块权限解决:用户对该业务模块具有什么数据操作能力。
|
||
|
||
### 5.4 field
|
||
|
||
例如:
|
||
|
||
```text
|
||
field.cw_fee.mx_amount.view
|
||
field.cw_fee.mx_amount.edit
|
||
field.cw_fee.mx_amount.query
|
||
field.cw_fee.mx_amount.export
|
||
```
|
||
|
||
字段权限解决:用户对某个字段具有什么能力。
|
||
|
||
需要注意:`field.xxx.edit` 只是权限允许编辑,并不代表字段最终一定可编辑。最终还要同时考虑:
|
||
|
||
- 字段权限
|
||
- `s_field_edit.b_readonly`
|
||
- `s_field_edit.b_disabled`
|
||
- 业务状态
|
||
- 业务规则
|
||
|
||
### 5.5 page
|
||
|
||
例如:
|
||
|
||
```text
|
||
page.cw_fee
|
||
```
|
||
|
||
用于页面访问控制。
|
||
|
||
页面权限和菜单权限可以同时存在:
|
||
|
||
```text
|
||
menu.cw_fee
|
||
page.cw_fee
|
||
```
|
||
|
||
菜单解决入口展示 / 进入菜单,页面解决具体页面访问。
|
||
|
||
### 5.6 report
|
||
|
||
例如:
|
||
|
||
```text
|
||
report.cw_fee_summary
|
||
```
|
||
|
||
用于报表访问权限。
|
||
|
||
报表权限本身不等于数据权限。例如用户拥有 `report.cw_fee_summary`,还需要根据报表对应的数据模块执行数据范围控制。
|
||
|
||
---
|
||
|
||
## 6. 核心表结构
|
||
|
||
以下表结构暂时不加入索引、唯一约束、外键约束,后续根据实际运行情况再补充。
|
||
|
||
### 6.1 s_power
|
||
|
||
权限定义表。
|
||
|
||
```sql
|
||
create table dbo.s_power (
|
||
b_id varchar(300) not null,
|
||
|
||
b_name nvarchar(200) not null,
|
||
b_i18n varchar(150) null,
|
||
|
||
b_power_type varchar(20) not null,
|
||
-- menu / action / module / field / page / report
|
||
|
||
b_resource varchar(128) null,
|
||
-- action / page / report 等资源 ID
|
||
|
||
b_menu_id varchar(50) null,
|
||
-- 所属菜单,主要用于 menu / action
|
||
|
||
b_module_id varchar(50) null,
|
||
-- 所属业务模块
|
||
|
||
b_field varchar(50) null,
|
||
-- field 权限对应字段
|
||
|
||
b_operation varchar(30) not null,
|
||
-- menu/page/report: access
|
||
-- action: execute
|
||
-- module: read/create/update/delete/export
|
||
-- field: view/edit/query/export
|
||
|
||
b_canuse tinyint not null default 1,
|
||
|
||
b_xh int not null default 0
|
||
);
|
||
```
|
||
|
||
`b_id` 示例:
|
||
|
||
```text
|
||
menu.cw_fee
|
||
action.cw_fee_audit
|
||
module.cw_fee.read
|
||
module.cw_fee.update
|
||
field.cw_fee.mx_amount.view
|
||
field.cw_fee.mx_amount.edit
|
||
page.cw_fee
|
||
report.cw_fee_summary
|
||
```
|
||
|
||
这里的 `b_id` 就是 Power 的业务编码。
|
||
|
||
不再需要 `power_cw_fee_update`、`power_cw_fee_audit` 这种额外编码。
|
||
|
||
---
|
||
|
||
## 7. s_user_power
|
||
|
||
用户权限授权表。
|
||
|
||
```sql
|
||
create table dbo.s_user_power (
|
||
b_user_id varchar(50) not null,
|
||
|
||
b_power_id varchar(300) not null,
|
||
|
||
b_canuse tinyint not null default 1,
|
||
|
||
b_updatedatetime datetime2 null
|
||
);
|
||
```
|
||
|
||
语义:
|
||
|
||
- 存在有效记录 = 用户拥有权限
|
||
- 不存在记录 = 用户没有权限
|
||
- `b_canuse = 0` = 当前授权无效
|
||
|
||
当前设计不增加 allow / deny,即采用:
|
||
|
||
**默认拒绝,明确授权。**
|
||
|
||
---
|
||
|
||
## 8. 数据权限
|
||
|
||
操作权限与数据权限必须分开。
|
||
|
||
例如:
|
||
|
||
```text
|
||
module.cw_fee.read
|
||
```
|
||
|
||
只表示:用户具有读取费用数据的能力。
|
||
|
||
它并不表示:用户可以读取所有费用数据。
|
||
|
||
数据范围由 `s_data_scope` / `s_user_data_scope` 控制。
|
||
|
||
---
|
||
|
||
## 9. s_data_scope
|
||
|
||
数据范围定义表。
|
||
|
||
```sql
|
||
create table dbo.s_data_scope (
|
||
b_id varchar(50) not null,
|
||
|
||
b_name nvarchar(200) not null,
|
||
|
||
b_i18n varchar(150) null,
|
||
|
||
b_module_id varchar(50) not null,
|
||
-- 数据权限作用的数据模块
|
||
|
||
b_scope_type varchar(30) not null,
|
||
-- own / department / department_tree / all / custom
|
||
|
||
b_scope_field varchar(50) null,
|
||
-- 业务数据中的归属字段
|
||
-- 例如 b_inputuser_id / b_department_id / b_owner_id
|
||
|
||
b_scope_value varchar(100) null,
|
||
-- custom 等场景使用
|
||
|
||
b_canuse tinyint not null default 1,
|
||
|
||
b_xh int not null default 0
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 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_id varchar(50) not null,
|
||
|
||
b_xh int not null default 0,
|
||
|
||
b_updatedatetime datetime2 null
|
||
);
|
||
```
|
||
|
||
多个 Scope 同时存在时:
|
||
|
||
```text
|
||
Scope A OR Scope B OR Scope C
|
||
```
|
||
|
||
例如:
|
||
|
||
```text
|
||
张三
|
||
cw_fee
|
||
read
|
||
├── department
|
||
└── own
|
||
```
|
||
|
||
表示张三读取费用数据时:department 范围 OR own 范围。
|
||
|
||
---
|
||
|
||
## 11. 完整示例
|
||
|
||
假设系统有:
|
||
|
||
- 模块:`cw_fee` = 费用管理
|
||
- 菜单:`cw_fee` = 费用管理
|
||
- 动作:`cw_fee_audit` = 审核、`cw_fee_unaudit` = 反审核、`cw_fee_writeoff` = 核销
|
||
- 字段:`mx_amount` = 金额
|
||
|
||
### 11.1 自动产生 Power
|
||
|
||
菜单:
|
||
|
||
```text
|
||
menu.cw_fee
|
||
```
|
||
|
||
动作:
|
||
|
||
```text
|
||
action.cw_fee_audit
|
||
action.cw_fee_unaudit
|
||
action.cw_fee_writeoff
|
||
```
|
||
|
||
模块:
|
||
|
||
```text
|
||
module.cw_fee.read
|
||
module.cw_fee.create
|
||
module.cw_fee.update
|
||
module.cw_fee.delete
|
||
module.cw_fee.export
|
||
```
|
||
|
||
字段:
|
||
|
||
```text
|
||
field.cw_fee.mx_amount.view
|
||
field.cw_fee.mx_amount.edit
|
||
field.cw_fee.mx_amount.query
|
||
field.cw_fee.mx_amount.export
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 用户授权示例
|
||
|
||
张三拥有:
|
||
|
||
- `menu.cw_fee`
|
||
- `module.cw_fee.read`
|
||
- `module.cw_fee.update`
|
||
- `action.cw_fee_audit`
|
||
- `field.cw_fee.mx_amount.view`
|
||
|
||
```sql
|
||
insert into dbo.s_user_power (
|
||
b_user_id,
|
||
b_power_id,
|
||
b_canuse
|
||
)
|
||
values
|
||
('zhangsan', 'menu.cw_fee', 1),
|
||
('zhangsan', 'module.cw_fee.read', 1),
|
||
('zhangsan', 'module.cw_fee.update', 1),
|
||
('zhangsan', 'action.cw_fee_audit', 1),
|
||
('zhangsan', 'field.cw_fee.mx_amount.view', 1);
|
||
```
|
||
|
||
张三没有 `module.cw_fee.delete`、`field.cw_fee.mx_amount.edit`,所以:
|
||
|
||
- 不能删除费用
|
||
- 不能修改金额字段
|
||
|
||
---
|
||
|
||
## 13. 数据范围示例
|
||
|
||
定义:
|
||
|
||
```sql
|
||
insert into dbo.s_data_scope (
|
||
b_id,
|
||
b_name,
|
||
b_module_id,
|
||
b_scope_type,
|
||
b_scope_field,
|
||
b_canuse,
|
||
b_xh
|
||
)
|
||
values
|
||
(
|
||
'scope.cw_fee.department',
|
||
N'本部门',
|
||
'cw_fee',
|
||
'department',
|
||
'b_department_id',
|
||
1,
|
||
0
|
||
);
|
||
```
|
||
|
||
然后授权:
|
||
|
||
```sql
|
||
insert into dbo.s_user_data_scope (
|
||
b_user_id,
|
||
b_module_id,
|
||
b_operation,
|
||
b_scope_id,
|
||
b_xh
|
||
)
|
||
values (
|
||
'zhangsan',
|
||
'cw_fee',
|
||
'read',
|
||
'scope.cw_fee.department',
|
||
0
|
||
);
|
||
```
|
||
|
||
此时张三拥有 `module.cw_fee.read`,并且 read 数据范围 = 本部门。
|
||
|
||
最终不是「张三可以读取全部费用」,而是「张三可以读取自己有权限范围内的费用」。
|
||
|
||
---
|
||
|
||
## 14. 权限执行顺序
|
||
|
||
一个业务操作建议按照以下顺序判断:
|
||
|
||
```text
|
||
① 用户是否有效
|
||
↓
|
||
② 菜单 / 页面入口权限
|
||
↓
|
||
③ Action 权限
|
||
↓
|
||
④ Module 数据操作权限
|
||
↓
|
||
⑤ Field 字段权限
|
||
↓
|
||
⑥ Data Scope 数据范围
|
||
↓
|
||
⑦ 业务状态 / 业务规则
|
||
↓
|
||
⑧ 执行操作
|
||
```
|
||
|
||
例如「审核费用」:
|
||
|
||
```text
|
||
用户
|
||
↓
|
||
menu.cw_fee
|
||
↓
|
||
page.cw_fee
|
||
↓
|
||
action.cw_fee_audit
|
||
↓
|
||
module.cw_fee.update
|
||
↓
|
||
数据范围
|
||
↓
|
||
费用当前状态 = 送审
|
||
↓
|
||
执行审核
|
||
```
|
||
|
||
---
|
||
|
||
## 15. 不同权限解决不同问题
|
||
|
||
| 问题 | 权限 |
|
||
| -------------- | ------------------------------- |
|
||
| 能不能看到菜单 | `menu.*` |
|
||
| 能不能进入页面 | `page.*` |
|
||
| 能不能执行审核 | `action.*` |
|
||
| 能不能修改费用 | `module.cw_fee.update` |
|
||
| 能不能看到金额 | `field.cw_fee.mx_amount.view` |
|
||
| 能不能修改金额 | `field.cw_fee.mx_amount.edit` |
|
||
| 能不能查询金额 | `field.cw_fee.mx_amount.query` |
|
||
| 能不能导出金额 | `field.cw_fee.mx_amount.export` |
|
||
| 能不能看报表 | `report.*` |
|
||
| 能看哪些数据 | `s_data_scope` |
|
||
|
||
---
|
||
|
||
## 16. 与元数据体系的关系
|
||
|
||
Power 不应该成为另一套独立的资源体系,而应该从现有元数据自动生成。
|
||
|
||
```text
|
||
s_menu
|
||
↓
|
||
menu.<MenuID>
|
||
|
||
Action 定义
|
||
↓
|
||
action.<ActionID>
|
||
|
||
s_module
|
||
↓
|
||
module.<ModuleID>.<Operation>
|
||
|
||
s_field
|
||
↓
|
||
field.<ModuleID>.<Field>.<Operation>
|
||
|
||
Page 定义
|
||
↓
|
||
page.<PageID>
|
||
|
||
Report 定义
|
||
↓
|
||
report.<ReportID>
|
||
```
|
||
|
||
因此新增模块 `cw_air_fee`,系统可以自动注册:
|
||
|
||
```text
|
||
module.cw_air_fee.read
|
||
module.cw_air_fee.create
|
||
module.cw_air_fee.update
|
||
module.cw_air_fee.delete
|
||
module.cw_air_fee.export
|
||
```
|
||
|
||
新增字段 `mx_tax`,可以自动注册:
|
||
|
||
```text
|
||
field.cw_air_fee.mx_tax.view
|
||
field.cw_air_fee.mx_tax.edit
|
||
field.cw_air_fee.mx_tax.query
|
||
field.cw_air_fee.mx_tax.export
|
||
```
|
||
|
||
不需要开发人员另外维护 Power 编码。
|
||
|
||
---
|
||
|
||
## 17. 权限与用户个性化的关系
|
||
|
||
用户个性化配置(`s_user_field_pref`、`s_user_query_field_pref`)只能调整:
|
||
|
||
- 显示
|
||
- 排序
|
||
- 宽度
|
||
- 查询字段默认状态
|
||
|
||
不能增加权限。
|
||
|
||
最终优先级:
|
||
|
||
```text
|
||
字段 b_canuse
|
||
↓
|
||
权限
|
||
↓
|
||
系统默认布局
|
||
↓
|
||
用户个性化
|
||
```
|
||
|
||
例如:用户没有 `field.cw_fee.mx_amount.view`,即使 `s_user_field_pref.b_visible = 1`,也不能显示金额字段。
|
||
|
||
---
|
||
|
||
## 18. 最终推荐的核心关系
|
||
|
||
```text
|
||
┌───────────────┐
|
||
│ s_module │
|
||
└───────┬───────┘
|
||
│
|
||
├──────────────┐
|
||
↓ ↓
|
||
s_field s_data_scope
|
||
│ │
|
||
↓ ↓
|
||
s_power s_user_data_scope
|
||
│
|
||
↓
|
||
s_user_power
|
||
│
|
||
↓
|
||
b_user
|
||
```
|
||
|
||
菜单和动作:
|
||
|
||
```text
|
||
s_menu
|
||
│
|
||
├── menu.<MenuID>
|
||
│
|
||
└── action.<ActionID>
|
||
↓
|
||
s_power
|
||
```
|
||
|
||
页面和报表:
|
||
|
||
```text
|
||
page / report
|
||
↓
|
||
s_power
|
||
```
|
||
|
||
---
|
||
|
||
## 19. 最终结论
|
||
|
||
本设计的核心原则可以归纳为:
|
||
|
||
- 资源 ID = 资源本身的 ID
|
||
- Power ID = 资源类型 + 资源 ID + Operation
|
||
|
||
统一规则:
|
||
|
||
```text
|
||
menu.<MenuID>
|
||
action.<ActionID>
|
||
module.<ModuleID>.<Operation>
|
||
field.<ModuleID>.<Field>.<Operation>
|
||
page.<PageID>
|
||
report.<ReportID>
|
||
```
|
||
|
||
其中:
|
||
|
||
- `b_id` 是稳定的业务权限编码,不需要人工随机生成。
|
||
- `s_power` 是统一权限注册表。
|
||
- `s_user_power` 是用户操作权限。
|
||
- `s_data_scope` 是数据范围定义。
|
||
- `s_user_data_scope` 是用户数据范围授权。
|
||
- 操作权限和数据权限完全分离。
|
||
- 菜单不负责数据范围。
|
||
- 用户个性化不能突破权限。
|
||
- 当前不引入角色继承。
|
||
- 后续如果增加角色,可以在 `s_user_power` 之外增加角色授权层,而无需改变 Power 编码体系。
|
||
|
||
---
|
||
|
||
## 20. Demo 数据(4 张表)
|
||
|
||
以下为 4 张表的示例数据,沿用正文的 `cw_fee` 费用模块。示例用户:张三(费用会计)、李四(财务经理)。
|
||
|
||
### 20.1 s_power(权限定义)
|
||
|
||
| b_id | b_name | b_power_type | b_resource | b_menu_id | b_module_id | b_field | b_operation | b_canuse | b_xh |
|
||
| --------------------------------- | ---------- | ------------ | --------------- | --------- | ----------- | ---------- | ----------- | -------- | ---- |
|
||
| menu.cw_fee | 费用管理菜单 | menu | cw_fee | cw_fee | null | null | access | 1 | 10 |
|
||
| page.cw_fee | 费用页面 | page | cw_fee | cw_fee | null | null | access | 1 | 20 |
|
||
| action.cw_fee_audit | 费用审核 | action | cw_fee_audit | cw_fee | cw_fee | null | execute | 1 | 30 |
|
||
| action.cw_fee_unaudit | 费用反审核 | action | cw_fee_unaudit | cw_fee | cw_fee | null | execute | 1 | 40 |
|
||
| module.cw_fee.read | 费用读取 | module | null | cw_fee | cw_fee | null | read | 1 | 10 |
|
||
| module.cw_fee.create | 费用新增 | module | null | cw_fee | cw_fee | null | create | 1 | 20 |
|
||
| module.cw_fee.update | 费用修改 | module | null | cw_fee | cw_fee | null | update | 1 | 30 |
|
||
| module.cw_fee.delete | 费用删除 | module | null | cw_fee | cw_fee | null | delete | 1 | 40 |
|
||
| module.cw_fee.export | 费用导出 | module | null | cw_fee | cw_fee | null | export | 1 | 50 |
|
||
| field.cw_fee.mx_amount.view | 金额可查看 | field | null | cw_fee | cw_fee | mx_amount | view | 1 | 10 |
|
||
| field.cw_fee.mx_amount.edit | 金额可编辑 | field | null | cw_fee | cw_fee | mx_amount | edit | 1 | 20 |
|
||
| field.cw_fee.mx_amount.query | 金额可查询 | field | null | cw_fee | cw_fee | mx_amount | query | 1 | 30 |
|
||
| field.cw_fee.mx_amount.export | 金额可导出 | field | null | cw_fee | cw_fee | mx_amount | export | 1 | 40 |
|
||
| report.cw_fee_summary | 费用汇总报表 | report | cw_fee_summary | cw_fee | cw_fee | null | access | 1 | 60 |
|
||
|
||
要点:覆盖全部 6 种 `b_power_type`;`b_id` 由类型 + 资源 + 操作自动拼出,`b_module_id` / `b_field` 等列是解析冗余,便于按模块、字段反查权限。
|
||
|
||
### 20.2 s_user_power(用户授权)
|
||
|
||
| b_user_id | b_power_id | b_canuse | b_updatedatetime |
|
||
| --------- | ------------------------------ | -------- | -------------------- |
|
||
| zhangsan | menu.cw_fee | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | page.cw_fee | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | module.cw_fee.read | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | module.cw_fee.update | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | module.cw_fee.export | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | module.cw_fee.delete | **0** | 2026-02-10 14:30:00 |
|
||
| zhangsan | action.cw_fee_audit | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | field.cw_fee.mx_amount.view | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | field.cw_fee.mx_amount.query | 1 | 2026-02-01 09:00:00 |
|
||
| zhangsan | report.cw_fee_summary | 1 | 2026-02-01 09:00:00 |
|
||
| lisi | menu.cw_fee | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | page.cw_fee | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | module.cw_fee.read | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | module.cw_fee.create | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | module.cw_fee.update | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | module.cw_fee.delete | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | module.cw_fee.export | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | action.cw_fee_audit | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | action.cw_fee_unaudit | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | field.cw_fee.mx_amount.view | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | field.cw_fee.mx_amount.edit | 1 | 2026-01-15 10:00:00 |
|
||
| lisi | field.cw_fee.mx_amount.export | 1 | 2026-01-15 10:00:00 |
|
||
|
||
要点:
|
||
|
||
- 张三的 `module.cw_fee.delete` 记录存在但 `b_canuse = 0`,演示「授权被手动停用 = 无权限」,与「无记录 = 无权限」效果相同;
|
||
- 张三没有 `field.cw_fee.mx_amount.edit`,金额字段对他只读;李四全量字段能力。
|
||
|
||
### 20.3 s_data_scope(数据范围定义)
|
||
|
||
| b_id | b_name | b_module_id | b_scope_type | b_scope_field | b_scope_value | b_canuse | b_xh |
|
||
| ------------------------------ | ------------ | ----------- | ---------------- | ---------------- | ------------- | -------- | ---- |
|
||
| scope.cw_fee.own | 仅本人 | cw_fee | own | b_inputuser_id | null | 1 | 10 |
|
||
| scope.cw_fee.department | 本部门 | cw_fee | department | b_department_id | null | 1 | 20 |
|
||
| scope.cw_fee.department_tree | 本部门及下属 | cw_fee | department_tree | b_department_id | null | 1 | 30 |
|
||
| scope.cw_fee.all | 全部费用 | cw_fee | all | null | null | 1 | 40 |
|
||
| scope.cw_fee.custom_project | 指定项目 | cw_fee | custom | b_project_id | PRJ001 | 1 | 50 |
|
||
|
||
要点:`own` / `department` / `department_tree` / `all` 靠 `b_scope_type` 语义过滤,`b_scope_field` 指向业务表的归属字段;`custom` 额外用 `b_scope_value` 指定具体值。
|
||
|
||
### 20.4 s_user_data_scope(用户数据范围授权)
|
||
|
||
| b_user_id | b_module_id | b_operation | b_scope_id | b_xh | b_updatedatetime |
|
||
| --------- | ----------- | ----------- | ---------------------------- | ---- | ------------------- |
|
||
| zhangsan | cw_fee | read | scope.cw_fee.department | 0 | 2026-02-01 09:00:00 |
|
||
| zhangsan | cw_fee | read | scope.cw_fee.own | 10 | 2026-02-01 09:00:00 |
|
||
| zhangsan | cw_fee | update | scope.cw_fee.own | 0 | 2026-02-01 09:00:00 |
|
||
| lisi | cw_fee | read | scope.cw_fee.department_tree | 0 | 2026-01-15 10:00:00 |
|
||
| lisi | cw_fee | update | scope.cw_fee.department_tree | 0 | 2026-01-15 10:00:00 |
|
||
| lisi | cw_fee | delete | scope.cw_fee.all | 0 | 2026-01-15 10:00:00 |
|
||
|
||
要点:
|
||
|
||
- 张三 read 挂了两条范围 → 部门数据 OR 本人数据;
|
||
- 数据范围按操作分开授权:张三能看本部门,但只能改自己录的费用(update 仅 own);
|
||
- 李四 delete 挂 `all`,经理可删全模块数据,符合「操作越重、范围越收」或「管理者放宽」都可表达的弹性。
|
||
|
||
### 20.5 组合结果解读
|
||
|
||
| 能力 | 张三(费用会计) | 李四(财务经理) |
|
||
| ---------------- | ---------------------------------------- | -------------------------------- |
|
||
| 看菜单 / 页面 | ✅ | ✅ |
|
||
| 读取费用数据 | ✅ 本部门 + 本人 | ✅ 本部门及下属部门 |
|
||
| 新增 | ❌ 无 module.create | ✅ |
|
||
| 修改 | ✅ 仅本人录入的单据 | ✅ 本部门及下属部门的单据 |
|
||
| 删除 | ❌ 授权已停用(b_canuse=0) | ✅ 全部数据 |
|
||
| 审核 / 反审核 | ✅ 可审核,❌ 不可反审核 | ✅ 都可以 |
|
||
| 金额字段 | 可看、可查询、❌ 不可编辑、❌ 不可导出字段列 | 可看、可编辑、可导出 |
|
||
| 汇总报表 | ✅ | ✅(报表数据仍受 read 范围约束) |
|