feat(mes): 设计项目分页返回待审核文件数 pendingAuditCount,文件审核完成后才可提交审批
- MesPdProjectRespVO 新增 pendingAuditCount(未审核文件数)
- 列表/详情/导出统一批量填充,避免前端 N+1 查询
- MesPdDocumentMapper/AuditMapper 新增批量查询方法
- 统计口径与 submitProjectApproval 校验(仅 auditStatus=0)一致
Co-Authored-By: Claude <noreply@anthropic.com>
| | |
| | | // 1.1 批量获取关联数据(主设计师 + 审核人) |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(list, |
| | | project -> Stream.of(project.getChiefDesigner(), project.getReviewer()))); |
| | | // 1.2 批量获取各项目待审核文件数 |
| | | Map<Long, Integer> pendingAuditCountMap = projectService.getPendingAuditCountMap( |
| | | convertSet(list, MesPdProjectDO::getId)); |
| | | // 2. 拼接 VO |
| | | return BeanUtils.toBean(list, MesPdProjectRespVO.class, vo -> { |
| | | MapUtils.findAndThen(userMap, vo.getChiefDesigner(), |
| | | user -> vo.setChiefDesignerNickname(user.getNickname())); |
| | | MapUtils.findAndThen(userMap, vo.getReviewer(), |
| | | user -> vo.setReviewerNickname(user.getNickname())); |
| | | vo.setPendingAuditCount(pendingAuditCountMap.getOrDefault(vo.getId(), 0)); |
| | | }); |
| | | } |
| | | |
| | |
| | | @Schema(description = "BPM 流程实例编号") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "待审核文件数", example = "3") |
| | | private Integer pendingAuditCount; |
| | | |
| | | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("创建时间") |
| | | private LocalDateTime createTime; |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.pd.document; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | @Mapper |
| | |
| | | return selectList(MesPdDocumentDO::getProjectId, projectId); |
| | | } |
| | | |
| | | default List<MesPdDocumentDO> selectListByProjectIds(Collection<Long> projectIds) { |
| | | if (CollUtil.isEmpty(projectIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return selectList(MesPdDocumentDO::getProjectId, projectIds); |
| | | } |
| | | |
| | | default int deleteByProjectId(Long projectId) { |
| | | return delete(MesPdDocumentDO::getProjectId, projectId); |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.pd.documentaudit; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | @Mapper |
| | |
| | | .eq(MesPdDocumentAuditDO::getAuditStatus, 0)) > 0; |
| | | } |
| | | |
| | | /** |
| | | * 批量查询指定资料ID列表中所有待审核的记录 |
| | | * |
| | | * @param documentIds 资料ID列表 |
| | | * @return 待审核记录列表 |
| | | */ |
| | | default List<MesPdDocumentAuditDO> selectPendingAuditListByDocumentIds(Collection<Long> documentIds) { |
| | | if (CollUtil.isEmpty(documentIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return selectList(new LambdaQueryWrapperX<MesPdDocumentAuditDO>() |
| | | .in(MesPdDocumentAuditDO::getDocumentId, documentIds) |
| | | .eq(MesPdDocumentAuditDO::getAuditStatus, 0)); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | List<MesPdDocumentDO> getDocumentListByProjectId(Long projectId); |
| | | |
| | | /** |
| | | * 批量获得指定多个设计项目下的资料列表 |
| | | * |
| | | * @param projectIds 设计项目ID集合 |
| | | * @return 资料列表 |
| | | */ |
| | | List<MesPdDocumentDO> getDocumentListByProjectIds(Collection<Long> projectIds); |
| | | |
| | | /** |
| | | * 删除指定设计项目下的所有资料 |
| | | * |
| | | * @param projectId 设计项目ID |
| | |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<MesPdDocumentDO> getDocumentListByProjectIds(Collection<Long> projectIds) { |
| | | return documentMapper.selectListByProjectIds(projectIds); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteByProjectId(Long projectId) { |
| | | List<MesPdDocumentDO> documents = documentMapper.selectListByProjectId(projectId); |
| | | for (MesPdDocumentDO document : documents) { |
| | |
| | | |
| | | List<MesPdProjectDO> getProjectByProductCode(String productCode); |
| | | |
| | | /** |
| | | * 批量统计各设计项目的待审核文件数 |
| | | * <p> |
| | | * 统计口径:该项目下资料对应的审核记录中,存在 auditStatus=0(待审核)的记录数。 |
| | | * |
| | | * @param projectIds 设计项目ID集合 |
| | | * @return 项目ID -> 待审核文件数 |
| | | */ |
| | | Map<Long, Integer> getPendingAuditCountMap(Collection<Long> projectIds); |
| | | |
| | | } |
| | |
| | | return projectMapper.selectList(new QueryWrapper<MesPdProjectDO>().lambda().eq(MesPdProjectDO::getProductCode,productCode).eq(MesPdProjectDO::getStatus, MesPdProjectStatusEnum.ARCHIVE.getStatus())); |
| | | } |
| | | |
| | | @Override |
| | | public Map<Long, Integer> getPendingAuditCountMap(Collection<Long> projectIds) { |
| | | if (CollUtil.isEmpty(projectIds)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | // 1. 批量查出这些项目下的所有资料 |
| | | List<MesPdDocumentDO> documents = documentService.getDocumentListByProjectIds(projectIds); |
| | | if (CollUtil.isEmpty(documents)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | // 2. 资料ID -> 项目ID |
| | | Map<Long, Long> documentProjectIdMap = convertMap(documents, MesPdDocumentDO::getId, MesPdDocumentDO::getProjectId); |
| | | // 3. 批量查出所有待审核记录(auditStatus=0) |
| | | List<MesPdDocumentAuditDO> pendingAudits = |
| | | documentAuditMapper.selectPendingAuditListByDocumentIds(documentProjectIdMap.keySet()); |
| | | // 4. 按项目统计待审核文件数 |
| | | Map<Long, Integer> result = new HashMap<>(); |
| | | for (MesPdDocumentAuditDO audit : pendingAudits) { |
| | | Long projectId = documentProjectIdMap.get(audit.getDocumentId()); |
| | | if (projectId != null) { |
| | | result.merge(projectId, 1, Integer::sum); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private void validateProjectInitiate(MesPdProjectDO project) { |
| | | if (!MesPdProjectStatusEnum.INITIATE.getStatus().equals(project.getStatus())) { |
| | | throw exception(PD_PROJECT_NOT_INITIATE); |