diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/constant/ReportDocConstant.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/constant/ReportDocConstant.java new file mode 100644 index 00000000..03eaaf54 --- /dev/null +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/constant/ReportDocConstant.java @@ -0,0 +1,8 @@ +package com.zt.plat.module.qms.business.reportdoc.constant; + +public class ReportDocConstant { + + public static final String REPORT_DOCUMENT_BUSINESS_FILE_SOURCE_QMS = "qms.reportdoc"; + public static final String REPORT_DOCUMENT_BUSINESS_FILE_SOURCE_IWORK = "iwork"; + +} diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java index d9de9d9b..c5b485c0 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java @@ -9,9 +9,12 @@ import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.util.object.BeanUtils; import com.zt.plat.framework.security.core.LoginUser; import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils; +import com.zt.plat.module.infra.api.businessfile.BusinessFileApi; +import com.zt.plat.module.infra.api.businessfile.dto.BusinessFileSaveReqDTO; import com.zt.plat.module.infra.api.file.FileApi; import com.zt.plat.module.infra.api.file.dto.FileCreateReqDTO; import com.zt.plat.module.infra.api.file.dto.FileRespDTO; +import com.zt.plat.module.qms.business.reportdoc.constant.ReportDocConstant; import com.zt.plat.module.qms.business.reportdoc.controller.vo.ReportDocumentFileSaveReqVO; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentFileDO; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMainDO; @@ -28,6 +31,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; import java.io.IOException; import java.io.InputStream; @@ -56,10 +61,10 @@ public class ReportDocumentAssistService { @Resource private ReportDocumentTypeService reportDocumentTypeService; @Resource private ReportDocumentFileService reportDocumentFileService; @Resource private DataTemplateService dataTemplateService; - @Resource private SequenceUtil sequenceUtil; @Resource private FileApi fileApi; + @Resource private BusinessFileApi businessFileApi; - private String sequenceKey = "QMS_REPORT_IWORK_CODE"; +// private String sequenceKey = "QMS_REPORT_IWORK_CODE"; // todo 判断是否更新pdf public boolean checkUpdateDocFile(JSONObject variables){ @@ -78,6 +83,8 @@ public class ReportDocumentAssistService { JSONObject extension = bpmFieldExtensions.getJSONObject(i); String fieldName = extension.getString("fieldName"); String stringValue = extension.getString("stringValue"); + if(ObjectUtils.isEmpty(stringValue)) + stringValue = ""; if(fieldName.equalsIgnoreCase("createiworkflow") && stringValue.equals("1")){ createIworkWorkflowFlag = true; break; @@ -96,16 +103,23 @@ public class ReportDocumentAssistService { LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); IWorkWorkflowCreateReqDTO dto = new IWorkWorkflowCreateReqDTO(); - dto.setOperatorUserId(String.valueOf(loginUser.getId())); - dto.setJbr(String.valueOf(loginUser.getId())); - dto.setYybm(String.valueOf(loginUser.getVisitDeptId())); - dto.setFb(String.valueOf(loginUser.getVisitCompanyId())); + + String operatorUserId = "455"; //iWork 操作人用户编号 + String jbr = "455"; //用印申请人 + String yybm = "1055"; //用印部门 + String fb = "170"; //用印单位 + + + dto.setOperatorUserId(operatorUserId); + dto.setJbr(jbr); + dto.setYybm(yybm); + dto.setFb(fb); dto.setSqsj(sdf.format(new Date())); dto.setYyqx("检测报告用印"); dto.setYysy("检测报告用印"); dto.setYysx("检测报告用印"); dto.setXyywjUrl(docFile.getUrl()); - dto.setYwxtdjbh(sequenceUtil.genCode(sequenceKey)); + dto.setYwxtdjbh(entity.getDocumentCode()); dto.setBizCallbackKey(ReportDocListenerConstant.IWORK_BIZ_CALL_BACK_KEY); //业务回调标识,回调分发使用 return iWorkIntegrationApi.createWorkflow(dto); } @@ -114,6 +128,7 @@ public class ReportDocumentAssistService { * 生成新版pdf文件 * 在reportDocumentFile创建新pdf文件 * */ + @Transactional(rollbackFor = Exception.class) public ReportDocumentFileDO generatePdf(ReportDocumentMainDO mainDO) throws IOException { String pageFlag = "1"; //分页处理 Long typeId = mainDO.getReportDocumentTypeId(); @@ -134,11 +149,20 @@ public class ReportDocumentAssistService { .execute(); log.info("html2pdf--end at {}", LocalDateTime.now()); InputStream inputStream = response.bodyStream(); // 关键:返回原始 InputStream - - //尝试从响应头中提取文件名 - String documentCode = mainDO.getDocumentCode(); - if(documentCode == null) documentCode = ""; - String filename = documentCode + "检测报告.pdf"; + String formDataStr = mainDO.getFormData(); + JSONObject formData = JSONObject.parseObject(formDataStr); + String entrustCode = ""; + String sampleCategory = ""; + String filename = "检测报告"; + if(!ObjectUtils.isEmpty(formData)){ + entrustCode = formData.getString("entrustCode"); + sampleCategory = formData.getString("sampleCategory"); + if(!ObjectUtils.isEmpty(entrustCode)) + filename = entrustCode; + if(!ObjectUtils.isEmpty(sampleCategory)) + filename = filename + "(" + sampleCategory + ")"; + } + filename += ".pdf"; byte[] fileBytes = IOUtils.toByteArray(inputStream); //上传到文件服务 @@ -152,6 +176,17 @@ public class ReportDocumentAssistService { throw new ServiceException(REPORT_DOCUMENT_FILE_NOT_EXISTS.getCode(), "通过文件服务创建附件失败: " + Optional.ofNullable(fileResult).map(CommonResult::getMsg).orElse("未知错误")); } FileRespDTO fileRespDTO = fileResult.getData(); + //创建businessFile + BusinessFileSaveReqDTO businessFileSaveReqDTO = BusinessFileSaveReqDTO.builder() + .businessId(mainDO.getId()) + .businessCode(mainDO.getDocumentCode()) + .fileName(filename) + .fileId(fileRespDTO.getId()) + .source(ReportDocConstant.REPORT_DOCUMENT_BUSINESS_FILE_SOURCE_QMS) + .status(1) + .build(); + businessFileApi.createBusinessFile(businessFileSaveReqDTO); + //写入ReportDocumentFile ReportDocumentFileSaveReqVO fileSaveReqVO = new ReportDocumentFileSaveReqVO(); fileSaveReqVO.setMainId(mainDO.getId()); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainService.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainService.java index dec48649..21794e17 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainService.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainService.java @@ -6,8 +6,7 @@ import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayReportDat import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustRegistrationDO; import com.zt.plat.module.qms.business.reportdoc.controller.vo.*; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMainDO; -import com.zt.plat.module.system.api.iwork.dto.IWorkOperationRespDTO; -import com.zt.plat.module.system.api.iwork.dto.IWorkWorkflowCreateReqDTO; +import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentTypeDO; import jakarta.validation.Valid; import java.util.List; @@ -31,7 +30,7 @@ public interface ReportDocumentMainService { //移除数据 CommonResult execRemoveData(ReportDocumentMainSaveReqVO reqVO); - void updateCommonField(ReportDocumentMainDO reportDocumentMainDO); + void updateCommonField(ReportDocumentMainDO reportDocumentMainDO, ReportDocumentTypeDO typeDO); //保存报告 void doSave(@Valid ReportDocumentMainSaveReqVO updateReqVO); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainServiceImpl.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainServiceImpl.java index baa8974d..81c2c5a7 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainServiceImpl.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentMainServiceImpl.java @@ -29,6 +29,7 @@ import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentTy import com.zt.plat.module.qms.business.reportdoc.dal.mapper.ReportDocumentMainMapper; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMainDO; import com.zt.plat.module.qms.common.data.service.DataKeyCheckService; +import com.zt.plat.module.qms.core.code.SequenceUtil; import com.zt.plat.module.qms.enums.QmsBpmConstant; import com.zt.plat.module.qms.enums.QmsCommonConstant; import jakarta.annotation.Resource; @@ -70,6 +71,7 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService, @Resource private BusinessSampleEntrustRegistrationService businessSampleEntrustRegistrationService; @Resource private ReportDocumentAssistService reportDocumentAssistService; @Resource private DataKeyCheckService dataKeyCheckService; + @Resource private SequenceUtil sequenceUtil; /* * 测试异步执行 @@ -190,14 +192,15 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService, if(!insertList.isEmpty()) reportDocumentDataService.insertBatch(insertList); ReportDocumentMainDO reportDocumentMainDO = reportDocumentMainMapper.selectById(id); - updateCommonField(reportDocumentMainDO); + ReportDocumentTypeDO typeDO = reportDocumentTypeService.getReportDocumentType(reportDocumentMainDO.getReportDocumentTypeId()); + updateCommonField(reportDocumentMainDO, typeDO); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String formData = reportDocumentMainDO.getFormData(); JSONObject formDataJson = new JSONObject(); if(!ObjectUtils.isEmpty(formData)) formDataJson = JSONObject.parseObject(formData); - ReportDocumentTypeDO typeDO = reportDocumentTypeService.getReportDocumentType(reportDocumentMainDO.getReportDocumentTypeId()); + String customConfig = typeDO.getCustomConfig(); String defaultConclusion = ""; if(!ObjectUtils.isEmpty(customConfig)){ @@ -262,9 +265,15 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService, } @Override - public void updateCommonField(ReportDocumentMainDO reportDocumentMainDO) { + public void updateCommonField(ReportDocumentMainDO reportDocumentMainDO, ReportDocumentTypeDO typeDO) { if(reportDocumentMainDO == null) return; + String documentCode = reportDocumentMainDO.getDocumentCode(); + if(ObjectUtils.isEmpty(documentCode)){ + String codeRule = typeDO.getCodeRule(); + documentCode = sequenceUtil.genCode(codeRule); + reportDocumentMainDO.setDocumentCode(documentCode); + } if(reportDocumentMainDO.getCancelFlag() == null || reportDocumentMainDO.getCancelFlag().equals("-1")) reportDocumentMainDO.setCancelFlag("0"); } @@ -462,11 +471,15 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService, String firstActivityFlag = "0"; if(!fieldExtensions.isEmpty()){ for(int i = 0; i < fieldExtensions.size(); i++){ - JSONObject fieldExtension = fieldExtensions.getJSONObject(i); - if(fieldExtension.getString("fieldName").equalsIgnoreCase(QmsBpmConstant.BPM_LAST_ACTIVITY_FLAG)){ + JSONObject extension = fieldExtensions.getJSONObject(i); + String fieldName = extension.getString("fieldName"); + String stringValue = extension.getString("stringValue"); + if(ObjectUtils.isEmpty(stringValue)) + stringValue = ""; + if(fieldName.equalsIgnoreCase(QmsBpmConstant.BPM_LAST_ACTIVITY_FLAG) && stringValue.equals("1")){ lastActivityFlag = "1"; } - if(fieldExtension.getString("fieldName").equalsIgnoreCase(QmsBpmConstant.BPM_FIRST_ACTIVITY_FLAG)){ + if(fieldName.equalsIgnoreCase(QmsBpmConstant.BPM_FIRST_ACTIVITY_FLAG) && stringValue.equals("1")){ firstActivityFlag = "1"; } } 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 index 37c1bcab..cc876d80 100644 --- 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 @@ -61,7 +61,8 @@ public class QmsPermissionAspect { QmsPermission annotation = getAnnotationByJoinPoint(joinPoint); if(annotation == null) return; - QMSPermissionContextHolder.setContext(true, annotation.deptDataRoleCodes(), annotation.moduleDataRoleCodes(), annotation.deptIdColumn(), annotation.userIdColumn(), annotation.custom()); + QMSPermissionContextHolder.setContext(true, annotation.deptDataRoleCodes(), annotation.moduleDataRoleCodes(), + annotation.deptIdColumn(), annotation.userIdColumn(), annotation.self(), annotation.custom()); } private QmsPermission getAnnotationByJoinPoint(JoinPoint joinPoint) { 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 index 29379bc2..5ef381ca 100644 --- 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 @@ -21,6 +21,8 @@ public @interface QmsPermission { String userIdColumn() default "CREATOR"; //人员id列 + boolean self() default false; //是否可查看自己创建的数据 + //todo 考虑支持模块自定义扩展。参数传入表达式,通过表达式计算权限 String custom() default ""; 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 index 3cfc3d7b..c8fe6e7f 100644 --- 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 @@ -3,7 +3,6 @@ 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.alibaba.fastjson.JSONObject; 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; @@ -15,11 +14,9 @@ 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 com.zt.plat.module.qms.core.aspect.annotation.QmsPermission; 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.*; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.relational.*; @@ -31,6 +28,9 @@ import net.sf.jsqlparser.statement.select.SelectItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -63,13 +63,21 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler @Override public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { - log.error("QMSMultiDataPermissionHandler: Expression={}", where); + log.info("QMSMultiDataPermissionHandler - table={}, Expression={}, mappedStatementId={}", + table.getName(), where, mappedStatementId); + + // 判断是否应该对该表应用权限(只处理主表) + boolean applyPermission = shouldApplyPermission(table, mappedStatementId); + if (!applyPermission) { + return null; + } //获取注解 if(!QMSPermissionContextHolder.shouldExecute()) return null; try{ Expression expression = buildExpression(table, where); + log.info("QMSMultiDataPermissionHandler 权限表达式:{}", expression); return expression; }catch (Exception e){ log.error("QMSMultiDataPermissionHandler: Expression={}", where); @@ -79,6 +87,88 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler return EXPRESSION_NULL; } + /** + * 判断是否应该对当前表应用权限控制(只针对主表) + * 通过解析 mappedStatementId 找到对应的 Mapper 接口和实体类,然后判断当前表是否是主表 + * + */ + private boolean shouldApplyPermission(Table table, String mappedStatementId) { + try{ + // mappedStatementId 格式:com.zt.plat.module.qms.resource.material.dal.mapper.MaterialBatchMapper.selectPageWithPdtInfo + int lastDotIndex = mappedStatementId.lastIndexOf('.'); + if (lastDotIndex == -1) { + return true; + } + + String mapperClassName = mappedStatementId.substring(0, lastDotIndex); + Class mapperClass = Class.forName(mapperClassName); + // 获取方法上的@QmsPermission 注解 + Method[] methods = mapperClass.getMethods(); + boolean applyPermission = false; + for (Method method : methods) { + if (method.isAnnotationPresent(QmsPermission.class)) { + // 获取主表的表名(通过实体类) + String mainTableName = getMainTableName(mapperClass); + String currentTableName = MyBatisUtils.getTableName(table); + Alias tableAlias = table.getAlias(); + String aliasName = tableAlias != null ? tableAlias.getName() : null; + // 只处理主表,且别名为 t 的表(避免自关联或重复应用) + if (mainTableName != null && mainTableName.equalsIgnoreCase(currentTableName)) { + // 如果有别名,检查别名是否为 "t" + if (aliasName != null) { + applyPermission = "t".equals(aliasName); + } else { + applyPermission = true; + } + } + } + } + return applyPermission; + } catch (Exception e) { + log.warn("QMSMultiDataPermissionHandler 解析 mappedStatementId 失败:{}", mappedStatementId, e); + } + + return false; + } + + /** + * 获取主表的表名 + * 通过 Mapper 接口的泛型参数找到对应的实体类,然后从@TableName 注解中获取表名 + * + */ + private String getMainTableName(Class mapperClass) { + try{ + // 1. 获取泛型接口列表 + Type[] genericInterfaces = mapperClass.getGenericInterfaces(); + if (genericInterfaces.length == 0) return null; + // 2. 遍历泛型接口 + for (Type type : genericInterfaces) { + // 3. 检查是否是参数化类型 + if (!(type instanceof ParameterizedType parameterizedType)) continue; + // 4. 获取泛型参数数组 + Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); + if (actualTypeArguments.length == 0) continue; + // 5. 获取第一个泛型参数(实体类) + Type firstTypeArg = actualTypeArguments[0]; + if (!(firstTypeArg instanceof Class entityClass)) continue; + // 6. 检查是否有 @TableName 注解 + com.baomidou.mybatisplus.annotation.TableName tableNameAnnotation = + entityClass.getAnnotation(com.baomidou.mybatisplus.annotation.TableName.class); + + if (tableNameAnnotation == null) continue; + + // 7. 返回表名 + return tableNameAnnotation.value(); + } + // 8. 未找到符合条件的表名 + log.debug("[getMainTableName] {} 未找到带@TableName 的实体类", mapperClass.getSimpleName()); + return null; + + } catch (Exception e) { + log.warn("[getMainTableName] 获取主表名失败:{}", mapperClass.getName(), e); + return null; + } + } /* * 构建权限sql*/ private Expression buildExpression(Table table, Expression where) { @@ -92,6 +182,7 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler } String deptIdCol = QMSPermissionContextHolder.getDeptIdColumn(); //部门id列 String userIdCol = QMSPermissionContextHolder.getUserIdColumn(); //人员id列 + Boolean self = QMSPermissionContextHolder.getSelf(); String deptDataRoleCodes = QMSPermissionContextHolder.getDeptDataRoleCode(); //部门数据权限角色。具有该角色,然后按角色的权限属性判断。从而获得人员允许查看的部门数据 String moduleDataRoleCodes = QMSPermissionContextHolder.getModuleDataRoleCodes(); //模块数据权限角色。 String custom = QMSPermissionContextHolder.getCustom(); //todo 自定义权限 @@ -149,7 +240,11 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler // 情况三,拼接 Dept 和 Company User 的条件,最后组合 Expression deptExpression = buildDeptExpression(tableName, deptIdCol, tableAlias, effectiveDeptIds); - Expression userExpression = buildUserExpression(tableName, userIdCol, tableAlias, effectiveSelf, loginUser.getId()); + // 只有当 userIdCol 不为空且 self 为 true 时,才构建用户表达式 + Expression userExpression = null; + if (StrUtil.isNotEmpty(userIdCol) && Boolean.TRUE.equals(self)) { + userExpression = buildUserExpression(tableName, userIdCol, tableAlias, effectiveSelf, loginUser.getId()); + } if (deptExpression == null && userExpression == null) { // TODO:获得不到条件的时候,暂时不抛出异常,而是不返回数据 log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]", @@ -165,7 +260,7 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler return deptExpression; } // 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即,WHERE (dept_id IN ? OR user_id = ?) - return new ParenthesedExpressionList(new OrExpression(deptExpression, userExpression)); + return new ParenthesedExpressionList<>(new OrExpression(deptExpression, userExpression)); } private Expression buildDeptExpression(String tableName, String columnName, Alias tableAlias, Set deptIds) { @@ -205,10 +300,26 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler 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)))); + new ParenthesedExpressionList( + new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new))));*/ + // 构建:(dept_id IS NULL OR dept_id IN (?, ?, ?)) + // 含义:部门 ID 为空的数据允许所有人查看,部门 ID 不为空的数据只允许指定部门查看 + Column column = MyBatisUtils.buildColumn(tableName, tableAlias, columnName); + + // 构建 IS NULL 条件(允许部门 ID 为空的数据) + IsNullExpression isNullExpr = new IsNullExpression(column); + + // 构建 IN 条件(限制部门 ID 不为空的数据) + InExpression inExpression = new InExpression(column, + new ParenthesedExpressionList<>( + new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new)))); + + // 组合:IS NULL OR IN (...) + OrExpression orExpression = new OrExpression(isNullExpr, inExpression); + return new ParenthesedExpressionList<>(orExpression); } private Expression buildUserExpression(String tableName, String columnName, Alias tableAlias, Boolean self, Long userId) { 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 index 192bae82..ed663811 100644 --- 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 @@ -11,6 +11,7 @@ public class QMSPermissionContextHolder { 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 self = new TransmittableThreadLocal<>(); private static final ThreadLocal custom = new TransmittableThreadLocal<>(); //人员id列 public static void setEnable(Boolean ignore) { @@ -21,12 +22,14 @@ public class QMSPermissionContextHolder { return Boolean.TRUE.equals(enable.get()); } - public static void setContext(boolean enable, String deptDataRoleCode, String moduleDataRoleCode, String deptIdColumn, String userIdColumn, String custom){ + public static void setContext(boolean enable, String deptDataRoleCode, String moduleDataRoleCode, + String deptIdColumn, String userIdColumn, Boolean self, String custom){ QMSPermissionContextHolder.setEnable(enable); QMSPermissionContextHolder.deptDataRoleCodes.set(deptDataRoleCode); QMSPermissionContextHolder.moduleDataRoleCodes.set(moduleDataRoleCode); QMSPermissionContextHolder.deptIdColumn.set(deptIdColumn); QMSPermissionContextHolder.userIdColumn.set(userIdColumn); + QMSPermissionContextHolder.self.set(self); QMSPermissionContextHolder.custom.set(custom); } @@ -62,6 +65,15 @@ public class QMSPermissionContextHolder { return userIdColumn.get(); } + // 新增 self 的 getter 和 setter + public static void setSelf(Boolean self) { + QMSPermissionContextHolder.self.set(self); + } + + public static Boolean getSelf() { + return self.get(); + } + public static void setCustom(String custom) { QMSPermissionContextHolder.custom.set(custom); } diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/rpc/config/RpcConfiguration.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/rpc/config/RpcConfiguration.java index 85e35704..486a931a 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/rpc/config/RpcConfiguration.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/framework/rpc/config/RpcConfiguration.java @@ -2,6 +2,7 @@ package com.zt.plat.module.qms.framework.rpc.config; import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi; import com.zt.plat.module.bpm.api.task.BpmTaskApi; +import com.zt.plat.module.infra.api.businessfile.BusinessFileApi; import com.zt.plat.module.infra.api.file.FileApi; import com.zt.plat.module.system.api.dept.DeptApi; import com.zt.plat.module.system.api.iwork.IWorkIntegrationApi; @@ -13,6 +14,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Configuration; @Configuration(value = "qmsRpcConfiguration", proxyBeanMethods = false) -@EnableFeignClients(clients = {FileApi.class, SequenceApi.class, AdminUserApi.class, DeptApi.class, BpmProcessInstanceApi.class, BpmTaskApi.class, PermissionApi.class, IWorkIntegrationApi.class}) +@EnableFeignClients(clients = {FileApi.class, BusinessFileApi.class, SequenceApi.class, AdminUserApi.class, DeptApi.class, BpmProcessInstanceApi.class, BpmTaskApi.class, PermissionApi.class, IWorkIntegrationApi.class}) public class RpcConfiguration { } diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/dal/mapper/MaterialBatchMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/dal/mapper/MaterialBatchMapper.java index 72b581d5..b215d9fb 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/dal/mapper/MaterialBatchMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/dal/mapper/MaterialBatchMapper.java @@ -48,7 +48,7 @@ public interface MaterialBatchMapper extends BaseMapperX { .orderByDesc(MaterialBatchDO::getId)); } - // @QmsPermission(deptDataRoleCodes = "ytjyDeptAndSub", moduleDataRoleCodes = "qms_material_manager") + @QmsPermission(moduleDataRoleCodes = "ytjyAdmin", deptIdColumn = "ASN_DEPT_ID") default PageResult selectPageWithPdtInfo(MaterialBatchPageReqVO reqVO, List pdtIds) { MPJLambdaWrapper wrapper = new MPJLambdaWrapperX() diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/service/MaterialBatchServiceImpl.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/service/MaterialBatchServiceImpl.java index 376afb53..8a846903 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/service/MaterialBatchServiceImpl.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/resource/material/service/MaterialBatchServiceImpl.java @@ -392,21 +392,7 @@ public class MaterialBatchServiceImpl implements MaterialBatchService { pageResult = materialBatchMapper.selectPageWithPdtInfo(pageReqVO, List.of()); } - // 查全部 - if (StrUtil.isEmpty(pageReqVO.getDataType())) { - List respVOS = pageResult.getList(); - if (CollUtil.isNotEmpty(respVOS)) { - List batIds = respVOS.stream().map(MaterialBatchRespVO::getId).toList(); - List gongs = materialBatchMapper.selectList(Wrappers.lambdaQuery(MaterialBatchDO.class) - .in(MaterialBatchDO::getParentId, batIds)); - if (CollUtil.isNotEmpty(gongs)) { - List gongRespVOs = gongs.stream().map(gong -> BeanUtils.toBean(gong, MaterialBatchRespVO.class)).toList(); - respVOS.addAll(gongRespVOs); - pageResult.setList(respVOS); - } - } - } - + // 给批次设置顶级分类的json配置 if (StrUtil.isEmpty(pageReqVO.getDataType()) || MaterialBatchGongType.batch.name().equals(pageReqVO.getDataType())) { List batches = pageResult.getList(); if (CollUtil.isNotEmpty(batches)) { @@ -428,6 +414,21 @@ public class MaterialBatchServiceImpl implements MaterialBatchService { } } + // 查全部 + if (StrUtil.isEmpty(pageReqVO.getDataType())) { + List respVOS = pageResult.getList(); + if (CollUtil.isNotEmpty(respVOS)) { + List batIds = respVOS.stream().map(MaterialBatchRespVO::getId).toList(); + List gongs = materialBatchMapper.selectList(Wrappers.lambdaQuery(MaterialBatchDO.class) + .in(MaterialBatchDO::getParentId, batIds)); + if (CollUtil.isNotEmpty(gongs)) { + List gongRespVOs = gongs.stream().map(gong -> BeanUtils.toBean(gong, MaterialBatchRespVO.class)).toList(); + respVOS.addAll(gongRespVOs); + pageResult.setList(respVOS); + } + } + } + // 需要组装children if (!MaterialBatchGongType.gong.name().equals(pageReqVO.getDataType()) && pageReqVO.getChildren()) { List voList = pageResult.getList();