|
@@ -0,0 +1,120 @@
|
|
|
+package cn.iocoder.yudao.framework.datapermission.core.rule.device;
|
|
|
+
|
|
|
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
|
|
+import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
|
|
|
+import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
|
|
|
+import cn.iocoder.yudao.framework.security.core.LoginUser;
|
|
|
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
|
|
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
|
|
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import net.sf.jsqlparser.expression.Alias;
|
|
|
+import net.sf.jsqlparser.expression.Expression;
|
|
|
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
|
|
+
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+@AllArgsConstructor
|
|
|
+public class DevicePersonDataPermissionRule implements DataPermissionRule {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * LoginUser 的 Context 缓存 Key
|
|
|
+ */
|
|
|
+ protected static final String CONTEXT_KEY = DeptDataPermissionRule.class.getSimpleName();
|
|
|
+
|
|
|
+ private final PermissionApi permissionApi;
|
|
|
+
|
|
|
+ // 设备表名
|
|
|
+ private static final String DEVICE_TABLE = "rq_iot_device";
|
|
|
+ // 设备责任人表名
|
|
|
+ private static final String PERSON_TABLE = "rq_iot_device_person";
|
|
|
+ // 设备ID字段
|
|
|
+ private static final String DEVICE_ID_COLUMN = "id";
|
|
|
+ // 责任人ID字段
|
|
|
+ private static final String PERSON_ID_COLUMN = "person_id";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Set<String> getTableNames() {
|
|
|
+ // 只对设备表生效
|
|
|
+ return Collections.singleton(DEVICE_TABLE);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Expression getExpression(String tableName, Alias tableAlias) {
|
|
|
+ // 只处理设备表
|
|
|
+ if (!DEVICE_TABLE.equalsIgnoreCase(tableName)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前登录用户
|
|
|
+ LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
|
|
+ if (loginUser == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查用户是否拥有全部数据权限
|
|
|
+ if (hasAllDataPermission(loginUser)) {
|
|
|
+ return null; // 拥有全部权限时不添加条件
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 使用字符串解析方式
|
|
|
+ return buildExpressionWithStringParsing(tableAlias, loginUser.getId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 方法1:使用字符串解析构建表达式(兼容性最好)
|
|
|
+ */
|
|
|
+ private Expression buildExpressionWithStringParsing(Alias tableAlias, Long userId) throws Exception {
|
|
|
+ // 构建设备ID列名(带表别名)
|
|
|
+ String deviceColumn = (tableAlias != null ? tableAlias.getName() + "." : "") + DEVICE_ID_COLUMN;
|
|
|
+
|
|
|
+ // 构建子查询SQL
|
|
|
+ String subQuery = String.format(
|
|
|
+ "(SELECT device_id FROM %s WHERE %s = %d)",
|
|
|
+ PERSON_TABLE, PERSON_ID_COLUMN, userId
|
|
|
+ );
|
|
|
+
|
|
|
+ // 构建完整的IN条件表达式
|
|
|
+ String inExpression = String.format("%s IN %s", deviceColumn, subQuery);
|
|
|
+
|
|
|
+ // 解析为Expression对象
|
|
|
+ return CCJSqlParserUtil.parseCondExpression(inExpression);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户是否拥有全部数据权限
|
|
|
+ */
|
|
|
+ private boolean hasAllDataPermission(LoginUser loginUser) {
|
|
|
+ // 1. 尝试从上下文中获取部门数据权限
|
|
|
+ DeptDataPermissionRespDTO deptPermission = loginUser.getContext(
|
|
|
+ CONTEXT_KEY, DeptDataPermissionRespDTO.class);
|
|
|
+
|
|
|
+ // 2. 如果存在且标记为全部权限,返回 true
|
|
|
+ if (deptPermission != null && deptPermission.getAll()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 非管理员用户默认没有全部权限
|
|
|
+ if (!loginUser.getUserType().equals(UserTypeEnum.ADMIN.getValue())) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 重新计算权限(如果上下文没有缓存)
|
|
|
+ deptPermission = permissionApi.getDeptDataPermission(loginUser.getId());
|
|
|
+ if (deptPermission == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 缓存计算结果
|
|
|
+ loginUser.setContext(CONTEXT_KEY, deptPermission);
|
|
|
+
|
|
|
+ return deptPermission.getAll();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|