客户数据权限控制实现指南
📅 创建日期:2025-10-27
📌 版本:v1.0
📋 目录
实现概述
已完成的工作 ✅
- ✅ DataScope 注解扩展 - 添加了
customerAlias参数 - ✅ DataScopeAspect 切面扩展 - 实现了客户权限过滤逻辑(DATA_SCOPE_CUSTOMER = “6”)
- ✅ 6个 Mapper XML 修改 - 所有查询都已添加
${params.dataScope}占位符 - ✅ Domain 实体类更新 - 子任务和处理记录添加了
customerId字段 - ✅ 数据库迁移脚本创建 -
db/add_customer_id_to_subtask_tables.sql - ✅ BzCustomerServiceImpl - 已添加
@DataScope注解
待完成的工作 ⏸️
还需要为5个 Service 实现类添加 @DataScope 注解
必须执行:数据库迁移
⚠️ 重要提示
在修改 Service 类之前,必须先执行数据库迁移脚本!
执行步骤
# 进入项目目录
cd H:\gitea-code-2025\HuaweiCloud\husky-afterservice
# 执行数据库脚本
mysql -u root -p husky_afterservice_db < db/add_customer_id_to_subtask_tables.sql
脚本功能
该脚本会自动完成以下操作:
- ✅ 为
bz_work_order_subtask表添加customer_id字段 - ✅ 为
bz_subtask_process_record表添加customer_id字段 - ✅ 从工单表回填历史数据的
customer_id - ✅ 创建索引
idx_customer_id以提升查询性能 - ✅ 输出数据完整性验证报告
验证迁移结果
执行以下 SQL 验证数据完整性:
-- 应该没有空值或不匹配的记录
SELECT
'bz_work_order_subtask' AS table_name,
COUNT(*) AS total,
COUNT(customer_id) AS filled,
COUNT(*) - COUNT(customer_id) AS missing
FROM bz_work_order_subtask
UNION ALL
SELECT
'bz_subtask_process_record',
COUNT(*),
COUNT(customer_id),
COUNT(*) - COUNT(customer_id)
FROM bz_subtask_process_record;
待完成:Service 类修改
修改清单
需要为以下5个 Service 实现类添加 @DataScope 注解:
| # | Service 类 | 文件路径 | 方法名 | customerAlias | 状态 |
|---|---|---|---|---|---|
| 1 | BzProjectServiceImpl | .../service/impl/BzProjectServiceImpl.java |
selectBzProjectList |
p |
⏸️ 待完成 |
| 2 | BzProjectEquipmentServiceImpl | .../service/impl/BzProjectEquipmentServiceImpl.java |
selectBzProjectEquipmentList |
pe |
⏸️ 待完成 |
| 3 | BzWorkOrderServiceImpl | .../service/impl/BzWorkOrderServiceImpl.java |
selectBzWorkOrderList |
w |
⏸️ 待完成 |
| 4 | BzWorkOrderSubtaskServiceImpl | .../service/impl/BzWorkOrderSubtaskServiceImpl.java |
selectBzWorkOrderSubtaskList |
st |
⏸️ 待完成 |
| 5 | BzSubtaskProcessRecordServiceImpl | .../service/impl/BzSubtaskProcessRecordServiceImpl.java |
selectBzSubtaskProcessRecordList |
r |
⏸️ 待完成 |
修改步骤(针对每个类)
步骤1:添加 import 语句
在文件顶部的 import 区域添加:
import com.husky.common.annotation.DataScope;
步骤2:添加注解
在 selectXxxList 方法的 @Override 注解下方添加:
@DataScope(customerAlias = "表别名")
示例:BzProjectServiceImpl
修改前:
@Override
public List<BzProject> selectBzProjectList(BzProject bzProject)
{
return bzProjectMapper.selectBzProjectList(bzProject);
}
修改后:
import com.husky.common.annotation.DataScope;
...
@Override
@DataScope(customerAlias = "p")
public List<BzProject> selectBzProjectList(BzProject bzProject)
{
return bzProjectMapper.selectBzProjectList(bzProject);
}
customerAlias 对照表
确保 customerAlias 与 Mapper XML 中的表别名完全一致:
| Service | Mapper XML 中的别名 | customerAlias 值 |
|---|---|---|
| BzProjectServiceImpl | p (from bz_project p) |
"p" |
| BzProjectEquipmentServiceImpl | pe (from bz_project_equipment pe) |
"pe" |
| BzWorkOrderServiceImpl | w (from bz_work_order w) |
"w" |
| BzWorkOrderSubtaskServiceImpl | st (from bz_work_order_subtask st) |
"st" |
| BzSubtaskProcessRecordServiceImpl | r (from bz_subtask_process_record r) |
"r" |
测试验证
测试前准备
- ✅ 确认数据库迁移已执行
- ✅ 确认所有 Service 类已添加注解
- ✅ 重新编译项目:
mvn clean package - ✅ 重启应用服务器
测试场景
测试1:单客户权限
步骤:
- 创建测试角色”角色A”,设置
data_scope = '6' - 在角色管理界面,为”角色A”授权客户1
- 创建测试用户,分配”角色A”
- 使用该用户登录系统
- 查询客户列表、项目列表、工单列表
预期结果:
- 只能看到客户1的数据
- 只能看到客户1的项目
- 只能看到客户1的工单
测试2:多客户权限
步骤:
- 修改”角色A”,授权客户1、2、3
- 登录查询
预期结果:
- 可以看到客户1、2、3的所有数据
测试3:超级管理员
步骤:
- 使用 admin 账号登录
- 查询所有数据
预期结果:
- 可以看到所有客户的数据(权限检查被跳过)
验证 SQL 是否正确生成
开启 MyBatis SQL 日志(application.yml):
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
重启后,查询列表时会在控制台看到类似的 SQL:
SELECT * FROM bz_customer
WHERE del_flag = '0'
AND bz_customer.customer_id IN (
SELECT customer_id FROM sys_role_customer WHERE role_id = 100
)
故障排查
问题1:权限不生效,可以看到所有数据
排查步骤:
检查角色的
data_scope字段:SELECT role_id, role_name, data_scope FROM sys_role WHERE role_id = ?;应该为
'6'检查
sys_role_customer表是否有数据:SELECT * FROM sys_role_customer WHERE role_id = ?;检查 Service 方法是否添加了
@DataScope注解清理缓存并重启应用
问题2:查询结果为空
排查步骤:
- 检查
customerAlias是否正确:`java
// 错误示例(别名不匹配)
@DataScope(customerAlias = “customer”) // XML中是 bz_customer
// 正确示例
@DataScope(customerAlias = “bz_customer”) // 与XML一致
2. 检查表中是否有 `customer_id` 数据:
```sql
SELECT COUNT(*) FROM bz_customer WHERE customer_id IS NOT NULL;- 检查生成的 SQL(查看日志)
问题3:子任务数据不一致
症状: 子任务的 customer_id 与工单不匹配
解决方案:
重新执行数据回填:
UPDATE bz_work_order_subtask st INNER JOIN bz_work_order wo ON st.order_id = wo.order_id SET st.customer_id = wo.customer_id;检查应用层代码是否正确设置
customer_id
权限过滤原理
SQL 生成示例
原始查询:
SELECT * FROM bz_work_order w
WHERE w.del_flag = '0'
添加权限过滤后:
SELECT * FROM bz_work_order w
WHERE w.del_flag = '0'
AND w.customer_id IN (
SELECT customer_id FROM sys_role_customer WHERE role_id = 100
)
多角色权限合并
当用户拥有多个角色时:
WHERE (
w.customer_id IN (SELECT customer_id FROM sys_role_customer WHERE role_id = 100)
OR w.customer_id IN (SELECT customer_id FROM sys_role_customer WHERE role_id = 101)
)
附录:完整修改清单
已修改的文件 ✅
| 类型 | 文件名 | 说明 |
|---|---|---|
| 注解 | DataScope.java | 添加 customerAlias 参数 |
| 切面 | DataScopeAspect.java | 实现客户权限过滤逻辑 |
| Mapper | BzCustomerMapper.xml | 添加权限过滤占位符 |
| Mapper | BzProjectMapper.xml | 添加权限过滤占位符 |
| Mapper | BzProjectEquipmentMapper.xml | 添加权限过滤占位符 |
| Mapper | BzWorkOrderMapper.xml | 添加权限过滤占位符 |
| Mapper | BzWorkOrderSubtaskMapper.xml | 添加权限过滤占位符 |
| Mapper | BzSubtaskProcessRecordMapper.xml | 添加权限过滤占位符 |
| Domain | BzWorkOrderSubtask.java | 添加 customerId 字段 |
| Domain | BzSubtaskProcessRecord.java | 添加 customerId 字段 |
| Service | BzCustomerServiceImpl.java | 添加 @DataScope 注解 |
| SQL | add_customer_id_to_subtask_tables.sql | 数据库迁移脚本 |
待修改的文件 ⏸️
| 文件名 | 需要添加的内容 |
|---|---|
| BzProjectServiceImpl.java | @DataScope(customerAlias = "p") |
| BzProjectEquipmentServiceImpl.java | @DataScope(customerAlias = "pe") |
| BzWorkOrderServiceImpl.java | @DataScope(customerAlias = "w") |
| BzWorkOrderSubtaskServiceImpl.java | @DataScope(customerAlias = "st") |
| BzSubtaskProcessRecordServiceImpl.java | @DataScope(customerAlias = "r") |
快速参考
角色配置流程
- 登录系统 → 系统管理 → 角色管理
- 新建/编辑角色
- 设置数据范围为”客户数据权限”
- 在客户权限标签页勾选授权的客户
- 保存
权限类型说明
| 数据范围 | 代码 | 说明 |
|---|---|---|
| 全部数据权限 | 1 | 查看所有数据 |
| 自定义数据权限 | 2 | 基于部门 |
| 部门数据权限 | 3 | 仅本部门 |
| 部门及以下 | 4 | 本部门+下级部门 |
| 仅本人数据 | 5 | 仅自己创建的 |
| 客户数据权限 | 6 | 仅授权的客户 |
如有疑问,请查看完整的技术文档或联系开发团队。
作者:聂盼盼 创建时间:2025-10-27 17:20
最后编辑:聂盼盼 更新时间:2025-10-28 19:53
最后编辑:聂盼盼 更新时间:2025-10-28 19:53