当前位置: 首页 > news >正文

统一字段权限组件功能设计方案(一)---升鲜宝生鲜配送供应链管理系统

升鲜宝供应链系统

统一字段权限功能设计方案

 

适用范围:Spring Boot + MyBatis-Plus + Vue3 + Redis/Caffeine
覆盖:后台管理端 / 小程序 / App / POS / 导入导出 / 打印 / PDF / 图片 / 分享码

文档版本:V1.0 Final
生成日期:2024-04-28
文档性质:研发可落地设计文档
适用项目:升鲜宝供应链管理系统

 

版本记录

版本

日期

说明

适用阶段

V1.0 Final

2024-04-28

统一字段权限最终完善版,面向一次性底座重构与分批业务接入

设计评审 / 研发落地

适配范围

长期有效

适配升鲜宝供应链管理系统后台、小程序、App、POS、导入导出、打印、分享码等场景

全系统

 

目录

目录生成提示:在 Word 中右键更新域即可生成完整目录。

提示:Word 打开后可右键目录区域选择“更新域”,即可生成真实页码目录。本文档同时提供完整章节标题,便于直接阅读。

 

1. 方案定位与重构目标

最终设计结论

升鲜宝字段权限不能只做“前端隐藏列”。最终应建设为统一字段安全底座,覆盖列表、详情、表单、新增、修改、审核、反审核、查询、排序、导入导出、打印、PDF/图片生成、分享码外部查看等全链路场景。

统一字段权限组件的目标,是让不同用户、不同角色、不同门店、不同终端、不同业务场景下,同一个资源的字段能够按照统一规则完成可见、脱敏、隐藏、禁止、可编辑、可查询、可导出、可打印、可分享等控制。

目标

说明

统一建模

字段资源、字段定义、字段场景、字段策略、脱敏规则、日志审计全部统一管理。

统一接入

业务模块通过注解、API绑定或公共组件接入,避免每个模块重复写字段权限逻辑。

统一拦截

后端对返回值、提交DTO、查询字段、排序字段、导出字段、打印字段、分享字段进行强校验。

统一审计

敏感字段访问、字段脱敏、越权查询、越权编辑、批量导出、分享码访问等全部记录日志。

统一扩展

后续可扩展到 SQL 字段裁剪、动态列、字段审批、字段水印、字段级数据血缘。

 

1.1 一次性落地重构原则

  • 底座一次性设计完整:表结构、引擎、缓存、接口、审计、配置后台一次性定型。
  • 业务模块分批接入:商品、客户、供应商先行,订单、采购、WMS、财务随后接入。
  • 旧接口平滑兼容:使用 sys_field_api_bind 做接口与资源场景绑定,避免大面积修改 Controller 方法签名。
  • 后端强制兜底:前端隐藏只是用户体验,最终安全必须由后端强校验。
  • 高敏字段默认拒绝:成本价、采购价、毛利率、余额、授信额度、银行账户等必须显式授权。

1.2 与现有权限体系的关系

权限类型

控制对象

典型示例

与字段权限关系

菜单权限

能否进入页面

是否能进入商品管理

字段权限在菜单权限通过后生效

按钮权限

能否执行动作

是否能新增、审核、反审核

字段编辑权限在按钮动作内部继续细分

数据权限

能看到哪些数据行

只能看自己门店、自己客户

字段权限控制同一行数据中的字段范围

字段权限

能看/改/查/导出哪些字段

是否能看成本价、手机号、余额

本方案核心

场景权限

同一资源在不同场景的差异

商品在销售开单与商品管理中不同

字段权限必须绑定 scene_code

 

2. 业务痛点与典型场景

业务场景

权限痛点

最终解决方式

商品列表

普通业务员不应查看成本价、毛利率、库存金额

READ 权限返回过滤,EXPORT/PRINT/SHARE 单独控制

销售开单选择商品

需要商品名称、规格、售价,但不能看到采购价、成本价

同一 pms.goods 资源使用 admin.sales.order.create.selectGoods 场景

销售出库

仓库人员需要库位、批次、库存数量,不需要客户授信、账期

WMS 场景只开放仓储相关字段

客户列表

手机号、地址、账期、授信额度、应收余额需要不同权限

手机号脱敏,账期/授信/余额默认高敏隐藏

供应商模块

采购可看采购价和联系人,仓管不应看到结算账户

角色/岗位/部门组合授权,CRITICAL 字段默认禁止

Excel 导出

页面可见不代表可以导出

EXPORT 权限独立计算,敏感字段可配置审批

打印配送单

客户单据不能暴露成本、采购价、内部备注

PRINT/RENDER 权限过滤模板字段和数据

分享码查看

外部客户/供应商/司机不能继承内部员工权限

SHARE 独立场景,外部最小字段集

 

3. 总体架构设计

 

1 统一字段权限总体架构

整体架构分为四层:前端 Schema 层、FieldPermission API 层、FieldPermissionEngine 引擎层、业务集成层。业务模块不直接写权限判断,而是通过公共入口接入字段权限底座。

3.1 核心组成

组件

职责

落地内容

字段资源中心

定义业务资源

resource_code、资源名称、领域、主表、VO 类

字段定义中心

定义资源字段

field_code、field_path、db_column、敏感等级、默认策略

业务场景中心

定义场景差异

scene_code、终端、页面、动作、场景类型

字段策略中心

配置主体授权

用户/角色/部门/岗位/门店/租户的字段权限

脱敏规则中心

统一脱敏算法

手机号、邮箱、身份证、银行卡、地址、金额区间

字段权限引擎

计算最终权限

上下文、策略匹配、优先级合并、缓存、日志

业务接入层

全链路拦截

AOP、ResponseAdvice、QueryFacade、ExportGuard、PrintGuard、ShareGuard

 

3.2 运行时处理流程

 

2 字段权限运行时处理流程

4. 权限模型设计

字段权限的本质公式如下:

最终字段权限 =

租户 + 用户 + 角色 + 部门 + 岗位 + 门店

+ 资源编码 resource_code

+ 场景编码 scene_code

+ 字段编码 field_code

+ 操作类型 operation_type

+ 字段敏感等级 sensitivity_level

+ 默认策略 + 场景策略 + 授权策略 + 显式拒绝策略

 

4.1 最小控制单元

tenant_id

+ resource_code

+ scene_code

+ field_code

+ operation_type

+ subject_type

+ subject_id

 

示例维度

示例值

租户

10001

资源

pms.goods

场景

admin.sales.order.create.selectGoods

字段

costPrice

操作

READ

主体

ROLE:销售员

结果

HIDE

 

4.2 操作类型

操作类型

说明

典型场景

READ

读取字段

列表、详情、下拉选择、看板

CREATE

新增字段提交

新增客户时提交授信额度

UPDATE

修改字段提交

修改商品采购价、成本价

QUERY

查询条件字段

高级查询使用成本价、余额过滤

SORT

排序字段

按毛利率、余额排序

IMPORT

导入字段

Excel 导入客户账期、商品成本

EXPORT

导出字段

Excel 导出手机号、成本价、余额

PRINT

打印字段

打印配送单、对账单、采购单

RENDER

PDF/图片生成字段

小票图片、单据 PDF、分享图

SHARE

分享码外部查看字段

客户扫码、供应商扫码、司机任务

 

4.3 权限模式

权限类型

模式

说明

读取 read_mode

PLAIN

原值返回

读取 read_mode

MASK

脱敏返回

读取 read_mode

HIDE

字段隐藏,返回 null 或移除

读取 read_mode

FORBIDDEN

禁止访问,记录越权日志

编辑 edit_mode

EDITABLE

可编辑

编辑 edit_mode

READONLY

只读,不允许提交变更

编辑 edit_mode

FORBIDDEN

禁止提交

查询 query_mode

ALLOW

允许作为查询条件

查询 query_mode

MASK_QUERY

仅允许脱敏查询,例如手机号后四位

查询 query_mode

FORBIDDEN

禁止查询

导出 export_mode

PLAIN / MASK / FORBIDDEN / APPROVAL_REQUIRED

原值、脱敏、禁止、审批后导出

输出 print/render/share

ALLOW / MASK / FORBIDDEN

允许、脱敏、禁止

 

4.4 敏感等级

等级

编码

默认读取

默认导出

默认分享

示例字段

1

PUBLIC

PLAIN

PLAIN

ALLOW

商品名称、规格、单位

2

INTERNAL

PLAIN

PLAIN

按场景

库存数量、订单金额

3

SENSITIVE

MASK

MASK

MASK/FORBIDDEN

手机号、地址、联系人

4

SECRET

HIDE

FORBIDDEN

FORBIDDEN

成本价、毛利率、应收余额

5

CRITICAL

FORBIDDEN

FORBIDDEN

FORBIDDEN

银行账号、身份证、接口密钥

 

5. 编码规范

5.1 资源编码 resource_code

建议格式:领域.资源,例如 pms.goods、crm.customer、wms.stockOut。字段权限编码必须稳定,不应随着表名重构频繁变化。

业务资源

resource_code

说明

商品档案

pms.goods

商品主数据、商品选择、商品导出

客户档案

crm.customer

客户基础信息、账期、授信、余额

供应商档案

sup.supplier

供应商基础信息、结算账户、应付余额

销售订单

oms.salesOrder

销售单主表与明细字段

采购订单

pur.purchaseOrder

采购单主表与明细字段

入库单

wms.stockIn

采购入库、调拨入库、退货入库

出库单

wms.stockOut

销售出库、报损出库、调拨出库

门店库存

hwms.inventory

门店库存、货位、批次

应收账款

fin.receivable

客户应收、已收、未收、对账

应付账款

fin.payable

供应商应付、已付、未付、对账

 

5.2 场景编码 scene_code

建议格式:终端.模块.业务动作.页面位置。例如 admin.sales.order.create.selectGoods。场景编码是字段权限落地的关键,因为同一个资源在不同页面、不同终端、不同动作下字段权限不同。

业务场景

scene_code

后台商品列表

admin.pms.goods.list

后台商品详情

admin.pms.goods.detail

销售开单选择商品

admin.sales.order.create.selectGoods

销售出库选择商品

admin.wms.stockOut.create.selectGoods

商品导出

admin.pms.goods.export

客户对账单打印

admin.fin.customerStatement.print

客户扫码查看配送单

share.customer.delivery.view

供应商扫码查看采购单

share.supplier.purchase.view

司机小程序查看配送任务

mobile.driver.delivery.task

 

5.3 字段编码 field_code

field_code 推荐使用 Java VO 字段名,而不是数据库字段名。数据库字段名只作为映射字段 db_column 存储。这样可以降低表结构演进对权限配置的影响。

field_code = costPrice

field_path = detailList[].costPrice

db_table = pms_goods

db_column = cost_price

 

6. 数据库设计总览

表名

用途

是否核心

sys_field_resource

字段资源表

核心

sys_field_define

字段定义表

核心

sys_field_scene

字段场景表

核心

sys_field_scene_field

场景字段默认策略表

核心

sys_field_policy

字段授权策略主表

核心

sys_field_policy_item

字段授权策略明细表

核心

sys_field_mask_rule

字段脱敏规则表

核心

sys_field_permission_log

字段权限命中/越权日志表

审计

sys_field_policy_change_log

字段权限配置变更日志表

审计

sys_field_cache_version

字段权限缓存版本表

性能

sys_field_api_bind

接口与资源场景绑定表

兼容

 

6.1 核心表结构说明

sys_field_resource

定义业务资源,例如商品、客户、供应商、销售订单、入库单、出库单。

CREATE TABLE sys_field_resource (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID0表示系统级资源',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码,如 pms.goods',

    resource_name VARCHAR(100) NOT NULL COMMENT '资源名称,如 商品档案',

    domain_code VARCHAR(50) NOT NULL COMMENT '领域编码,如 pms/oms/wms/crm/fin',

    module_code VARCHAR(50) DEFAULT NULL COMMENT '模块编码',

    main_table VARCHAR(100) DEFAULT NULL COMMENT '主表名',

    entity_class VARCHAR(255) DEFAULT NULL COMMENT 'Entity类名',

    vo_class VARCHAR(255) DEFAULT NULL COMMENT 'VO类名',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_by BIGINT DEFAULT NULL COMMENT '创建人',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_by BIGINT DEFAULT NULL COMMENT '更新人',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_tenant_resource (tenant_id, resource_code),

    KEY idx_domain_code (domain_code),

    KEY idx_module_code (module_code)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-字段资源表';

 

sys_field_define

定义资源字段,包括字段路径、数据库映射、敏感等级和默认策略。

CREATE TABLE sys_field_define (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID0表示系统级字段',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    field_code VARCHAR(100) NOT NULL COMMENT '字段编码,如 costPrice',

    field_name VARCHAR(100) NOT NULL COMMENT '字段名称,如 成本价',

    field_path VARCHAR(200) NOT NULL COMMENT '字段路径,支持 detailList[].costPrice',

    db_table VARCHAR(100) DEFAULT NULL COMMENT '数据库表名',

    db_table_alias VARCHAR(50) DEFAULT NULL COMMENT 'SQL表别名',

    db_column VARCHAR(100) DEFAULT NULL COMMENT '数据库字段名,如 cost_price',

    data_type VARCHAR(50) DEFAULT NULL COMMENT '数据类型',

    sensitivity_level TINYINT NOT NULL DEFAULT 1 COMMENT '敏感等级:1普通,2内部,3敏感,4高敏,5极高敏',

    default_read_mode VARCHAR(20) NOT NULL DEFAULT 'PLAIN' COMMENT '默认读取模式',

    default_edit_mode VARCHAR(20) NOT NULL DEFAULT 'EDITABLE' COMMENT '默认编辑模式',

    default_query_mode VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '默认查询模式',

    default_sort_mode VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '默认排序模式',

    default_import_mode VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '默认导入模式',

    default_export_mode VARCHAR(20) NOT NULL DEFAULT 'PLAIN' COMMENT '默认导出模式',

    default_print_mode VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '默认打印模式',

    default_render_mode VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '默认PDF/图片生成模式',

    default_share_mode VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '默认分享模式',

    mask_rule_code VARCHAR(50) DEFAULT NULL COMMENT '默认脱敏规则编码',

    frontend_component VARCHAR(50) DEFAULT NULL COMMENT '前端组件类型',

    sort_no INT NOT NULL DEFAULT 0 COMMENT '排序号',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_resource_field (tenant_id, resource_code, field_code),

    KEY idx_resource_code (resource_code),

    KEY idx_sensitivity_level (sensitivity_level),

    KEY idx_db_column (db_table, db_column)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-字段定义表';

 

sys_field_scene

定义字段权限适用的业务场景。

CREATE TABLE sys_field_scene (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID0表示系统级场景',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) NOT NULL COMMENT '场景编码',

    scene_name VARCHAR(100) NOT NULL COMMENT '场景名称',

    scene_type VARCHAR(50) NOT NULL COMMENT '场景类型:LIST/DETAIL/FORM/EXPORT/PRINT/SHARE/API',

    terminal_type VARCHAR(50) NOT NULL DEFAULT 'ADMIN' COMMENT

        '终端:ADMIN/MOBILE/MINIAPP/POS/SHARE',

    biz_action VARCHAR(50) DEFAULT NULL COMMENT '业务动作:VIEW/CREATE/UPDATE/APPROVE/EXPORT',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_scene_code (tenant_id, scene_code),

    KEY idx_resource_code (resource_code),

    KEY idx_scene_type (scene_type),

    KEY idx_terminal_type (terminal_type)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-字段场景表';

 

sys_field_scene_field

定义同一字段在不同场景下的默认权限。

CREATE TABLE sys_field_scene_field (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) NOT NULL COMMENT '场景编码',

    field_code VARCHAR(100) NOT NULL COMMENT '字段编码',

    read_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认读取模式',

    edit_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认编辑模式',

    query_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认查询模式',

    sort_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认排序模式',

    import_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认导入模式',

    export_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认导出模式',

    print_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认打印模式',

    render_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认渲染模式',

    share_mode VARCHAR(20) DEFAULT NULL COMMENT '场景默认分享模式',

    visible_flag TINYINT NOT NULL DEFAULT 1 COMMENT '前端是否显示:0否,1',

    readonly_flag TINYINT NOT NULL DEFAULT 0 COMMENT '前端是否只读:0否,1',

    required_flag TINYINT NOT NULL DEFAULT 0 COMMENT '是否必填:0否,1',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_scene_field (tenant_id, scene_code, field_code),

    KEY idx_resource_scene (tenant_id, resource_code, scene_code)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-场景字段默认策略表';

 

sys_field_policy

定义授权主体,如用户、角色、部门、岗位、门店、租户。

CREATE TABLE sys_field_policy (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL COMMENT '租户ID',

    policy_code VARCHAR(100) NOT NULL COMMENT '策略编码',

    policy_name VARCHAR(100) NOT NULL COMMENT '策略名称',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) NOT NULL COMMENT '场景编码',

    subject_type VARCHAR(30) NOT NULL COMMENT '主体类型:USER/ROLE/DEPT/POST/SHOP/TENANT',

    subject_id BIGINT NOT NULL COMMENT '主体ID',

    effect VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '效果:ALLOW/DENY',

    priority INT NOT NULL DEFAULT 100 COMMENT '优先级,数字越小优先级越高',

    effective_start_time DATETIME DEFAULT NULL COMMENT '生效开始时间',

    effective_end_time DATETIME DEFAULT NULL COMMENT '生效结束时间',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_by BIGINT DEFAULT NULL COMMENT '创建人',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_by BIGINT DEFAULT NULL COMMENT '更新人',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_policy_subject (tenant_id, resource_code, scene_code, subject_type, subject_id),

    KEY idx_subject (tenant_id, subject_type, subject_id),

    KEY idx_resource_scene (tenant_id, resource_code, scene_code),

    KEY idx_status_time (status, effective_start_time, effective_end_time)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-字段授权策略主表';

 

sys_field_policy_item

定义策略下每个字段的读取、编辑、查询、导出、打印、分享权限。

CREATE TABLE sys_field_policy_item (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL COMMENT '租户ID',

    policy_id BIGINT NOT NULL COMMENT '策略主表ID',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) NOT NULL COMMENT '场景编码',

    field_code VARCHAR(100) NOT NULL COMMENT '字段编码',

    read_mode VARCHAR(20) DEFAULT NULL COMMENT '读取权限',

    edit_mode VARCHAR(20) DEFAULT NULL COMMENT '编辑权限',

    query_mode VARCHAR(20) DEFAULT NULL COMMENT '查询权限',

    sort_mode VARCHAR(20) DEFAULT NULL COMMENT '排序权限',

    import_mode VARCHAR(20) DEFAULT NULL COMMENT '导入权限',

    export_mode VARCHAR(20) DEFAULT NULL COMMENT '导出权限',

    print_mode VARCHAR(20) DEFAULT NULL COMMENT '打印权限',

    render_mode VARCHAR(20) DEFAULT NULL COMMENT 'PDF/图片生成权限',

    share_mode VARCHAR(20) DEFAULT NULL COMMENT '分享权限',

    mask_rule_code VARCHAR(50) DEFAULT NULL COMMENT '脱敏规则',

    condition_json JSON DEFAULT NULL COMMENT '条件表达式',

    effect VARCHAR(20) NOT NULL DEFAULT 'ALLOW' COMMENT '效果:ALLOW/DENY',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_policy_field (tenant_id, policy_id, field_code),

    KEY idx_resource_scene_field (tenant_id, resource_code, scene_code, field_code),

    KEY idx_field_code (field_code)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-字段授权策略明细表';

 

sys_field_mask_rule

统一管理脱敏规则。

CREATE TABLE sys_field_mask_rule (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID0表示系统级规则',

    rule_code VARCHAR(50) NOT NULL COMMENT '规则编码,如 MOBILE/ID_CARD/BANK_CARD',

    rule_name VARCHAR(100) NOT NULL COMMENT '规则名称',

    rule_type VARCHAR(50) NOT NULL COMMENT '规则类型:MOBILE/EMAIL/ID_CARD/BANK_CARD/ADDRESS/CUSTOM',

    rule_config JSON DEFAULT NULL COMMENT '规则配置JSON',

    example_before VARCHAR(200) DEFAULT NULL COMMENT '脱敏前示例',

    example_after VARCHAR(200) DEFAULT NULL COMMENT '脱敏后示例',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_rule_code (tenant_id, rule_code)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-脱敏规则表';

 

sys_field_permission_log

记录敏感字段访问、脱敏、隐藏、越权、导出、打印、分享行为。

CREATE TABLE sys_field_permission_log (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL COMMENT '租户ID',

    user_id BIGINT NOT NULL COMMENT '操作用户ID',

    username VARCHAR(100) DEFAULT NULL COMMENT '用户名',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) NOT NULL COMMENT '场景编码',

    field_code VARCHAR(100) NOT NULL COMMENT '字段编码',

    operation_type VARCHAR(50) NOT NULL COMMENT '动作类型:READ/UPDATE/QUERY/EXPORT/PRINT/SHARE',

    permission_result VARCHAR(50) NOT NULL COMMENT '权限结果:PLAIN/MASK/HIDE/FORBIDDEN',

    request_uri VARCHAR(500) DEFAULT NULL COMMENT '请求URI',

    request_method VARCHAR(20) DEFAULT NULL COMMENT '请求方法',

    request_param JSON DEFAULT NULL COMMENT '请求参数',

    ip VARCHAR(50) DEFAULT NULL COMMENT 'IP地址',

    user_agent VARCHAR(500) DEFAULT NULL COMMENT 'User-Agent',

    risk_level TINYINT NOT NULL DEFAULT 1 COMMENT '风险等级:1低,2中,3高,4严重',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    KEY idx_user_time (tenant_id, user_id, create_time),

    KEY idx_resource_scene (tenant_id, resource_code, scene_code),

    KEY idx_field_action (field_code, operation_type),

    KEY idx_risk_level (risk_level)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-命中日志表';

 

sys_field_policy_change_log

记录字段权限配置变更,便于审计和追溯。

CREATE TABLE sys_field_policy_change_log (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL COMMENT '租户ID',

    operator_id BIGINT NOT NULL COMMENT '操作人ID',

    operator_name VARCHAR(100) DEFAULT NULL COMMENT '操作人名称',

    change_type VARCHAR(30) NOT NULL COMMENT 'CREATE/UPDATE/DELETE/ENABLE/DISABLE',

    resource_code VARCHAR(100) DEFAULT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) DEFAULT NULL COMMENT '场景编码',

    policy_id BIGINT DEFAULT NULL COMMENT '策略ID',

    before_json JSON DEFAULT NULL COMMENT '变更前JSON',

    after_json JSON DEFAULT NULL COMMENT '变更后JSON',

    ip VARCHAR(50) DEFAULT NULL COMMENT 'IP地址',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    KEY idx_operator_time (tenant_id, operator_id, create_time),

    KEY idx_policy_id (policy_id),

    KEY idx_resource_scene (resource_code, scene_code)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-策略变更日志表';

 

sys_field_cache_version

权限配置变更后用于刷新 Redis 和 Caffeine 缓存。

CREATE TABLE sys_field_cache_version (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL COMMENT '租户ID',

    version_no BIGINT NOT NULL DEFAULT 1 COMMENT '当前版本号',

    last_refresh_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后刷新时间',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    UNIQUE KEY uk_tenant_id (tenant_id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-缓存版本表';

 

sys_field_api_bind

将老接口与 resource_code、scene_code、operation_type 绑定,降低改造成本。

CREATE TABLE sys_field_api_bind (

    id BIGINT NOT NULL PRIMARY KEY COMMENT '主键ID',

    tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID0表示系统级绑定',

    request_uri VARCHAR(500) NOT NULL COMMENT '接口URI,支持精确匹配或Ant模式',

    request_method VARCHAR(20) NOT NULL COMMENT 'GET/POST/PUT/DELETE',

    resource_code VARCHAR(100) NOT NULL COMMENT '资源编码',

    scene_code VARCHAR(150) NOT NULL COMMENT '场景编码',

    operation_type VARCHAR(50) NOT NULL COMMENT 'READ/CREATE/UPDATE/QUERY/EXPORT/PRINT/SHARE',

    match_type VARCHAR(20) NOT NULL DEFAULT 'EXACT' COMMENT 'EXACT/ANT/REGEX',

    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',

    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0停用,1启用',

    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否,1',

    UNIQUE KEY uk_api_bind (tenant_id, request_uri, request_method, operation_type),

    KEY idx_resource_scene (tenant_id, resource_code, scene_code)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='统一字段权限-接口资源场景绑定表';

 

7. 字段权限引擎设计

7.1 项目包结构

com.sxb.system.fieldpermission

├── annotation

│   ├── SxbFieldPermission.java

│   ├── SxbFieldWriteCheck.java

│   └── SxbFieldExportCheck.java

├── api

│   ├── FieldResourceController.java

│   ├── FieldDefineController.java

│   ├── FieldSceneController.java

│   ├── FieldPolicyController.java

│   └── FieldSchemaController.java

├── application

│   ├── FieldPermissionAppService.java

│   ├── FieldPolicyAppService.java

│   ├── FieldSchemaAppService.java

│   └── FieldAuditAppService.java

├── domain

│   ├── engine

│   │   ├── FieldPermissionEngine.java

│   │   ├── FieldPolicyMatchEngine.java

│   │   ├── FieldPolicyMergeEngine.java

│   │   ├── FieldMaskEngine.java

│   │   └── FieldPermissionCacheService.java

│   ├── model

│   │   ├── FieldPermissionContext.java

│   │   ├── FieldPermissionSnapshot.java

│   │   ├── FieldPermissionItem.java

│   │   └── FieldMaskResult.java

│   └── enums

│       ├── FieldOperationTypeEnum.java

│       ├── FieldReadModeEnum.java

│       ├── FieldEditModeEnum.java

│       ├── FieldQueryModeEnum.java

│       ├── FieldExportModeEnum.java

│       └── FieldSensitivityLevelEnum.java

├── infrastructure

│   ├── entity

│   ├── mapper

│   ├── repository

│   └── cache

└── support

    ├── FieldPermissionAspect.java

    ├── FieldPermissionResponseAdvice.java

    ├── FieldWriteCheckAspect.java

    ├── FieldQueryGuard.java

    ├── FieldExportGuard.java

    ├── FieldPrintGuard.java

    └── FieldShareGuard.java

 

7.2 核心接口

public interface FieldPermissionEngine {

 

    FieldPermissionSnapshot calculate(FieldPermissionContext context);

 

    <T> T filterReadResult(T data, FieldPermissionContext context);

 

    <T> List<T> filterReadList(List<T> dataList, FieldPermissionContext context);

 

    void checkCreateFields(Object dto, FieldPermissionContext context);

 

    void checkUpdateFields(Object dto, FieldPermissionContext context);

 

    void checkQueryFields(QueryRequest queryRequest, FieldPermissionContext context);

 

    void checkSortFields(QueryRequest queryRequest, FieldPermissionContext context);

 

    List<ExportField> filterExportFields(List<ExportField> fields, FieldPermissionContext

        context);

 

    Map<String, Object> filterPrintData(Map<String, Object> data, FieldPermissionContext

        context);

 

    Map<String, Object> filterShareData(Map<String, Object> data, FieldPermissionContext

        context);

}

 

7.3 权限上下文

@Data

public class FieldPermissionContext {

    private Long tenantId;

    private Long userId;

    private String username;

    private List<Long> roleIds;

    private List<Long> deptIds;

    private List<Long> postIds;

    private Long shopId;

    private String terminalType;

    private String resourceCode;

    private String sceneCode;

    private FieldOperationTypeEnum operationType;

    private String requestUri;

    private String requestMethod;

    private Boolean superAdmin;

    private Map<String, Object> bizContext;

}

 

7.4 权限快照

@Data

public class FieldPermissionSnapshot {

    private Long tenantId;

    private Long userId;

    private String resourceCode;

    private String sceneCode;

    private String operationType;

    private Long versionNo;

    private Map<String, FieldPermissionItem> fieldMap;

}

 

@Data

public class FieldPermissionItem {

    private String fieldCode;

    private String fieldName;

    private String fieldPath;

    private Integer sensitivityLevel;

    private String readMode;

    private String editMode;

    private String queryMode;

    private String sortMode;

    private String importMode;

    private String exportMode;

    private String printMode;

    private String renderMode;

    private String shareMode;

    private String maskRuleCode;

    private Boolean visible;

    private Boolean editable;

    private Boolean queryable;

    private Boolean exportable;

    private Boolean printable;

    private Boolean shareable;

}

 

8. 权限计算与合并规则

1. 构建 FieldPermissionContext,包括租户、用户、角色、部门、岗位、门店、终端、资源、场景、操作类型。

2. 判断超级管理员,但超级管理员是否默认拥有高敏字段应由系统参数控制。

3. 加载字段定义 sys_field_define。

4. 加载场景默认策略 sys_field_scene_field。

5. 加载命中的用户、岗位、角色、部门、门店、租户默认策略。

6. 按优先级合并策略,显式 DENY 永远优先。

7. 应用敏感等级默认规则。

8. 生成 FieldPermissionSnapshot 并写入缓存。

9. 根据操作类型执行返回过滤、编辑校验、查询校验、导出过滤、打印过滤或分享过滤。

规则

说明

显式拒绝优先

只要命中 DENY,就不能通过其他角色绕过。

用户优先

用户级策略优先于岗位、角色、部门、租户策略。

岗位优先于部门

岗位通常比部门更能表示业务职责。

高敏字段从严

多角色命中高敏字段时取更严格权限。

普通字段可从宽

普通字段多角色命中可取更宽松权限。

场景优先

场景默认策略优先于字段默认策略。

导出/分享更严格

页面能看不代表可以导出或分享。

 

9. 后端接入方案

9.1 Controller 注解接入

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface SxbFieldPermission {

    String resourceCode();

    String sceneCode();

    FieldOperationTypeEnum operationType() default FieldOperationTypeEnum.READ;

}

 

@SxbFieldPermission(

    resourceCode = "pms.goods",

    sceneCode = "admin.sales.order.create.selectGoods",

    operationType = FieldOperationTypeEnum.READ

)

@GetMapping("/goods/select")

public List<GoodsSelectVO> selectGoods(GoodsSelectQueryDTO queryDTO) {

    return goodsService.selectGoods(queryDTO);

}

 

9.2 老接口 API 绑定接入

对于老接口,不建议一次性大面积修改 Controller 方法签名。可以先将接口路径与资源场景写入 sys_field_api_bind。运行时 AOP 根据请求路径匹配 resource_code、scene_code、operation_type。

接口

资源

场景

动作

/api/pms/goods/page

pms.goods

admin.pms.goods.list

READ

/api/pms/goods/detail

pms.goods

admin.pms.goods.detail

READ

/api/oms/order/goods/select

pms.goods

admin.sales.order.create.selectGoods

READ

/api/crm/customer/update

crm.customer

admin.crm.customer.update

UPDATE

 

9.3 返回值过滤

推荐第一版采用 ResponseBodyAdvice + AOP 的方式,在 Controller 返回后统一过滤 VO、List、Page、IPage、Map、嵌套对象、明细列表。不要第一版就全局 SQL 拦截,避免误伤复杂 Mapper。

Controller 返回 VO / List / Page

    

ResponseBodyAdvice 拦截

    

读取 SxbFieldPermission sys_field_api_bind

    

构建 FieldPermissionContext

    

FieldPermissionEngine.calculate()

    

对字段执行 PLAIN / MASK / HIDE / FORBIDDEN

    

返回前端安全结果

 

9.4 DTO 写入校验

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface SxbFieldWriteCheck {

    String resourceCode();

    String sceneCode();

    FieldOperationTypeEnum operationType();

}

 

@SxbFieldWriteCheck(

    resourceCode = "crm.customer",

    sceneCode = "admin.crm.customer.update",

    operationType = FieldOperationTypeEnum.UPDATE

)

@PostMapping("/update")

public Boolean update(@RequestBody CustomerUpdateDTO dto) {

    return customerService.update(dto);

}

 

编辑校验关键点

修改接口不能只判断 DTO 中是否存在字段,还要对比数据库原值。无权限字段如果没有发生变更可放行,如果发生变更必须拒绝。

9.5 QueryFacade 集成

升鲜宝高级查询组件、排序组件、动态列组件必须统一通过 QueryFacade 校验字段权限。禁止业务模块直接拼接用户提交的字段名。

前端提交查询条件

    

QueryFacade 解析 queryFields / sortFields / selectFields

    

FieldPermissionEngine.checkQueryFields()

    

FieldPermissionEngine.checkSortFields()

    

无权限字段直接拒绝

    

构建安全 SQL

 

9.6 导出组件接入

导出必须使用 EXPORT 权限,不能复用页面 READ 权限。导出任务中心必须记录导出字段清单、筛选条件、导出数量、是否包含敏感字段、文件地址和操作人。

export_mode

处理方式

PLAIN

原值导出

MASK

脱敏导出

FORBIDDEN

不允许导出

APPROVAL_REQUIRED

进入审批流程,审批通过后导出

 

9.7 打印、PDF、图片生成接入

打印模板字段不能直接读取业务 VO,必须经过 PRINT / RENDER 权限过滤。客户配送单、对账单、采购单、小票图片、单据 PDF 都需要使用独立的输出场景。

  • 打印模板设计器加载字段时,仅展示 PRINT 允许的字段。
  • 模板已存在的字段,在渲染前还要再次校验。
  • PDF/图片生成场景使用 RENDER 权限,默认比 READ 更严格。
  • 对外单据默认禁止成本价、采购价、毛利、毛利率、内部备注、供应商结算信息。

9.8 分享码接入

分享码访问不能继承当前员工权限,必须构建独立的 SHARE 权限上下文。外部客户、供应商、司机使用不同 share scene_code,默认最小字段集。

FieldPermissionContext context = new FieldPermissionContext();

context.setTenantId(tenantId);

context.setUserId(0L);

context.setTerminalType("SHARE");

context.setResourceCode("oms.deliveryBill");

context.setSceneCode("share.customer.delivery.view");

context.setOperationType(FieldOperationTypeEnum.SHARE);

 

10. 前端接入方案

10.1 字段 Schema 接口

GET /api/system/field-permission/schema

 

Request:

{

  "resourceCode": "pms.goods",

  "sceneCode": "admin.sales.order.create.selectGoods"

}

 

Response:

{

  "resourceCode": "pms.goods",

  "sceneCode": "admin.sales.order.create.selectGoods",

  "versionNo": 12,

  "fields": [

    {

      "fieldCode": "goodsName",

      "fieldName": "商品名称",

      "visible": true,

      "editable": false,

      "queryable": true,

      "sortable": true,

      "exportable": true,

      "printable": true,

      "shareable": true,

      "mask": false,

      "component": "input",

      "sortNo": 10

    },

    {

      "fieldCode": "costPrice",

      "fieldName": "成本价",

      "visible": false,

      "editable": false,

      "queryable": false,

      "sortable": false,

      "exportable": false,

      "printable": false,

      "shareable": false,

      "mask": false,

      "component": "amount",

      "sortNo": 90

    }

  ]

}

 

10.2 Vue3 Hook 封装

useFieldPermission(resourceCode, sceneCode)

 

返回能力:

{

  fieldMap,

  canVisible,

  canEdit,

  canQuery,

  canExport,

  canPrint,

  filterColumns,

  filterFormItems,

  filterQueryItems,

  filterExportFields

}

 

前端组件

接入方式

通用表格

visibleColumns = fieldPermission.filterColumns(allColumns)

通用表单

formItems = fieldPermission.filterFormItems(allFormItems)

字段只读

disabled = !fieldPermission.canEdit("creditLimit")

高级查询

queryFields = fieldPermission.filterQueryItems(allQueryFields)

导出弹窗

exportFields = fieldPermission.filterExportFields(allExportFields)

打印模板设计器

只允许拖入 printable=true 的字段

 

11. 权限配置后台设计

系统设置

└── 权限中心

    ├── 菜单权限

    ├── 按钮权限

    ├── 数据权限

    ├── 字段权限

    │   ├── 字段资源管理

    │   ├── 字段定义管理

    │   ├── 字段场景管理

    │   ├── 字段授权管理

    │   └── 脱敏规则管理

    └── 权限审计日志

 

页面

核心功能

字段资源管理

维护 resource_code、资源名称、领域、模块、主表、VO 类、状态。

字段定义管理

维护 field_code、field_path、db_column、敏感等级、默认权限、脱敏规则、前端组件。

字段场景管理

维护 scene_code、终端、场景类型、业务动作、场景说明。

字段授权管理

选择资源、场景、主体,配置读取/编辑/查询/排序/导入/导出/打印/分享权限。

脱敏规则管理

配置手机号、邮箱、身份证、银行卡、地址、金额区间、自定义脱敏。

审计日志

查询敏感字段访问、越权行为、导出行为、配置变更。

 

11.1 字段授权矩阵

字段

读取

编辑

查询

排序

导出

打印

分享

脱敏

商品名称

原值

只读

允许

允许

原值

允许

允许

手机号

脱敏

只读

禁止

禁止

脱敏

脱敏

脱敏

MOBILE

成本价

隐藏

禁止

禁止

禁止

禁止

禁止

禁止

毛利率

隐藏

禁止

禁止

禁止

审批

禁止

禁止

 

12. 脱敏规则设计

规则编码

规则说明

脱敏示例

MOBILE

手机号

138****5678

EMAIL

邮箱

a***@xx.com

ID_CARD

身份证

3301**********1234

BANK_CARD

银行卡

**** **** **** 1234

ADDRESS

地址

浙江省杭州市***

AMOUNT_RANGE

金额区间

1万-5万

CUSTOM

自定义规则

rule_config 执行

 

脱敏原则

脱敏不是简单字符串替换。必须根据字段类型、字段长度、终端类型、场景类型决定脱敏策略。例如司机可临时拨打客户电话,但页面仍可显示脱敏号码;财务可查看完整客户手机号,但导出时仍可配置脱敏。

13. 缓存设计

字段权限属于高频读取配置,必须使用 Caffeine 本地缓存 + Redis 分布式缓存 + 版本号刷新。

缓存对象

Key 示例

字段权限快照

sxb:field:permission:{tenantId}:{userId}:{resourceCode}:{sceneCode}:{operationType}:{versionNo}

字段定义

sxb:field:define:{tenantId}:{resourceCode}:{versionNo}

场景字段

sxb:field:scene:{tenantId}:{sceneCode}:{versionNo}

主体策略

sxb:field:policy:{tenantId}:{subjectType}:{subjectId}:{versionNo}

 

管理员修改字段权限

    

保存 sys_field_policy / sys_field_policy_item

    

写入 sys_field_policy_change_log

    

sys_field_cache_version.version_no + 1

    

发布 Redis Topic

    

各服务清理 Caffeine 本地缓存

    

下一次请求重新计算权限

 

14. 审计与告警设计

行为

是否记录

风险建议

高敏字段被查看

必须

字段被脱敏

可采样

/中

字段被隐藏

可采样

无权限字段查询

必须

无权限字段排序

必须

无权限字段编辑

必须

无权限字段导出

必须

严重

敏感字段批量导出

必须

严重

打印包含敏感字段

必须

分享码访问敏感字段

必须

严重

 

15. 核心业务模块字段初始化建议

商品模块 pms.goods

字段编码

字段名称

敏感等级

默认策略

goodsName

商品名称

PUBLIC

可见

goodsCode

商品编码

PUBLIC

可见

salePrice

销售价

INTERNAL

销售相关场景可见

purchasePrice

采购价

SECRET

默认隐藏

costPrice

成本价

SECRET

默认隐藏

grossProfitRate

毛利率

SECRET

默认隐藏

inventoryQty

库存数量

INTERNAL

按场景可见

inventoryAmount

库存金额

SECRET

默认隐藏

internalRemark

内部备注

SENSITIVE

默认隐藏

 

客户模块 crm.customer

字段编码

字段名称

敏感等级

默认策略

customerName

客户名称

PUBLIC

可见

contactName

联系人

INTERNAL

可见

contactPhone

手机号

SENSITIVE

默认脱敏

address

地址

SENSITIVE

按数据权限

creditLimit

授信额度

SECRET

财务/老板可见

accountPeriodDays

账期

SECRET

财务/老板可见

receivableBalance

应收余额

SECRET

财务/老板可见

internalRemark

内部备注

SENSITIVE

默认隐藏

 

供应商模块 sup.supplier

字段编码

字段名称

敏感等级

默认策略

supplierName

供应商名称

PUBLIC

可见

contactName

联系人

INTERNAL

可见

contactPhone

手机号

SENSITIVE

默认脱敏

bankAccount

银行账户

CRITICAL

默认禁止

bankName

开户行

SECRET

财务可见

payableBalance

应付余额

SECRET

财务/老板可见

internalRating

内部评价

SENSITIVE

采购主管可见

 

销售订单 oms.salesOrder

字段编码

字段名称

敏感等级

默认策略

orderNo

订单编号

PUBLIC

可见

customerName

客户名称

PUBLIC

可见

goodsName

商品名称

PUBLIC

可见

qty

数量

PUBLIC

可见

salePrice

销售单价

INTERNAL

销售/财务可见

amount

金额

INTERNAL

销售/财务可见

costPrice

成本价

SECRET

默认隐藏

grossProfitRate

毛利率

SECRET

默认隐藏

internalRemark

内部备注

SENSITIVE

默认隐藏

 

WMS 模块 wms.stockIn / wms.stockOut

字段编码

字段名称

敏感等级

默认策略

warehouseName

仓库

PUBLIC

可见

locationCode

库位

INTERNAL

仓管可见

batchNo

批次

INTERNAL

仓管可见

productionDate

生产日期

INTERNAL

仓管可见

inventoryQty

库存数量

INTERNAL

仓管可见

inventoryAmount

库存金额

SECRET

财务/老板可见

costPrice

成本价

SECRET

默认隐藏

 

财务模块 fin.receivable / fin.payable

字段编码

字段名称

敏感等级

默认策略

receivableAmount

应收金额

SECRET

财务/老板可见

receivedAmount

已收金额

SECRET

财务/老板可见

unpaidAmount

未收金额

SECRET

财务/老板可见

payableAmount

应付金额

SECRET

财务/老板可见

bankAccount

银行账户

CRITICAL

财务主管可见

voucherRemark

凭证备注

SENSITIVE

财务可见

 

16. 默认角色权限建议

角色

建议权限

老板

大部分业务字段可见;成本、毛利、余额可见;敏感导出必须记录日志;银行账号、身份证等建议二次验证或审批。

财务

应收、应付、账期、授信、余额、成本金额可见;导出敏感字段需要审计。

采购

采购价、供应商联系人可见;供应商结算账户默认不可见;客户财务信息不可见。

销售

销售价、客户基础信息可见;手机号默认脱敏或按客户归属显示;成本价、毛利率不可见。

仓管

库存数量、库位、批次、生产日期可见;价格类字段和库存金额默认不可见。

司机

仅配送任务相关字段可见;客户地址可见;客户电话可脱敏或临时拨打;金额、成本、毛利不可见。

门店店员

门店商品、库存、销售价可见;成本价不可见;客户隐私脱敏。

 

17. 一次性落地重构路线

 

3 一次性底座重构 + 分批接入路线

阶段

交付内容

验收标准

第一阶段:统一底座

11 张核心表、fieldpermission 模块、引擎、上下文、策略合并、脱敏、缓存、审计、Schema API、基础后台页面。

字段权限底座可独立运行。

第二阶段:公共组件

通用表格、表单、高级查询、导入导出、打印、PDF/图片、分享码组件接入。

公共组件可根据 Schema 自动控制字段。

第三阶段:核心模块

商品、客户、供应商、销售订单、采购订单、WMS、财务接入。

核心敏感字段不再泄露。

第四阶段:历史接口兼容

通过 sys_field_api_bind 绑定老接口,减少 Controller 改造。

老接口也能执行字段过滤。

第五阶段:灰度上线

逐步开启 read-filter、write-check、query-check、export-check、print-check、share-check。

可按租户/模块/场景灰度。

第六阶段:审计优化

敏感访问审计、越权告警、导出审批、性能优化、SQL 字段裁剪。

安全闭环形成。

 

18. 灰度开关设计

field.permission.enabled=true

field.permission.schema.enabled=true

field.permission.read-filter.enabled=false

field.permission.write-check.enabled=false

field.permission.query-check.enabled=false

field.permission.export-check.enabled=false

field.permission.print-check.enabled=false

field.permission.share-check.enabled=false

 

推荐上线顺序:先开启 Schema,再开启前端隐藏,再开启后端返回过滤,再开启查询校验、编辑校验,最后开启导出、打印、分享强校验。

19. 测试与验收标准

19.1 后端验收

验收项

标准

字段资源

所有核心模块已注册 resource_code。

字段定义

核心 VO 字段已入库,敏感等级准确。

场景定义

列表、详情、表单、导出、打印、分享均有 scene_code。

返回过滤

无权限字段不会返回原值。

编辑校验

无权限字段不能被修改。

查询校验

无权限字段不能作为查询条件。

排序校验

无权限字段不能排序。

导出过滤

无权限字段不能导出,敏感字段导出有日志或审批。

打印过滤

无权限字段不能打印或渲染到 PDF/图片。

分享过滤

外部分享不泄露内部字段。

缓存刷新

权限配置修改后能实时生效。

 

19.2 安全用例

测试用例

预期结果

普通销售员查看商品成本价

看不到,返回 null 或字段不存在。

普通销售员抓包请求成本价

后端仍然不返回原值。

普通销售员使用成本价查询

后端拒绝并记录越权日志。

普通销售员修改客户授信额度

后端拒绝。

仓管导出商品库存金额

后端拒绝或走审批。

客户扫码查看配送单

不出现成本、毛利、内部备注。

司机查看配送任务

只看到配送所需信息。

财务导出客户余额

允许但记录敏感导出日志。

 

20. 性能与演进建议

不要第一版直接全局 SQL 拦截

MyBatis-Plus InnerInterceptor 可作为后期优化。第一版建议采用 VO 返回过滤 + DTO 写入校验 + QueryFacade 字段校验,风险最低、落地最快。

阶段

策略

第一版

VO 过滤 + DTO 校验 + QueryFacade 查询/排序校验。

第二版

QueryFacade SELECT 字段裁剪,减少无权限字段查询。

第三版

MyBatis-Plus InnerInterceptor 增强,多表 join、别名、子查询逐步支持。

长期演进

字段级审批、字段级水印、字段访问画像、异常导出告警、字段级数据血缘。

 

21. 最终落地检查清单

  • 已创建 11 张字段权限核心表。
  • 已实现 FieldPermissionEngine 及策略合并规则。
  • 已实现字段 Schema API。
  • 已实现 ResponseBodyAdvice 返回过滤。
  • 已实现 DTO 新增/修改字段校验。
  • 已实现 QueryFacade 查询字段与排序字段校验。
  • 已实现导出字段过滤和导出日志。
  • 已实现打印、PDF、图片、分享码字段过滤。
  • 已实现脱敏规则中心。
  • 已实现 Redis + Caffeine 缓存和版本刷新。
  • 已实现字段权限配置后台。
  • 已完成商品、客户、供应商试点。
  • 已完成销售订单、采购、WMS、财务核心模块接入。
  • 已完成安全测试、越权测试、导出测试、分享码测试。

22. 附录:初始化 SQL 示例

-- 脱敏规则初始化

INSERT INTO sys_field_mask_rule

(id, tenant_id, rule_code, rule_name, rule_type, rule_config, example_before, example_after,

    status)

VALUES

(1, 0, 'MOBILE', '手机号脱敏', 'MOBILE', JSON_OBJECT('prefix',3,'suffix',4), '13812345678',

    '138****5678', 1),

(2, 0, 'EMAIL', '邮箱脱敏', 'EMAIL', JSON_OBJECT('prefix',1), 'abc@test.com', 'a***@test.com', 1),

(3, 0, 'ID_CARD', '身份证脱敏', 'ID_CARD', JSON_OBJECT('prefix',4,'suffix',4), '330102199001011234',

    '3301**********1234', 1),

(4, 0, 'BANK_CARD', '银行卡脱敏', 'BANK_CARD', JSON_OBJECT('suffix',4), '6222021234567890123', '****

    **** **** 0123', 1);

 

-- 商品资源初始化

INSERT INTO sys_field_resource

(id, tenant_id, resource_code, resource_name, domain_code, module_code, main_table, vo_class,

    status)

VALUES

(1001, 0, 'pms.goods', '商品档案', 'pms', 'goods', 'pms_goods', 'com.sxb.pms.vo.GoodsVO', 1);

 

-- 商品高敏字段示例

INSERT INTO sys_field_define

(id, tenant_id, resource_code, field_code, field_name, field_path, db_table, db_column,

 data_type, sensitivity_level, default_read_mode, default_export_mode, default_share_mode,

     status)

VALUES

(1101, 0, 'pms.goods', 'costPrice', '成本价', 'costPrice', 'pms_goods', 'cost_price',

 'decimal', 4, 'HIDE', 'FORBIDDEN', 'FORBIDDEN', 1),

(1102, 0, 'pms.goods', 'grossProfitRate', '毛利率', 'grossProfitRate', 'pms_goods',

    'gross_profit_rate',

 'decimal', 4, 'HIDE', 'FORBIDDEN', 'FORBIDDEN', 1);

 

23. 附录:接口清单建议

接口

方法

说明

/api/system/field-resource/page

GET

字段资源分页

/api/system/field-resource/save

POST

新增/修改字段资源

/api/system/field-define/page

GET

字段定义分页

/api/system/field-define/import-from-vo

POST

VO 扫描导入字段定义

/api/system/field-scene/page

GET

字段场景分页

/api/system/field-policy/save

POST

保存字段授权策略

/api/system/field-permission/schema

GET

获取当前用户字段 Schema

/api/system/field-mask-rule/page

GET

脱敏规则分页

/api/system/field-audit/page

GET

字段权限日志查询

/api/system/field-cache/refresh

POST

刷新字段权限缓存版本

 

24. 结论

最终推荐方案

升鲜宝统一字段权限应作为系统级基础能力建设,而不是单个模块的补丁。最终落地形态是:字段资源中心 + 字段定义中心 + 业务场景中心 + 授权策略中心 + 脱敏中心 + 字段权限引擎 + 前端 Schema + 后端全链路强校验 + 审计告警。

按本文档方案落地后,升鲜宝可以在不反复推翻业务代码的前提下,逐步将商品、客户、供应商、订单、采购、WMS、财务、POS、小程序、打印、分享码等能力纳入统一字段安全底座。

http://www.jsqmd.com/news/719496/

相关文章:

  • 2026年昆明代理记账与工商变更全生命周期企业财税服务深度横评指南 - 优质企业观察收录
  • 2026最新硅胶复模厂家推荐!广东优质源头企业权威榜单发布,深圳高性价比靠谱厂家精选 - 十大品牌榜
  • 技术深度解析:InstructPix2Pix 指令驱动的图像编辑架构与3大核心技术实现
  • RAG架构中重排序模型的核心价值与实战评测
  • PyCharm远程开发踩坑记:那个让我折腾半天的‘host-status’错误,原来重启服务器就能搞定
  • 厂房无尘室洁净室工程公司怎么选?专业洁净室施工与改造扩建推荐指南 - 品牌2026
  • 老年旅游加盟选对品牌=稳盈利!4家合规品牌对比,全扶持低风险,创业者优选 - 品牌策略主理人
  • 两串锂电池充电芯片模块板电压浮动范围
  • 玄机网络安全靶场:Hadoop YARN ResourceManager 未授权 RCE WP
  • 【教训总结】2026年5月天梭官方售后网点核验报告:踩坑实录与避坑指南 - 亨得利官方服务中心
  • 学 Simulink——基于 Simulink 的 LCL 滤波器谐振抑制与有源阻尼设计
  • AI开发-python-langchain框架(--常用的几种文本分割 )
  • 2026年西藏装配式建筑产业基地与拉萨轻质混凝土墙板完全选购指南 - 优质企业观察收录
  • 把2012款Mac Mini改造成家庭影音中心:Monterey系统下的播放器、音量调节与远程管理配置
  • 2026最新手板复模厂家/源头工厂/工厂推荐!广东优质智造榜单发布,实力靠谱深圳手板复模厂商精选 - 十大品牌榜
  • 大模型评估实战:从指标设计到企业级落地
  • 【横评】2026年5月帝舵官方售后网点核验报告:亲历踩坑实录与防坑指南 - 亨得利官方服务中心
  • 别再折腾ST-Link了!用Proteus仿真STM32调试HAL库代码,效率提升不止一倍
  • 告别‘夜盲症’:用PyTorch复现这篇极低光去噪论文(附代码与SE模块详解)
  • 【老司机分享】2026年5月劳力士官方售后网点核验报告:踩坑实录与防坑指南 - 亨得利官方服务中心
  • STM32F103驱动0.96寸OLED:模拟IIC vs 硬件IIC,到底该选哪个?
  • 2026 年甘肃省【彩砖 / 渗水砖 / PC 砖 / 道牙砖 / 六角砖】生产厂家 TOP5 推荐(全省供货・西北配送) - 深度智识库
  • 边缘计算时序模型选型与工业应用实战
  • 【大白话说Java面试题】【Java基础篇】第19题:HashMap的key如何减少发生哈希冲突
  • 从VCU到MCU:一份给新能源汽车三电工程师的HiL测试避坑指南(含BMS故障注入实战)
  • 不只是跑包:用EWSA Pro中文版做一次完整的家庭Wi-Fi安全自检(附防破解建议)
  • 2026年4月北京灭蟑螂/灭老鼠/除蟑螂/除老鼠/消杀公司解析,认准北京祥尔生物科技有限公司 - 2026年企业推荐榜
  • 终极指南:如何用OmenSuperHub完全掌控暗影精灵风扇与性能
  • 厂房无尘室洁净室工程必看!设计施工一体化承包与改造扩建核心要点 - 品牌2026
  • 树莓派miniDLNA服务配置详解:从/media目录权限到外挂NTFS硬盘的避坑全记录