华为云:集团企业资产系统,真正的难点不在功能,而在组织模型与数据权限
集团型企业搭建资产系统,对外呈现的功能清单往往大同小异,真正决定这套系统能不能落地用好、能不能支撑财务、运维、审计长期可信使用的核心,是组织模型设计与数据权限体系。
单组织场景下,“谁能看什么数据” 是简单问题:全员可见或者管理员管控。一旦进入集团化架构 —— 总部、分公司、子公司、项目部、托管机房共用一套资产平台,这个问题复杂度会成倍上升:
- 集团资产部需要查看全集团资产台账,分公司管理员仅可查看本片区资产;
- 财务关注资产产权归属,运维关注资产位置与管护责任,同一台设备,两类角色看到的台账信息不一样;
- 资产从 A 分公司调拨至 B 分公司,在途期间资产归属该如何界定?
- 组织发生合并、拆分、更名后,历史统计报表会不会跟着口径错乱?
这类问题在需求调研阶段很容易被忽略,往往上线半年后集中暴露,并且大部分问题都需要调整底层数据模型才能修复。本文按照建模 → 归属 → 权限 → 调拨 → 组织变更的顺序,拆解华为云资产多租户场景下的落地设计方案。
一、组织建模:不要只用一张扁平表实现
1.1 组织单元需要支持多口径并行关系
最常见的设计误区,是组织表只做带 parent_id 的扁平树,认为一套组织树就能覆盖全部业务。但集团企业里,至少有三套组织结构并行使用:
表格
| 结构 | 用途 | 举例 |
|---|---|---|
| 行政组织 | 人事、考核、管理口径 | 集团 → 华东分公司 → 苏州办事处 |
| 成本核算组织 | 财务折旧、成本归集口径 | 集团 → 制造事业群 → 一厂 |
| 区域位置组织 | 资产实物存放、运维责任口径 | 华东区 → 苏州 IDC → B3 机房 |
一台服务器,可能产权归属制造事业群、运维责任归属华东分公司、物理位置在苏州 IDC。如果资产仅绑定单一 org_id,三类口径必然冲突。
推荐方案:按业务口径独立维护多棵组织树(至少行政树 + 位置树),资产实体独立记录 owner_org_id(产权)、use_org_id(使用 / 运维)、location_id(位置),三个字段可以分别指向不同组织树节点。不要尝试单棵组织树加类型字段兼容所有口径 —— 组织架构调整时,单树无法同时满足财务、运维两套统计规则。
1.2 组织树技术方案:邻接表 + 路径冗余
邻接表(parent_id)维护简单,但高频查询 “本组织及全部下级” 时会触发递归,千万级资产场景下做权限过滤,性能会严重不足。
工程化方案:邻接表 + 冗余路径字段
CREATE TABLE sys_org (
org_id BIGINT PRIMARY KEY,
org_name VARCHAR(128) NOT NULL,
parent_id BIGINT,
tree_type VARCHAR(16) NOT NULL COMMENT 'ADMIN=行政树 / LOCATION=位置树 / COST=核算树',
id_path VARCHAR(512) NOT NULL COMMENT '从根到本节点的ID路径,如 /1/12/125/',
name_path VARCHAR(1024) COMMENT '冗余名称路径,报表直接展示用',
level_no INT NOT NULL,
status TINYINT NOT NULL DEFAULT 1,
INDEX idx_path (tree_type, id_path)
);
id_path 前缀匹配,直接实现 “查询该组织及所有下级”,命中索引,规避递归:
-- 查询组织 12 及其所有下级范围内的资产
SELECT a.*
FROM asset a
JOIN sys_org o ON a.owner_org_id = o.org_id
WHERE o.tree_type = 'ADMIN'
AND o.id_path LIKE '/1/12/%';
代价是组织调整时,需要批量更新子树 id_path。这个取舍是合理的:组织变更属于低频操作(按月 / 季度),而权限过滤是每次查询都要执行的高频动作,把计算成本放在低频环节。
1.3 虚拟组织:项目组、临时团队
很多资产跟随项目周期流转:一个两年期技改项目,从各部门调拨设备,项目结束后资产归还原部门。直接新建行政节点会污染主组织树,不建节点又无法独立统计项目资产。
方案:引入虚拟组织标识 is_virtual = 1。人员归属沿用行政组织,资产通过 use_org_id 挂载至虚拟组织;统计报表支持配置是否展开虚拟组织。核心约束:虚拟组织不能作为产权归属主体,无法人主体,无法计提折旧。
二、资产归属:三大维度解耦
这是多组织资产设计里最容易模糊、需要提前对齐口径的核心点。
表格
| 维度 | 字段 | 业务含义 | 使用方 |
|---|---|---|---|
| 产权归属 | owner_org_id | 资产所属主体、折旧计提主体 | 财务 |
| 使用 / 运维归属 | use_org_id | 管护责任、日常运维主体 | 运维、行政 |
| 物理位置 | location_id | 资产当前存放地点 | 运维、机房管理 |
三维度解耦,天然支持集团内部调拨、借用、代管、托管场景。一台设备产权在总部,借给子公司使用、存放于子公司机房,在单归属模型中只能备注记录,统计、对账极易出错。
落地建议:不用一步到位实现三权分离。如果企业当前都是自购自用模式,可以先落地产权 + 使用两维度,预留位置字段,避免过度设计,造成一线填报负担。组织模型需要匹配业务成熟度。
三、数据权限:行级、字段级、功能级三层管控
3.1 行级权限:组织范围过滤,条件下推 SQL
行级权限控制用户可以看到哪些资产数据。核心原则:权限范围解析为 SQL 过滤条件,在数据库层过滤,不要查全量数据后在内存过滤。
/**
* 数据权限上下文解析与 SQL 片段生成
*
* 模块:数据权限(DataScope)
*/
public final class DataScope {
/** 全部数据 */
public static final String ALL = "ALL";
/** 仅本组织及下级 */
public static final String ORG_AND_CHILD = "ORG_AND_CHILD";
/** 仅本组织 */
public static final String ORG_ONLY = "ORG_ONLY";
/** 仅本人相关资产(使用人/保管人) */
public static final String SELF = "SELF";
/** 自定义组织集合 */
public static final String CUSTOM = "CUSTOM";
private final String scopeType;
private final Set<Long> customOrgIds;
private final Long orgId; // 用户所属组织
private final Long userId;
public DataScope(String scopeType, Set<Long> customOrgIds, Long orgId, Long userId) {
this.scopeType = scopeType;
this.customOrgIds = customOrgIds == null ? Collections.emptySet() : customOrgIds;
this.orgId = orgId;
this.userId = userId;
}
/**
* 生成资产表的行级过滤条件。
* 约定:别名 a 指向 asset 表,sys_org 以 EXISTS 子查询接入,
* 避免 JOIN 带来重复行(一台资产可能同时命中owner/use两条组织路径)。
*/
public String toAssetPredicate(String orgField) {
switch (scopeType) {
case ALL:
return "1 = 1";
case ORG_ONLY:
return "a." + orgField + " = " + orgId;
case ORG_AND_CHILD:
// id_path前缀匹配,走索引,规避递归
return "EXISTS (SELECT 1 FROM sys_org o WHERE o.org_id = a." + orgField
+ " AND o.id_path LIKE (SELECT p.id_path FROM sys_org p WHERE p.org_id = " + orgId + ") || '%')";
case SELF:
// 使用人或保管人为本人
return "(a.custodian_id = " + userId + " OR a.used_by = " + userId + ")";
case CUSTOM:
if (customOrgIds.isEmpty()) {
return "1 = 0";
}
return "a." + orgField + " IN (" + StringUtils.join(customOrgIds, ",") + ")";
default:
throw new IllegalArgumentException("不支持的数据范围类型: " + scopeType);
}
}
}
落地关键经验:
- 权限过滤下沉 SQL,内存过滤会造成分页、聚合、导出总数不一致;
- 优先使用 EXISTS,避免 JOIN 导致资产重复计数;
- 数据范围绑定角色,而非绑定用户;一人多岗时,多个角色的权限范围取并集;
- 导出接口复用同一套权限过滤逻辑,很多数据越权风险都出在导出接口。
3.2 字段级权限:敏感信息控制
行权限之外,还要控制同一资产记录里哪些字段可见。资产系统高频敏感字段:
表格
| 字段类别 | 示例 | 管控策略 |
|---|---|---|
| 金额类 | 原值、净值、累计折旧 | 财务、分管领导可见,其余角色脱敏隐藏 |
| 位置类 | 精确机柜位置、涉密载体位置 | 按密级、白名单管控 |
| 个人信息 | 使用人、保管人手机号 | 脱敏返回(138****1234) |
推荐在序列化层统一拦截处理(Jackson 注解、响应拦截器),而不是在每个业务 Service 单独判断,降低遗漏风险。
3.3 功能级权限:操作与单据状态联动
功能权限不止控制按钮显隐,还要结合单据状态做状态机守卫:
- 盘点任务提交后,不允许修改明细;
- 资产处于报废审批流程中,禁止发起调拨;
- 盘点差异未闭环,不支持关闭盘点任务。
状态规则统一收敛在状态机守卫,便于审计追溯操作拦截原因。
四、跨组织调拨:事务、在途、归属切换点
调拨是多组织资产最容易出错的业务,横跨组织、时间、统计口径。
4.1 调拨双阶段模型,显式引入在途状态
流程:DRAFT → OUT_CONFIRMED(调出已确认/在途) → IN_CONFIRMED(调入已确认/完成) 分支:OUT_CONFIRMED可取消;IN_CONFIRMED支持拒收退回至在途。
如果省略在途状态,调拨单创建就直接变更资产归属,实物还在调出方库房,会造成调出方盘亏、调入方盘盈,账实不符。
4.2 明确统计归属切换规则
调拨全周期口径约定:
表格
| 阶段 | 产权归属 | 使用归属 | 位置 |
|---|---|---|---|
| 已提交 | 调出方 | 调出方 | 调出方位置 |
| 在途 | 调出方(未交割) | 调出方 | 标记在途 |
| 调入确认 | 调入方 | 调入方 | 调入方位置 |
产权、使用归属在调入确认节点同步切换,不拆分切换时机,避免折旧、责任划分出现空窗矛盾。
4.3 调拨联动位置与标签
调拨确认完成后,联动两件事:
- 位置同步:对接 U 位管理系统,更新机柜位置,消除台账和机房 U 位数据割裂;
- 资产标签:跨法人调拨优先保留原资产编号,用调拨单建立新旧编号映射,优先保证追溯链路完整。
五、组织变更:历史报表口径不能随组织变形
组织合并、拆分、更名是常态化事件,设计底线:历史报表保留当时统计口径,不能随组织调整自动变更。
方案:资产归属快照表,增加时间有效期
CREATE TABLE asset_org_snapshot (
asset_id BIGINT NOT NULL,
org_id BIGINT NOT NULL,
org_id_path VARCHAR(512) NOT NULL COMMENT '当时的组织路径快照',
org_name_path VARCHAR(1024) COMMENT '当时的组织名称快照,报表直接用',
relation_type VARCHAR(16) NOT NULL COMMENT 'OWNER / USE',
valid_from DATE NOT NULL,
valid_to DATE,
PRIMARY KEY (asset_id, relation_type, valid_from)
);
查询历史周期报表(如 2025 年 Q4 资产统计),按报表时间匹配快照有效期,读取变更前的组织快照,审计可解释。
六、高频踩坑汇总
表格
| 坑点 | 现象 | 对策 |
|---|---|---|
| 权限过滤放内存 | 分页总数不准、导出越权 | SQL 层统一下推过滤,导出复用同一谓词 |
| JOIN 做组织过滤 | 资产数量重复统计 | 改用 EXISTS 子查询 |
| 用户只绑定单一数据范围 | 兼岗人员看不到对应数据 | 多角色权限范围取并集 |
| 仅单棵行政组织树 | 产权、运维、位置口径冲突 | 行政 / 位置 / 核算多树独立设计 |
| 调拨无在途状态 | 盘点盘盈盘亏 | 显式在途状态,交割完成再切换归属 |
| 直接修改历史组织数据 | 历史报表口径错乱 | 归属快照 + 有效期,历史报表读快照 |
七、上线前检查清单
- 组织树是否按业务口径拆分,至少覆盖行政、位置树
- id_path 冗余路径是否建立,子树查询是否走索引
- 数据权限是否下沉 SQL,分页、聚合、导出共用一套过滤条件
- 资产区分产权、使用、物理位置三个归属字段
- 金额、位置、个人敏感字段具备字段级管控与脱敏
- 功能操作和单据状态绑定,状态机统一管控拦截规则
- 调拨流程存在在途状态,归属切换规则文档化对齐
- 组织关系带有效期,历史报表读取资产快照
- 兼岗人员支持多角色数据范围取并集
- 虚拟组织禁止作为产权归属主体
- 点赞
- 收藏
- 关注作者
评论(0)