From c78f6b09925a5987720295cc6ee82990037b9a98 Mon Sep 17 00:00:00 2001 From: FCL Date: Fri, 9 Jan 2026 11:04:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:qms=E6=9D=83=E9=99=90=E7=BB=84=E4=BB=B6-?= =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qms/core/aspect/QmsPermissionAspect.java | 78 ++++++ .../core/aspect/annotation/QmsPermission.java | 27 +++ .../datapermission/QMSDataPermissionDTO.java | 32 +++ .../QMSMultiDataPermissionHandler.java | 227 ++++++++++++++++++ .../QMSPermissionContextHolder.java | 81 +++++++ .../mybatis/QMSDataPermissionConfig.java | 42 ++++ .../admin/DeviceApplyController.java | 1 - .../admin/DeviceConfigFlowController.java | 1 - .../admin/DeviceProductController.java | 2 +- .../device/dal/mapper/DeviceApplyMapper.java | 9 +- .../dal/mapper/DeviceInfomationMapper.java | 2 + .../dal/mapper/DeviceProductMapper.java | 1 - 12 files changed, 496 insertions(+), 7 deletions(-) create mode 100644 zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/QmsPermissionAspect.java create mode 100644 zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/annotation/QmsPermission.java create mode 100644 zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSDataPermissionDTO.java create mode 100644 zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSMultiDataPermissionHandler.java create mode 100644 zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSPermissionContextHolder.java create mode 100644 zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/mybatis/QMSDataPermissionConfig.java diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/QmsPermissionAspect.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/QmsPermissionAspect.java new file mode 100644 index 0000000..37c1bca --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/QmsPermissionAspect.java @@ -0,0 +1,78 @@ +package com.zt.plat.module.qms.core.aspect; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.zt.plat.framework.common.pojo.CommonResult; +import com.zt.plat.framework.common.pojo.PageResult; +import com.zt.plat.framework.security.core.LoginUser; +import com.zt.plat.module.qms.core.aspect.annotation.Dict; +import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission; +import com.zt.plat.module.qms.core.constant.CommonConstant; +import com.zt.plat.module.qms.core.legend.LegendApi; +import com.zt.plat.module.qms.core.legend.LegendConvertUtils; +import com.zt.plat.module.qms.core.legend.vo.DictModel; +import com.zt.plat.module.qms.framework.datapermission.QMSPermissionContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static com.zt.plat.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; +import static com.zt.plat.module.qms.core.constant.CacheConstant.QMS_DICT_BIZ_CACHE; +import static com.zt.plat.module.qms.core.constant.CacheConstant.QMS_DICT_TABLE_CACHE; +import static com.zt.plat.module.qms.core.constant.DataTypeConstant.DICT_ANNOTATION_SPLIT; + +@Aspect +@Component +@Slf4j +public class QmsPermissionAspect { + /** + * 定义切点Pointcut + */ + @Pointcut("@annotation(com.zt.plat.module.qms.core.aspect.annotation.QmsPermission)") + public void executeService() { + } + + @Before("executeService()") + public void doBefore(JoinPoint point) throws Throwable { + handleDataScope(point); + } + + private void handleDataScope(JoinPoint joinPoint){ + QmsPermission annotation = getAnnotationByJoinPoint(joinPoint); + if(annotation == null) + return; + QMSPermissionContextHolder.setContext(true, annotation.deptDataRoleCodes(), annotation.moduleDataRoleCodes(), annotation.deptIdColumn(), annotation.userIdColumn(), annotation.custom()); + } + + private QmsPermission getAnnotationByJoinPoint(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + if (method != null) { + return method.getAnnotation(QmsPermission.class); + } + return null; + } + +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/annotation/QmsPermission.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/annotation/QmsPermission.java new file mode 100644 index 0000000..29379bc --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/core/aspect/annotation/QmsPermission.java @@ -0,0 +1,27 @@ +package com.zt.plat.module.qms.core.aspect.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface QmsPermission { + + boolean enable() default true; //默认开启 + + //部门数据查看权限 + String deptDataRoleCodes() default ""; //指定部门数据查看角色,多值半角逗号分隔 + + //模块数据权限-具有此角色可查看本模块所有数据 + String moduleDataRoleCodes() default "ytjyAdmin"; //指定所有数据查看角色,多值半角逗号分隔 + + String deptIdColumn() default "DEPT_ID"; //部门id列 + + String userIdColumn() default "CREATOR"; //人员id列 + + //todo 考虑支持模块自定义扩展。参数传入表达式,通过表达式计算权限 + String custom() default ""; + +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSDataPermissionDTO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSDataPermissionDTO.java new file mode 100644 index 0000000..3a049c0 --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSDataPermissionDTO.java @@ -0,0 +1,32 @@ +package com.zt.plat.module.qms.framework.datapermission; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.HashSet; +import java.util.Set; + +@Schema(description = "QMS的数据权限 Response DTO") +@Data +public class QMSDataPermissionDTO { + + @Schema(description = "是否可查看全部数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + private Boolean all; + + @Schema(description = "是否可查看自己的数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + private Boolean self; + + @Schema(description = "可查看的部门编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]") + private Set deptIds; + + @Schema(description = "可查看的公司编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]") + private Long companyId; + + public QMSDataPermissionDTO() { + this.all = false; + this.self = false; + this.deptIds = new HashSet<>(); + this.companyId = 0L; + } + +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSMultiDataPermissionHandler.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSMultiDataPermissionHandler.java new file mode 100644 index 0000000..139eea4 --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSMultiDataPermissionHandler.java @@ -0,0 +1,227 @@ +package com.zt.plat.module.qms.framework.datapermission; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; +import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi; +import com.zt.plat.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO; +import com.zt.plat.framework.common.enums.UserTypeEnum; +import com.zt.plat.framework.common.util.collection.CollectionUtils; +import com.zt.plat.framework.common.util.json.JsonUtils; +import com.zt.plat.framework.mybatis.core.util.MyBatisUtils; +import com.zt.plat.framework.security.core.LoginUser; +import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils; +//import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission; +import com.zt.plat.framework.tenant.core.context.DeptContextHolder; +import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.expression.Alias; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.LongValue; +import net.sf.jsqlparser.expression.NullValue; +import net.sf.jsqlparser.expression.operators.conditional.AndExpression; +import net.sf.jsqlparser.expression.operators.conditional.OrExpression; +import net.sf.jsqlparser.expression.operators.relational.*; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.select.ParenthesedSelect; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.SelectItem; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import static java.util.Collections.singletonList; + + +/* +* QMS权限处理 +* 1、只能查看自己创建的数据 +* 2、部门领导可查看本部门数据 +* 3、模块管理员可查看本模块数据 +* +* */ +@Component +@Slf4j +public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler { + + @Autowired private PermissionCommonApi permissionApi; + /** + * LoginUser 的 Context 缓存 Key + */ + protected static final String QMS_PERMISSION_CONTEXT_KEY = "QMS_DATA_PERMISSION"; + static final Expression EXPRESSION_NULL = new NullValue(); + public static final String SYSTEM_USERS = "system_users"; + private static final String SYSTEM_USER_DEPT = "system_user_dept"; + private static final String DEPT_COLUMN_NAME = "dept_id"; + private static final String USER_COLUMN_NAME = "user_id"; + + @Override + public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { + log.error("QMSMultiDataPermissionHandler: Expression={}", where); + + //获取注解 + if(!QMSPermissionContextHolder.shouldExecute()) + return null; + try{ + Expression expression = buildExpression(table, where); + return expression; + }catch (Exception e){ + log.error("QMSMultiDataPermissionHandler: Expression={}", where); + }finally { + QMSPermissionContextHolder.clear(); + } + return EXPRESSION_NULL; + } + + /* + * 构建权限sql*/ + private Expression buildExpression(Table table, Expression where) { + LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); + if (loginUser == null) { + return EXPRESSION_NULL; + } + //管理员用户,不进行权限处理 + if (ObjectUtil.notEqual(loginUser.getUserType(), UserTypeEnum.ADMIN.getValue())) { + return null; + } + String deptIdCol = QMSPermissionContextHolder.getDeptIdColumn(); //部门id列 + String userIdCol = QMSPermissionContextHolder.getUserIdColumn(); //人员id列 + String deptDataRoleCodes = QMSPermissionContextHolder.getDeptDataRoleCode(); //部门数据权限角色。具有该角色,然后按角色的权限属性判断。从而获得人员允许查看的部门数据 + String moduleDataRoleCodes = QMSPermissionContextHolder.getModuleDataRoleCodes(); //模块数据权限角色。 + String custom = QMSPermissionContextHolder.getCustom(); //todo 自定义权限 + + List allRoleCode = new ArrayList<>(); + if(!ObjectUtil.isEmpty(deptDataRoleCodes)){ + allRoleCode.addAll(Arrays.asList(deptDataRoleCodes.split( ","))); + } + if(!ObjectUtil.isEmpty(moduleDataRoleCodes)){ + allRoleCode.addAll(Arrays.asList(moduleDataRoleCodes.split( ","))); + } + //查询角色 + + String tableName = MyBatisUtils.getTableName(table); + Alias tableAlias = table.getAlias(); + DeptDataPermissionRespDTO qmsDataPermission = loginUser.getContext(QMS_PERMISSION_CONTEXT_KEY, DeptDataPermissionRespDTO.class); + if(qmsDataPermission == null){ + try{ + DeptContextHolder.setRoleCodeList(allRoleCode); + qmsDataPermission = permissionApi.getDeptDataPermission(loginUser.getId()).getCheckedData(); + }catch (Exception e){ + log.error("[getExpression][LoginUser({}) 获取角色权限为 null]", JsonUtils.toJsonString(loginUser)); + log.error("", e); + }finally { + DeptContextHolder.clearRoleCodeList(); + } + + if (qmsDataPermission == null) { + log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser)); + throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限", loginUser.getId(), tableName, tableAlias.getName())); + } + // 添加到上下文中,避免重复计算 + loginUser.setContext(QMS_PERMISSION_CONTEXT_KEY, qmsDataPermission); + } + Long ctxDeptId = DeptContextHolder.getDeptId(); + // 计算有效的部门与自查标记:当存在上下文部门且未被忽略时,强制仅使用该部门,以避免默认全量或空权限分支 + Set effectiveDeptIds = qmsDataPermission.getDeptIds(); + Boolean effectiveSelf = qmsDataPermission.getSelf(); + if (!DeptContextHolder.shouldIgnore() && ctxDeptId != null && ctxDeptId > 0L) { + effectiveDeptIds = CollUtil.newHashSet(ctxDeptId); + } + // 情况一:仅当不存在上下文部门时,且 ALL 可查看全部,才无需拼接条件;若存在上下文部门则仍需基于该部门过滤 + if (ctxDeptId == null && qmsDataPermission.getAll()) { + return null; + } + + // 情况二:仅在有效部门集合为空且不可查看自己时,才认为无权限;若上下文提供部门,则跳过该兜底 + if (CollUtil.isEmpty(effectiveDeptIds) && Boolean.FALSE.equals(effectiveSelf)) { + return new EqualsTo(null, null); // WHERE null = null,可以保证返回的数据为空 + } + + // 情况三,拼接 Dept 和 Company User 的条件,最后组合 + Expression deptExpression = buildDeptExpression(tableName, deptIdCol, tableAlias, effectiveDeptIds); + Expression userExpression = buildUserExpression(tableName, userIdCol, tableAlias, effectiveSelf, loginUser.getId()); + if (deptExpression == null && userExpression == null) { + // TODO:获得不到条件的时候,暂时不抛出异常,而是不返回数据 + log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]", + JsonUtils.toJsonString(loginUser), tableName, tableAlias, JsonUtils.toJsonString(qmsDataPermission)); +// throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 构建的条件为空", +// loginUser.getId(), tableName, tableAlias.getName())); + return null; + } + if (deptExpression == null) { + return userExpression; + } + if (userExpression == null) { + return deptExpression; + } + // 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即,WHERE (dept_id IN ? OR user_id = ?) + return new ParenthesedExpressionList(new OrExpression(deptExpression, userExpression)); + } + + private Expression buildDeptExpression(String tableName, String columnName, Alias tableAlias, Set deptIds) { + // 特殊处理:system_users 表没有 dept_id 字段,已经迁移到了 user_dept 表 + if (SYSTEM_USERS.equals(tableName)) { + // system_users 走 exists 子查询 user_dept + if (CollUtil.isEmpty(deptIds)) { + return null; + } + // 构造 exists (select 1 from user_dept where user_dept.user_id = system_users.id and user_dept.dept_id in (...)) + PlainSelect plainSelect = new PlainSelect(); + plainSelect.setSelectItems(singletonList(new SelectItem<>(new LongValue(1)))); + Table userDept = new Table(SYSTEM_USER_DEPT); + // 使用 user 表别名避免语法错误 + Table user = new Table(tableAlias == null ? tableName : tableAlias.getName()); + plainSelect.setFromItem(userDept); + // where user_dept.user_id = system_users.id and user_dept.dept_id in (...) + Column userDeptUserIdCol = new Column(userDept, USER_COLUMN_NAME); + Column systemUsersIdCol = new Column(user, "id"); + EqualsTo userIdEquals = new EqualsTo(userDeptUserIdCol, systemUsersIdCol); + Column userDeptDeptIdCol = new Column(userDept, DEPT_COLUMN_NAME); + InExpression deptIn = new InExpression(userDeptDeptIdCol, new ParenthesedExpressionList<>(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new)))); + Expression whereExp = new AndExpression(userIdEquals, deptIn); + plainSelect.setWhere(whereExp); + // + ParenthesedSelect parenthesedSelect = new ParenthesedSelect(); + parenthesedSelect.setSelect(plainSelect); + // 构建 exists 表达式 + ExistsExpression existsExpr = new ExistsExpression(); + existsExpr.setRightExpression(parenthesedSelect); + return existsExpr; + } + if (StrUtil.isEmpty(columnName)) { + return null; + } + // 如果为空,则无条件 + if (CollUtil.isEmpty(deptIds)) { + return null; + } + // 拼接条件 + return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), + // Parenthesis 的目的,是提供 (1,2,3) 的 () 左右括号 + new ParenthesedExpressionList(new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)))); + } + + private Expression buildUserExpression(String tableName, String columnName, Alias tableAlias, Boolean self, Long userId) { + // 如果不查看自己,则无需作为条件 + if (Boolean.FALSE.equals(self)) { + return null; + } + if (StrUtil.isEmpty(columnName)) { + return null; + } + // 拼接条件 + return new EqualsTo(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), new LongValue(userId)); + } + + /* + * */ + private DeptDataPermissionRespDTO getQmsDataPermission(){ + return null; + } + +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSPermissionContextHolder.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSPermissionContextHolder.java new file mode 100644 index 0000000..192bae8 --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/datapermission/QMSPermissionContextHolder.java @@ -0,0 +1,81 @@ +package com.zt.plat.module.qms.framework.datapermission; + +import com.alibaba.ttl.TransmittableThreadLocal; + + +public class QMSPermissionContextHolder { + // 是否启用 + private static final ThreadLocal enable = new TransmittableThreadLocal<>(); + + private static final ThreadLocal deptDataRoleCodes = new TransmittableThreadLocal<>(); //部门数据查看权限 + private static final ThreadLocal moduleDataRoleCodes = new TransmittableThreadLocal<>(); //模块数据权限 + private static final ThreadLocal deptIdColumn = new TransmittableThreadLocal<>(); //部门id列 + private static final ThreadLocal userIdColumn = new TransmittableThreadLocal<>(); //人员id列 + private static final ThreadLocal custom = new TransmittableThreadLocal<>(); //人员id列 + + public static void setEnable(Boolean ignore) { + enable.set(ignore); + } + + public static boolean shouldExecute() { + return Boolean.TRUE.equals(enable.get()); + } + + public static void setContext(boolean enable, String deptDataRoleCode, String moduleDataRoleCode, String deptIdColumn, String userIdColumn, String custom){ + QMSPermissionContextHolder.setEnable(enable); + QMSPermissionContextHolder.deptDataRoleCodes.set(deptDataRoleCode); + QMSPermissionContextHolder.moduleDataRoleCodes.set(moduleDataRoleCode); + QMSPermissionContextHolder.deptIdColumn.set(deptIdColumn); + QMSPermissionContextHolder.userIdColumn.set(userIdColumn); + QMSPermissionContextHolder.custom.set(custom); + } + + public static void setDeptDataRoleCode(String deptDataRoleCode) { + QMSPermissionContextHolder.deptDataRoleCodes.set(deptDataRoleCode); + } + public static String getDeptDataRoleCode() { + return deptDataRoleCodes.get(); + } + + public static void setModuleDataRoleCodes(String moduleDataRoleCodes) { + QMSPermissionContextHolder.moduleDataRoleCodes.set(moduleDataRoleCodes); + } + public static String getModuleDataRoleCodes() { + return moduleDataRoleCodes.get(); + } + + public static void setDeptIdColumn(String deptIdColumn) { + QMSPermissionContextHolder.deptIdColumn.set(deptIdColumn); + } + public static String getDeptIdColumn() { + if(deptIdColumn.get() == null || deptIdColumn.get().length() == 0) + return "DEPT_ID"; + return deptIdColumn.get(); + } + + public static void setUserIdColumn(String userIdColumn) { + QMSPermissionContextHolder.userIdColumn.set(userIdColumn); + } + public static String getUserIdColumn() { + if(userIdColumn.get() == null || userIdColumn.get().length() == 0) + return "CREATOR"; + return userIdColumn.get(); + } + + public static void setCustom(String custom) { + QMSPermissionContextHolder.custom.set(custom); + } + public static String getCustom() { + return custom.get(); + } + + public static void clear() { + enable.remove(); + deptDataRoleCodes.remove(); + moduleDataRoleCodes.remove(); + deptIdColumn.remove(); + userIdColumn.remove(); + custom.remove(); + + } +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/mybatis/QMSDataPermissionConfig.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/mybatis/QMSDataPermissionConfig.java new file mode 100644 index 0000000..d1610e2 --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/mybatis/QMSDataPermissionConfig.java @@ -0,0 +1,42 @@ +package com.zt.plat.module.qms.framework.mybatis; + + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; +import com.zt.plat.module.qms.framework.datapermission.QMSMultiDataPermissionHandler; +import jakarta.annotation.PostConstruct; +import org.aspectj.lang.annotation.After; +import org.springframework.beans.factory.SmartInitializingSingleton; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +//@Configuration +public class QMSDataPermissionConfig implements SmartInitializingSingleton { + @Autowired + private MybatisPlusInterceptor mybatisPlusInterceptor; + + @Autowired + private QMSMultiDataPermissionHandler qmsMultiDataPermissionHandler; + + @Override + public void afterSingletonsInstantiated() { + List interceptors = mybatisPlusInterceptor.getInterceptors(); + // 避免重复注册 + boolean exists = interceptors.stream() + .filter(i -> i instanceof DataPermissionInterceptor) + .map(i -> (DataPermissionInterceptor) i) + .anyMatch(i -> i.getDataPermissionHandler() == qmsMultiDataPermissionHandler); + if (!exists) { + mybatisPlusInterceptor.addInnerInterceptor(new DataPermissionInterceptor(qmsMultiDataPermissionHandler)); + } + } + +// @PostConstruct +// public void addDataPermissionInterceptor() { +// +// } + +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceApplyController.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceApplyController.java index a575210..42cbe8b 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceApplyController.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceApplyController.java @@ -100,7 +100,6 @@ public class DeviceApplyController extends AbstractFileUploadController implemen @GetMapping("/page") @Operation(summary = "获得设备通用流程,验收、降级、停用、报废、还原、启用分页") - @PreAuthorize("@ss.hasPermission('qms:device-apply:query')") public CommonResult> getDeviceApplyPage(@Valid DeviceApplyPageReqVO pageReqVO) { PageResult pageResult = deviceApplyService.getDeviceApplyPage(pageReqVO); return success(BeanUtils.toBean(pageResult, DeviceApplyRespVO.class)); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceConfigFlowController.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceConfigFlowController.java index dcce81e..5d31f7d 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceConfigFlowController.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceConfigFlowController.java @@ -97,7 +97,6 @@ public class DeviceConfigFlowController implements BusinessControllerMarker { @GetMapping("/page") @Operation(summary = "获得设备通用流程配置分页") - @PreAuthorize("@ss.hasPermission('qms:device-config-flow:query')") public CommonResult> getDeviceConfigFlowPage(@Valid DeviceConfigFlowPageReqVO pageReqVO) { PageResult pageResult = deviceConfigFlowService.getDeviceConfigFlowPage(pageReqVO); return success(BeanUtils.toBean(pageResult, DeviceConfigFlowRespVO.class)); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceProductController.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceProductController.java index 84e7b98..c8f642a 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceProductController.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/controller/admin/DeviceProductController.java @@ -122,7 +122,7 @@ public class DeviceProductController extends AbstractFileUploadController implem @GetMapping("/page") @Operation(summary = "获得设备-设备大类分页") - @PreAuthorize("@ss.hasPermission('resource:device-product:query')") +// @PreAuthorize("@ss.hasPermission('resource:device-product:query')") public CommonResult> getDeviceProductPage(@Valid DeviceProductPageReqVO pageReqVO) { PageResult pageResult = deviceProductService.getDeviceProductPage(pageReqVO); return success(BeanUtils.toBean(pageResult, DeviceProductRespVO.class)); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceApplyMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceApplyMapper.java index 5358c25..813b61b 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceApplyMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceApplyMapper.java @@ -3,6 +3,7 @@ package com.zt.plat.module.qms.resource.device.dal.mapper; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX; +import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission; import com.zt.plat.module.qms.resource.device.controller.vo.DeviceApplyPageReqVO; import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceApplyDO; import org.apache.ibatis.annotations.Mapper; @@ -15,9 +16,10 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface DeviceApplyMapper extends BaseMapperX { + @QmsPermission default PageResult selectPage(DeviceApplyPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(DeviceApplyDO::getBusinessName, reqVO.getBusinessName()) + LambdaQueryWrapperX wrapper = new LambdaQueryWrapperX<>(); + wrapper.likeIfPresent(DeviceApplyDO::getBusinessName, reqVO.getBusinessName()) .likeIfPresent(DeviceApplyDO::getApplyDepartmentName, reqVO.getApplyDepartmentName()) .eqIfPresent(DeviceApplyDO::getApplyDepartment, reqVO.getApplyDepartment()) .likeIfPresent(DeviceApplyDO::getApplyUserName, reqVO.getApplyUserName()) @@ -39,7 +41,8 @@ public interface DeviceApplyMapper extends BaseMapperX { .eqIfPresent(DeviceApplyDO::getSystemDepartmentCode, reqVO.getSystemDepartmentCode()) .eqIfPresent(DeviceApplyDO::getRemark, reqVO.getRemark()) .betweenIfPresent(DeviceApplyDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(DeviceApplyDO::getId)); + .orderByDesc(DeviceApplyDO::getId); + return selectPage(reqVO, wrapper); } } \ No newline at end of file diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceInfomationMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceInfomationMapper.java index 2fba698..a2f89c0 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceInfomationMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceInfomationMapper.java @@ -3,6 +3,7 @@ package com.zt.plat.module.qms.resource.device.dal.mapper; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX; import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission; import com.zt.plat.module.qms.resource.device.controller.vo.DeviceInfomationPageReqVO; import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceInfoWithBizConfigVO; import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceInfomationDO; @@ -20,6 +21,7 @@ import java.util.Map; @Mapper public interface DeviceInfomationMapper extends BaseMapperX { + @QmsPermission(deptDataRoleCodes = "") default PageResult selectPage(DeviceInfomationPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(DeviceInfomationDO::getProductId, reqVO.getProductId()) diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceProductMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceProductMapper.java index fd64a7c..1b87ec9 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceProductMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/device/dal/mapper/DeviceProductMapper.java @@ -3,7 +3,6 @@ package com.zt.plat.module.qms.resource.device.dal.mapper; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX; import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; -import com.zt.plat.module.qms.resource.device.controller.vo.*; import com.zt.plat.module.qms.resource.device.controller.vo.DeviceProductPageReqVO; import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceProductDO; import org.apache.ibatis.annotations.Mapper;