package cn.iocoder.yudao.module.mes.service.pd.project; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.documentaudit.MesPdDocumentAuditDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.archive.MesPdArchiveDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.project.MesPdProjectDO; import cn.iocoder.yudao.module.mes.dal.mysql.pd.project.MesPdProjectMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pd.documentaudit.MesPdDocumentAuditMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pd.archive.MesPdArchiveMapper; import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; import cn.iocoder.yudao.module.mes.enums.pd.MesPdProjectStatusEnum; import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; import cn.iocoder.yudao.module.mes.service.pd.document.MesPdDocumentService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; /** * MES 设计项目 Service 实现类 * * @author 芋道源码 */ @Service @Validated public class MesPdProjectServiceImpl implements MesPdProjectService { @Resource private MesPdProjectMapper projectMapper; @Resource @Lazy private MesPdDocumentService documentService; @Resource private MesPdDocumentAuditMapper documentAuditMapper; @Resource private MesPdArchiveMapper archiveMapper; @Resource @Lazy private MesMdAutoCodeRecordService autoCodeRecordService; @Override @Transactional(rollbackFor = Exception.class) public Long createProject(MesPdProjectSaveReqVO createReqVO) { // 校验任务编码唯一 validateTaskCodeUnique(null, createReqVO.getTaskCode()); // 插入 MesPdProjectDO project = MesPdProjectDO.builder() .taskCode(createReqVO.getTaskCode()) .taskName(createReqVO.getTaskName()) .productCode(createReqVO.getProductCode()) .productName(createReqVO.getProductName()) .version(createReqVO.getVersion()) .status(MesPdProjectStatusEnum.INITIATE.getStatus()) .chiefDesigner(createReqVO.getChiefDesigner()) .reviewer(createReqVO.getReviewer()) .planFinishTime(createReqVO.getPlanFinishTime()) .remark(createReqVO.getRemark()) .build(); projectMapper.insert(project); return project.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateProject(MesPdProjectSaveReqVO updateReqVO) { // 校验存在 MesPdProjectDO project = validateProjectExists(updateReqVO.getId()); // 校验状态为待发布 validateProjectInitiate(project); // 校验任务编码唯一 validateTaskCodeUnique(updateReqVO.getId(), updateReqVO.getTaskCode()); // 更新 MesPdProjectDO updateObj = MesPdProjectDO.builder() .id(updateReqVO.getId()) .taskCode(updateReqVO.getTaskCode()) .taskName(updateReqVO.getTaskName()) .productCode(updateReqVO.getProductCode()) .productName(updateReqVO.getProductName()) .version(updateReqVO.getVersion()) .chiefDesigner(updateReqVO.getChiefDesigner()) .reviewer(updateReqVO.getReviewer()) .planFinishTime(updateReqVO.getPlanFinishTime()) .remark(updateReqVO.getRemark()) .build(); projectMapper.updateById(updateObj); } @Override @Transactional(rollbackFor = Exception.class) public void deleteProject(Long id) { // 校验存在 MesPdProjectDO project = validateProjectExists(id); // 校验状态为待发布 validateProjectInitiate(project); // 删除资料子表 documentService.deleteByProjectId(id); // 删除 projectMapper.deleteById(id); } @Override public MesPdProjectDO validateProjectExists(Long id) { MesPdProjectDO project = projectMapper.selectById(id); if (project == null) { throw exception(PD_PROJECT_NOT_EXISTS); } return project; } @Override public MesPdProjectDO getProject(Long id) { return projectMapper.selectById(id); } @Override public PageResult getProjectPage(MesPdProjectPageReqVO pageReqVO) { return projectMapper.selectPage(pageReqVO); } @Override public void publishProject(Long id) { // 校验存在 MesPdProjectDO project = validateProjectExists(id); // 校验状态为待发布 if (!MesPdProjectStatusEnum.INITIATE.getStatus().equals(project.getStatus())) { throw exception(PD_PROJECT_NOT_INITIATE_FOR_PUBLISH); } // 更新状态 projectMapper.updateById(MesPdProjectDO.builder() .id(id) .status(MesPdProjectStatusEnum.PUBLISH.getStatus()) .build()); } @Override @Transactional(rollbackFor = Exception.class) public void uploadProject(Long id, Long userId) { // 校验存在 MesPdProjectDO project = validateProjectExists(id); // 校验状态为待上传 if (!MesPdProjectStatusEnum.PUBLISH.getStatus().equals(project.getStatus())) { throw exception(PD_PROJECT_NOT_PUBLISH_FOR_UPLOAD); } // 更新项目状态为待审核 projectMapper.updateById(MesPdProjectDO.builder() .id(id) .status(MesPdProjectStatusEnum.UPLOAD.getStatus()) .build()); // 自动为该项目下所有资料创建审核记录 List documents = documentService.getDocumentListByProjectId(id); for (MesPdDocumentDO document : documents) { MesPdDocumentAuditDO audit = MesPdDocumentAuditDO.builder() .auditNo(generateAuditNo()) .documentId(document.getId()) .documentName(document.getDocumentName()) .documentVersion(document.getDocumentVersion()) .reviewer(project.getReviewer()) .auditStatus(0) // 待审核 .build(); documentAuditMapper.insert(audit); } } @Override public void auditProject(Long id) { // 校验存在 MesPdProjectDO project = validateProjectExists(id); // 校验状态为待审核 if (!MesPdProjectStatusEnum.UPLOAD.getStatus().equals(project.getStatus())) { throw exception(PD_PROJECT_NOT_UPLOAD_FOR_AUDIT); } // 校验该项目下所有资料审核记录均已审核(不存在待审核的记录) List documents = documentService.getDocumentListByProjectId(id); List documentIds = documents.stream().map(MesPdDocumentDO::getId).toList(); if (documentAuditMapper.existsPendingAuditByDocumentIds(documentIds)) { throw exception(PD_PROJECT_AUDIT_NOT_FINISHED); } // 更新状态 projectMapper.updateById(MesPdProjectDO.builder() .id(id) .status(MesPdProjectStatusEnum.AUDIT.getStatus()) .build()); } @Override @Transactional(rollbackFor = Exception.class) public void archiveProject(Long id, Long userId) { // 校验存在 MesPdProjectDO project = validateProjectExists(id); // 校验状态为待归档 if (!MesPdProjectStatusEnum.AUDIT.getStatus().equals(project.getStatus())) { throw exception(PD_PROJECT_NOT_AUDIT_FOR_ARCHIVE); } // 更新项目状态为已归档 projectMapper.updateById(MesPdProjectDO.builder() .id(id) .status(MesPdProjectStatusEnum.ARCHIVE.getStatus()) .build()); // 自动创建归档台账记录 MesPdArchiveDO archive = MesPdArchiveDO.builder() .archiveCode(generateArchiveCode()) .projectId(id) .archiver(userId) .archiveStatus(1) // 已归档 .archiveTime(LocalDateTime.now()) .build(); archiveMapper.insert(archive); } @Override public Map getProjectMap(Collection ids) { List list = projectMapper.selectBatchIds(ids); return convertMap(list, MesPdProjectDO::getId); } @Override public List getProjectByProductCode(String productCode) { return projectMapper.selectList(new QueryWrapper().lambda().eq(MesPdProjectDO::getProductCode,productCode).eq(MesPdProjectDO::getStatus, MesPdProjectStatusEnum.ARCHIVE.getStatus())); } private void validateProjectInitiate(MesPdProjectDO project) { if (!MesPdProjectStatusEnum.INITIATE.getStatus().equals(project.getStatus())) { throw exception(PD_PROJECT_NOT_INITIATE); } } private void validateTaskCodeUnique(Long id, String taskCode) { MesPdProjectDO existing = projectMapper.selectByTaskCode(taskCode); if (existing == null) { return; } // 如果 id 为空,说明是新增,编码重复 if (id == null) { throw exception(PD_PROJECT_CODE_DUPLICATE); } // 如果 id 不为空,说明是修改,编码重复且不是同一条记录 if (!existing.getId().equals(id)) { throw exception(PD_PROJECT_CODE_DUPLICATE); } } /** * 生成审核单号(使用编码规则) */ private String generateAuditNo() { return autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PD_DOCUMENT_AUDIT_CODE.getCode()); } /** * 生成归档编号(使用编码规则) */ private String generateArchiveCode() { return autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PD_ARCHIVE_CODE.getCode()); } }