梁华东
Published on 2025-08-15 / 81 Visits
0
0

数据隔离使用说明

一、 数据范围策略配置

需要使用,产品、物料、线体、车间、仓库、客户维度隔离采用以下方案。

  1. 登陆系统后:

  1. 添加策略新增数据范围,有多种维度可选择,一旦创建后不可变更

数据范围类型有7 10产品 20物料 30线体 40车间 50仓库 60客户 1000其他其他为自定义

  1. 添加资源可进行编辑新增或去除资源

  1. 维度授权

给资源授权相关的角色或用户。

  1. 开发接口使用

提供 OpenAPI 接口查询用户的数据维度权限,并按资源类型整合。页面可根据返回的 ID/Code 精确查询,如限制访问的页面必须传产品 ID/Code;也可在后端接口根据权限范围直接限制逻辑。

接口具体详情可查看mbm的openapi文档

调用流程如下:

请求以token来获取当前用户

返回值示例

10产品 20物料 30线体 40车间 50仓库 60客户 1000其他

       {

    "status""200",

    "message""success",

    "data": [

        {

            "data_scope_type"1000,

            "data_scope_detail_list": [

                {

                    "data_scope_value_id""123",

                    "data_scope_value_code""test"

                }

            ]

        },

        {

            "data_scope_type"10,

            "data_scope_detail_list": [

                {

                    "data_scope_value_id""1942511613201539073",

                    "data_scope_value_code""part_0708_barcode"

                },

                {

                    "data_scope_value_id""1943213413365899265",

                    "data_scope_value_code""Huawei25ProMax"

                }

            ]

        }

    ],

    "i18n"null

}

二、工厂维度隔离

为保障多工厂(site)场景下的数据隔离安全,行业包自己的功能需要实现统一的 siteId 工厂隔离机制

1. 业务数据表需按 siteId 字段进行工厂级别的隔离。

2. 实体类通过@Table(value = "SieMpmProjectDynamic",enableSite =true )

3. 查询时,系统应默认在构造 QueryWrapper 时自动追加 siteId = 当前上下文站点 的过滤条件,确保数据隔离。

4. 特殊场景(如运营后台跨工厂查询、超管权限)需提供跳过 siteId 自动过滤的能力。

5. 当前用户所属站点信息通过上下文HuaweiTenantContextHolder 进行管理,并支持线程隔离。

  1. 需隔离的工厂建模

实体继承 BaseSiteEntity 并加入enableSite =true 实现 siteId 显式建模

@Table(value = "SieMpmProjectDynamic",enableSite =true )

public class MpmProjectDynamic extends BaseEntity<MpmProjectDynamic> {

/**

* ID

*/

@TableId(type = IdType.ASSIGN_ID)

private Long id;

}

  1. 查询自动加入过滤

d

  1. 特殊查询可选择跳过 siteId 限制

QueryWrapper wrapper = QueryWrapper.create()

.setIgnoreSite(true)

.and("status", "active");

  1. 插入数据

插入数据底层进行自动填siteID

原理如下:

/**

* 自动填充siteID

*

* @param entities

*/

private void autoFillSite(List<?> entities) {

if (CollectionUtil.isEmpty(entities))

return;

Optional<HuaweiTenantContextInfo> dmeTenantContextInfo = Optional.ofNullable(HuaweiTenantContextHolder.get());

String siteId = dmeTenantContextInfo.map(t -> t.getSiteId()).orElse(null);

if (StringUtils.isEmpty(siteId))

return;

List<EntityMetaObject> entityMetaObjectList = DmeDelegatorJsonUtil.entityToMetaObjectList(entities);

entityMetaObjectList.forEach(entityMetaObject -> {

if (entityMetaObject.hasField("siteId")) {

if (ObjectUtils.isEmpty(entityMetaObject.getValue("siteId"))) {

entityMetaObject.setValue("siteId", siteId);

}

}

});

}


Comment