package com.ruoyi.process.service.impl; import cn.hutool.core.date.DateUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.Pictures; import com.ruoyi.common.constant.MenuJumpPathConstants; import com.ruoyi.common.core.domain.entity.InformationNotification; import com.ruoyi.common.core.domain.entity.User; import com.ruoyi.common.utils.DateImageUtil; import com.ruoyi.common.utils.QueryWrappers; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.WxCpUtils; import com.ruoyi.device.pojo.DeviceExamineRecord; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; import com.ruoyi.inspect.util.UserUtils; import com.ruoyi.inspect.util.XWPFDocumentUtils; import com.ruoyi.process.dto.QualityMonitorDetailsDto; import com.ruoyi.process.dto.QualityMonitorDetailsEvaluateDto; import com.ruoyi.process.dto.QualityMonitorDto; import com.ruoyi.process.excel.QualityMonitorDetailsUpload; import com.ruoyi.process.mapper.*; import com.ruoyi.process.pojo.*; import com.ruoyi.process.service.QualityMonitorDetailsEvaluateService; import com.ruoyi.process.service.QualityMonitorDetailsRatifyService; import com.ruoyi.process.service.QualityMonitorDetailsService; import com.ruoyi.process.service.QualityMonitorService; import com.ruoyi.system.mapper.UserMapper; import com.ruoyi.system.service.InformationNotificationService; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** * 质量监控计划主表 * * @author zhuo * @since 2024-11-06 */ @Service @Transactional(rollbackFor = Exception.class) public class QualityMonitorServiceImpl extends ServiceImpl implements QualityMonitorService { private static final Set EDITABLE_PLAN_STATES = new HashSet<>(Arrays.asList( "DRAFT", "REVIEW_REJECTED", "APPROVAL_REJECTED")); @Resource private QualityMonitorDetailsService qualityMonitorDetailsService; @Resource private QualityMonitorDetailsMapper qualityMonitorDetailsMapper; @Resource private UserMapper userMapper; @Resource private QualityMonitorDetailsRatifyMapper qualityMonitorDetailsRatifyMapper; @Resource private QualityMonitorDetailsRatifyService qualityMonitorDetailsRatifyService; @Resource private QualityMonitorDetailsEvaluateMapper qualityMonitorDetailsEvaluateMapper; @Resource private QualityMonitorDetailsEvaluateService qualityMonitorDetailsEvaluateService; @Resource private QualityMonitorDetailsEvaluateFileMapper qualityMonitorDetailsEvaluateFileMapper; @Resource private InformationNotificationService informationNotificationService; @Resource private ThreadPoolTaskExecutor threadPoolTaskExecutor; @Value("${file.path}") private String imgUrl; @Value("${wordUrl}") private String wordUrl; @Override public QualityMonitorDto createAnnualPlan(QualityMonitor input) { if (input == null || StringUtils.isBlank(input.getMonitorYear()) || !input.getMonitorYear().matches("\\d{4}")) { throw new ErrorException("请选择正确的计划年度"); } if (input.getExamineUserId() == null || userMapper.selectById(input.getExamineUserId()) == null) { throw new ErrorException("请选择有效的审核人"); } if (StringUtils.isBlank(input.getMonitorName())) { throw new ErrorException("请填写计划名称"); } int userId = SecurityUtils.getUserId().intValue(); QualityMonitor plan = new QualityMonitor(); plan.setMonitorYear(input.getMonitorYear()); plan.setMonitorName(input.getMonitorName().trim()); plan.setWriteUserId(userId); plan.setWriteTime(LocalDateTime.now()); plan.setExamineUserId(input.getExamineUserId()); plan.setWorkflowStatus("DRAFT"); baseMapper.insert(plan); return baseMapper.selectPlanDtoById(plan.getQualityMonitorId()); } @Override public QualityMonitorDto getAnnualPlan(String monitorYear, Integer qualityMonitorId) { QualityMonitor plan; if (qualityMonitorId != null) { plan = baseMapper.selectById(qualityMonitorId); if (plan == null || (StringUtils.isNotBlank(monitorYear) && !monitorYear.equals(plan.getMonitorYear()))) return null; } else { if (StringUtils.isBlank(monitorYear)) throw new ErrorException("请选择计划年度"); plan = baseMapper.selectOne(Wrappers.lambdaQuery() .eq(QualityMonitor::getMonitorYear, monitorYear) .orderByDesc(QualityMonitor::getCreateTime, QualityMonitor::getQualityMonitorId) .last("limit 1")); } return plan == null ? null : baseMapper.selectPlanDtoById(plan.getQualityMonitorId()); } @Override public boolean submitAnnualPlan(Integer qualityMonitorId) { QualityMonitor plan = requirePlan(qualityMonitorId); int current = SecurityUtils.getUserId().intValue(); if (!Integer.valueOf(current).equals(plan.getWriteUserId())) { throw new ErrorException("只有计划编制人可以提交审核"); } String state = effectiveStatus(plan); if (!EDITABLE_PLAN_STATES.contains(state)) throw new ErrorException("当前计划状态不能提交审核"); if (qualityMonitorDetailsMapper.selectCount(Wrappers.lambdaQuery() .eq(QualityMonitorDetails::getQualityMonitorId, qualityMonitorId)) == 0) { throw new ErrorException("请至少新增一条质控项目后再提交审核"); } baseMapper.update(null, Wrappers.lambdaUpdate() .eq(QualityMonitor::getQualityMonitorId, qualityMonitorId) .set(QualityMonitor::getWorkflowStatus, "PENDING_REVIEW") .set(QualityMonitor::getExamineStatus, null) .set(QualityMonitor::getExamineRemark, null) .set(QualityMonitor::getRatifyStatus, null)); sendPlanNotice(plan, plan.getExamineUserId(), "CNAS质量监控计划审核通知", "质量监控计划待审核"); return true; } @Override public void validateDetailEditable(Integer qualityMonitorId) { QualityMonitor plan = requirePlan(qualityMonitorId); if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(plan.getWriteUserId())) { throw new ErrorException("只有计划编制人可以维护质控项目"); } if (!EDITABLE_PLAN_STATES.contains(effectiveStatus(plan))) { throw new ErrorException("当前计划已提交,不能修改质控项目"); } } private QualityMonitor requirePlan(Integer id) { QualityMonitor plan = id == null ? null : baseMapper.selectById(id); if (plan == null) throw new ErrorException("年度质量控制计划不存在"); return plan; } private String effectiveStatus(QualityMonitor plan) { if (StringUtils.isNotBlank(plan.getWorkflowStatus())) return plan.getWorkflowStatus(); if (Integer.valueOf(1).equals(plan.getRatifyStatus())) return "APPROVED"; if (Integer.valueOf(0).equals(plan.getRatifyStatus())) return "APPROVAL_REJECTED"; if (Integer.valueOf(1).equals(plan.getExamineStatus())) return "PENDING_APPROVAL"; if (Integer.valueOf(0).equals(plan.getExamineStatus())) return "REVIEW_REJECTED"; return "DRAFT"; } private void sendPlanNotice(QualityMonitor plan, Integer receiverId, String theme, String suffix) { if (receiverId == null) return; int sender = SecurityUtils.getUserId().intValue(); User senderUser = userMapper.selectById(sender); InformationNotification info = new InformationNotification(); info.setCreateUser(senderUser == null ? "" : senderUser.getName()); info.setMessageType("6"); info.setTheme(theme); info.setContent(plan.getMonitorName() + suffix); info.setSenderId(sender); info.setConsigneeId(receiverId); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); } /** * 导入监控计划 * @param file * @return */ @Override public boolean importQualityMonitor(MultipartFile file, QualityMonitor monitor) { // 当前登录用户 Integer userId = SecurityUtils.getUserId().intValue(); // 文件名称 String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")); if (monitor.getMonitorYear() == null || !monitor.getMonitorYear().matches("\\d{4}")) { throw new ErrorException("请选择正确的计划年度"); } if (monitor.getExamineUserId() == null) throw new ErrorException("缺少审核人"); QualityMonitor qualityMonitor = new QualityMonitor(); qualityMonitor.setMonitorName(fileName); qualityMonitor.setMonitorYear(monitor.getMonitorYear()); qualityMonitor.setWriteUserId(userId); qualityMonitor.setExamineUserId(monitor.getExamineUserId()); qualityMonitor.setWriteTime(LocalDateTime.now()); qualityMonitor.setWorkflowStatus("PENDING_REVIEW"); baseMapper.insert(qualityMonitor); User user = userMapper.selectById(userId); // 消息发送 InformationNotification info = new InformationNotification(); // 发送人 info.setCreateUser(user.getName()); info.setMessageType("6"); info.setTheme("CNAS质量监控计划审核通知"); info.setContent(fileName + "质量监控计划待审核"); info.setSenderId(userId); // 接收人 info.setConsigneeId(monitor.getExamineUserId()); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); // 发送企业微信通知 threadPoolTaskExecutor.execute(() -> { // 查询发送人 User people = userMapper.selectById(monitor.getExamineUserId()); String message = ""; message += "CNAS质量监控计划审核通知"; message += "\n请去过程要求-质量监控计划"; message += "\n" + fileName + "质量监控计划待审核"; //发送企业微信消息通知 try { WxCpUtils.inform(people.getAccount(), message, null); } catch (Exception e) { throw new RuntimeException(e); } }); List detailsUploadList = new ArrayList<>(); // 导入附件内容 try { // excel解析 EasyExcel.read(file.getInputStream(), QualityMonitorDetailsUpload.class, new AnalysisEventListener() { @Override public void invoke(QualityMonitorDetailsUpload detailsUpload, AnalysisContext analysisContext) { if (StringUtils.isBlank(detailsUpload.getMonitorProject()) || StringUtils.isBlank(detailsUpload.getTechnicalStandardText()) || StringUtils.isBlank(detailsUpload.getMonitorWay()) || StringUtils.isBlank(detailsUpload.getCompletionMonth())) { throw new ErrorException("质控项目、技术标准、质控方式和完成时限不能为空"); } // 对象复制 QualityMonitorDetails monitorDetails = new QualityMonitorDetails(); BeanUtils.copyProperties(detailsUpload, monitorDetails); monitorDetails.setQualityMonitorId(qualityMonitor.getQualityMonitorId()); if (!detailsUpload.getCompletionMonth().matches("\\d{4}-\\d{2}")) { throw new ErrorException("完成时限格式应为yyyy-MM"); } if (StringUtils.isBlank(detailsUpload.getResponsibleName())) { throw new ErrorException("负责人不能为空"); } List users = userMapper.selectList(Wrappers.lambdaQuery() .eq(User::getName, detailsUpload.getResponsibleName())); if (users.size() != 1) throw new ErrorException("负责人姓名不存在或不唯一:" + detailsUpload.getResponsibleName()); monitorDetails.setResponsibleUserId(users.get(0).getId()); monitorDetails.setItemKind("OTHER"); detailsUploadList.add(monitorDetails); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } }).sheet().doRead(); qualityMonitorDetailsService.saveBatch(detailsUploadList); } catch (IOException e) { throw new RuntimeException(e); } return true; } /** * 监控计划审核 * @param qualityMonitor * @return */ @Override public boolean examineQualityMonitor(QualityMonitor qualityMonitor) { QualityMonitor stored = requirePlan(qualityMonitor.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (!Integer.valueOf(current).equals(stored.getExamineUserId())) { throw new ErrorException("只有指定审核人可以审核计划"); } if (!"PENDING_REVIEW".equals(effectiveStatus(stored))) { throw new ErrorException("当前计划不在待审核状态"); } if (Integer.valueOf(1).equals(qualityMonitor.getExamineStatus()) && qualityMonitor.getRatifyUserId() == null) { throw new ErrorException("审核通过时必须指定批准人"); } // 当前登录用户 baseMapper.update(null, Wrappers.lambdaUpdate() .eq(QualityMonitor::getQualityMonitorId, qualityMonitor.getQualityMonitorId()) .set(QualityMonitor::getRatifyUserId, qualityMonitor.getRatifyUserId()) .set(QualityMonitor::getExamineRemark, qualityMonitor.getExamineRemark()) .set(QualityMonitor::getExamineStatus, qualityMonitor.getExamineStatus()) .set(QualityMonitor::getExamineTime, LocalDateTime.now()) .set(QualityMonitor::getWorkflowStatus, Integer.valueOf(1).equals(qualityMonitor.getExamineStatus()) ? "PENDING_APPROVAL" : "REVIEW_REJECTED") ); if (!Integer.valueOf(1).equals(qualityMonitor.getExamineStatus())) return true; QualityMonitor monitor = baseMapper.selectById(qualityMonitor.getQualityMonitorId()); Integer userId = SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); // 消息发送 InformationNotification info = new InformationNotification(); // 发送人 info.setCreateUser(user.getName()); info.setMessageType("6"); info.setTheme("CNAS质量监控计划批准通知"); info.setContent(monitor.getMonitorName() + "质量监控计划待批准"); info.setSenderId(userId); // 接收人 info.setConsigneeId(qualityMonitor.getRatifyUserId()); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); // 发送企业微信通知 threadPoolTaskExecutor.execute(() -> { // 查询发送人 User people = userMapper.selectById(qualityMonitor.getRatifyUserId()); String message = ""; message += "CNAS质量监控计划批准通知"; message += "\n请去过程要求-质量监控计划"; message += "\n" + monitor.getMonitorName() + "质量监控计划待批准"; //发送企业微信消息通知 try { WxCpUtils.inform(people.getAccount(), message, null); } catch (Exception e) { throw new RuntimeException(e); } }); return true; } /** * 监控计划批准 * @param qualityMonitor * @return */ @Override public boolean ratifyQualityMonitor(QualityMonitor qualityMonitor) { QualityMonitor stored = requirePlan(qualityMonitor.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (!Integer.valueOf(current).equals(stored.getRatifyUserId())) { throw new ErrorException("只有指定批准人可以批准计划"); } if (!"PENDING_APPROVAL".equals(effectiveStatus(stored))) { throw new ErrorException("当前计划不在待批准状态"); } // 当前登录用户 baseMapper.update(null, Wrappers.lambdaUpdate() .eq(QualityMonitor::getQualityMonitorId, qualityMonitor.getQualityMonitorId()) .set(QualityMonitor::getRatifyRemark, qualityMonitor.getRatifyRemark()) .set(QualityMonitor::getRatifyStatus, qualityMonitor.getRatifyStatus()) .set(QualityMonitor::getRatifyTime, LocalDateTime.now()) .set(QualityMonitor::getWorkflowStatus, Integer.valueOf(1).equals(qualityMonitor.getRatifyStatus()) ? "APPROVED" : "APPROVAL_REJECTED") ); return true; } /** * 监控计划列表 * @param page * @param qualityMonitor * @return */ @Override public IPage pageQualityMonitor(Page page, QualityMonitor qualityMonitor) { return baseMapper.pageQualityMonitor(page, QueryWrappers.queryWrappers(qualityMonitor)); } /** * 监控计划详情列表 * @param page * @param qualityMonitorDetails * @return */ @Override public IPage pageQualityMonitorDetail(Page page, QualityMonitorDetails qualityMonitorDetails) { if (qualityMonitorDetails.getQualityMonitorId() == null) { return new Page(); } return qualityMonitorDetailsMapper.pageQualityMonitorDetail(page, QueryWrappers.queryWrappers(qualityMonitorDetails)); } /** * 导出监控计划 * @param qualityMonitorId * @param response */ @Override public void exportQualityMonitorDetail(Integer qualityMonitorId, HttpServletResponse response) { // 查询详情 QualityMonitor qualityMonitor = baseMapper.selectById(qualityMonitorId); //获取提交人的签名地址 String writeUrl = userMapper.selectById(qualityMonitor.getWriteUserId()).getSignatureUrl(); if (ObjectUtils.isEmpty(writeUrl) || writeUrl.equals("")) { throw new ErrorException("找不到检验人的签名"); } //获取复核人的签名地址 String examineUrl = null; if (qualityMonitor.getExamineUserId() != null) { examineUrl = userMapper.selectById(qualityMonitor.getExamineUserId()).getSignatureUrl(); if (StringUtils.isBlank(examineUrl)) { throw new ErrorException("找不到复核人的签名"); } } //获取批准人的签名地址 String ratifyUrl = null; if (qualityMonitor.getRatifyUserId() != null) { ratifyUrl = userMapper.selectById(qualityMonitor.getRatifyUserId()).getSignatureUrl(); if (StringUtils.isBlank(ratifyUrl)) { throw new ErrorException("找不到复核人的签名"); } } // 查询详情 List qualityMonitorDetails = qualityMonitorDetailsMapper.selectList(Wrappers.lambdaQuery() .eq(QualityMonitorDetails::getQualityMonitorId, qualityMonitorId)); // 判断监控目的一样的值 AtomicInteger count = new AtomicInteger(1); Map> listMap = qualityMonitorDetails.stream().collect(Collectors.groupingBy(QualityMonitorDetails::getMonitorPurpose)); listMap.forEach((s, details) -> { // 查询数量超过1的 if (details.size() > 1) { for (QualityMonitorDetails detail : details) { detail.setMonitorPurpose(detail.getMonitorPurpose() + "∑" + count); } count.getAndIncrement(); } }); int index = 1; for (QualityMonitorDetails qualityMonitorDetail : qualityMonitorDetails) { qualityMonitorDetail.setIndex(index); index++; } // 获取路径 InputStream inputStream = this.getClass().getResourceAsStream("/static/quality-monitor.docx"); String finalExamineUrl = examineUrl; String finalRatifyUrl = ratifyUrl; Configure configure = Configure.builder() .bind("monitorDetailList", new HackLoopTableRenderPolicy()) .build(); XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( new HashMap() {{ put("year", qualityMonitor.getMonitorYear()); put("monitorDetailList", qualityMonitorDetails); put("writeUrl", StringUtils.isNotBlank(writeUrl) ? Pictures.ofLocal(imgUrl + "/" + writeUrl).create() : null); put("examineUrl", StringUtils.isNotBlank(finalExamineUrl) ? Pictures.ofLocal(imgUrl + "/" + finalExamineUrl).create() : null); put("ratifyUrl", StringUtils.isNotBlank(finalRatifyUrl) ? Pictures.ofLocal(imgUrl + "/" + finalRatifyUrl).create() : null); put("writeDateUrl", qualityMonitor.getWriteTime() != null ? Pictures.ofStream(DateImageUtil.createDateImage(qualityMonitor.getWriteTime())).create() : null); put("examineDateUrl", qualityMonitor.getExamineTime() != null ? Pictures.ofStream(DateImageUtil.createDateImage(qualityMonitor.getExamineTime())).create() : null); put("ratifyDateUrl", qualityMonitor.getRatifyTime() != null ? Pictures.ofStream(DateImageUtil.createDateImage(qualityMonitor.getRatifyTime())).create() : null); }}); // 处理换行问题 XWPFDocumentUtils.updateMergeByDocument(template.getXWPFDocument()); try { response.setContentType("application/msword"); String fileName = URLEncoder.encode( qualityMonitor.getMonitorName(), "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx"); OutputStream os = response.getOutputStream(); template.write(os); os.flush(); os.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("导出失败"); } } /************************************************************ 批准 *******************************************************************/ /** * 查询监控计划详情实施信息 * @param qualityMonitorDetailsId * @return */ @Override public QualityMonitorDetailsRatify getQualityMonitorRatify(Integer qualityMonitorDetailsId) { QualityMonitorDetailsRatify qualityMonitorDetailsRatify; // 查询监控部门id qualityMonitorDetailsRatify = qualityMonitorDetailsRatifyMapper.selectOne(Wrappers.lambdaQuery() .eq(QualityMonitorDetailsRatify::getQualityMonitorDetailsId, qualityMonitorDetailsId)); if (qualityMonitorDetailsRatify == null) { // 查询详情计划 QualityMonitorDetails qualityMonitorDetails = qualityMonitorDetailsMapper.selectById(qualityMonitorDetailsId); qualityMonitorDetailsRatify = new QualityMonitorDetailsRatify(); qualityMonitorDetailsRatify.setQualityMonitorDetailsId(qualityMonitorDetailsId); // 详情id qualityMonitorDetailsRatify.setMonitorProject(qualityMonitorDetails.getMonitorProject()); // 监控项目 qualityMonitorDetailsRatify.setMonitorData(DateUtil.format(new Date(), "yyyy-MM")); // 监控时间 qualityMonitorDetailsRatify.setMonitorPurpose(qualityMonitorDetails.getMonitorPurpose()); // 监控目的 qualityMonitorDetailsRatify.setParticipant(qualityMonitorDetails.getParticipant()); // 参加人员 qualityMonitorDetailsRatify.setBudget(qualityMonitorDetails.getBudget()); // 预算 qualityMonitorDetailsRatify.setInspectionDepartment(userMapper.selectUserDepartmentLimsName( SecurityUtils.getUserId().intValue())); } if (qualityMonitorDetailsRatify.getRatifyUserId() != null) { qualityMonitorDetailsRatify.setRatifyName(userMapper.selectById(qualityMonitorDetailsRatify.getRatifyUserId()).getName()); } return qualityMonitorDetailsRatify; } /** * 新增监控批准实施 * @param qualityMonitorDetailsRatify * @return */ @Override public boolean addQualityMonitorRatify(QualityMonitorDetailsRatify qualityMonitorDetailsRatify) { if (qualityMonitorDetailsRatify.getQualityMonitorDetailsId() == null) { throw new ErrorException("缺少监控详细信息id"); } qualityMonitorDetailsRatifyService.saveOrUpdate(qualityMonitorDetailsRatify); if (qualityMonitorDetailsRatify.getRatifyUserId() != null) { // 查询详情信息 QualityMonitorDetails monitorDetails = qualityMonitorDetailsMapper.selectById(qualityMonitorDetailsRatify.getQualityMonitorDetailsId()); Integer userId =SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); // 消息发送 InformationNotification info = new InformationNotification(); // 发送人 info.setCreateUser(user.getName()); info.setMessageType("6"); info.setTheme("CNAS质量监控实施批准通知"); info.setContent("监控项目为: " + monitorDetails.getMonitorProject() + " 质量监控实施待批准"); info.setSenderId(userId); // 接收人 info.setConsigneeId(qualityMonitorDetailsRatify.getRatifyUserId()); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); // 发送企业微信通知 threadPoolTaskExecutor.execute(() -> { // 查询发送人 User people = userMapper.selectById(qualityMonitorDetailsRatify.getRatifyUserId()); String message = ""; message += "CNAS质量监控实施批准通知"; message += "\n请去过程要求-质量监控计划"; message += "\n" + "监控项目为: " + monitorDetails.getMonitorProject() + " 质量监控实施待批准"; //发送企业微信消息通知 try { WxCpUtils.inform(people.getAccount(), message, null); } catch (Exception e) { throw new RuntimeException(e); } }); } // 清空状态 qualityMonitorDetailsRatifyService.update(Wrappers.lambdaUpdate() .eq(QualityMonitorDetailsRatify::getDetailsRatifyId, qualityMonitorDetailsRatify.getDetailsRatifyId()) .set(QualityMonitorDetailsRatify::getIsFinish, null)); return true; } /** * 监控计划详情批准意见 * @param qualityMonitorDetailsRatify * @return */ @Override public boolean addQualityMonitorRatifyOpinion(QualityMonitorDetailsRatify qualityMonitorDetailsRatify) { LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate() .eq(QualityMonitorDetailsRatify::getDetailsRatifyId, qualityMonitorDetailsRatify.getDetailsRatifyId()) .set(QualityMonitorDetailsRatify::getRatifyOpinion, qualityMonitorDetailsRatify.getRatifyOpinion()) .set(QualityMonitorDetailsRatify::getIsFinish, qualityMonitorDetailsRatify.getIsFinish()); // 为0清除审核人 if (qualityMonitorDetailsRatify.getIsFinish().equals(0)) { wrapper.set(QualityMonitorDetailsRatify::getRatifyUserId, null); } qualityMonitorDetailsRatifyService.update(wrapper); return true; } /** * 导出监控计划详情实施信息 * * @param detailsRatifyId 监控计划详情实施id * @param response 响应 */ @Override public void exportQualityMonitorRatify(Integer detailsRatifyId, HttpServletResponse response) { QualityMonitorDetailsRatify qualityMonitorDetailsRatify = qualityMonitorDetailsRatifyMapper.selectOne(Wrappers.lambdaQuery().eq(QualityMonitorDetailsRatify::getQualityMonitorDetailsId, detailsRatifyId)); // 获取路径 InputStream inputStream = this.getClass().getResourceAsStream("/static/quality-monitor-details-ratify.docx"); Configure configure = Configure.builder() .bind("processMethodVerifyMachineAttachmentList", new HackLoopTableRenderPolicy()) .build(); XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( new HashMap() {{ put("qualityMonitorDetailsRatify", qualityMonitorDetailsRatify); put("ratifyUserUrl", UserUtils.getFinalUserSignatureUrl(qualityMonitorDetailsRatify.getRatifyUserId())); }}); try { response.setContentType("application/msword"); String fileName = URLEncoder.encode( "质量监控实施计划", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx"); OutputStream os = response.getOutputStream(); template.write(os); os.flush(); os.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("导出失败"); } } /************************************************************ 评价 *******************************************************************/ /** * 查询质量监控评价 * @param qualityMonitorDetailsId * @return */ @Override public QualityMonitorDetailsEvaluate getQualityMonitorEvaluate(Integer qualityMonitorDetailsId) { return qualityMonitorDetailsEvaluateMapper.getQualityMonitorEvaluate(qualityMonitorDetailsId); } /** * 新增监控评价 * @param qualityMonitorDetailsEvaluate * @return */ @Override public boolean addQualityMonitorEvaluate(QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate) { if (qualityMonitorDetailsEvaluate.getQualityMonitorDetailsId() == null) { throw new ErrorException("缺少监控详细信息id"); } // 查询详情信息 QualityMonitorDetails monitorDetails = qualityMonitorDetailsMapper.selectById(qualityMonitorDetailsEvaluate.getQualityMonitorDetailsId()); // 发送消息通知 // 判断评审结论人是否为空 if (qualityMonitorDetailsEvaluate.getRatifyUserId() != null) { Integer userId =SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); // 消息发送 InformationNotification info = new InformationNotification(); // 发送人 info.setCreateUser(user.getName()); info.setMessageType("6"); info.setTheme("CNAS质量监控评价结论通知"); info.setContent("监控项目为: " + monitorDetails.getMonitorProject() + " 质量监控待评价结论"); info.setSenderId(userId); // 接收人 info.setConsigneeId(qualityMonitorDetailsEvaluate.getRatifyUserId()); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); // 发送企业微信通知 threadPoolTaskExecutor.execute(() -> { // 查询发送人 User people = userMapper.selectById(qualityMonitorDetailsEvaluate.getRatifyUserId()); String message = ""; message += "CNAS质量监控评价结论通知"; message += "\n请去过程要求-质量监控计划"; message += "\n" + "监控项目为: " + monitorDetails.getMonitorProject() + " 质量监控待评价结论"; //发送企业微信消息通知 try { WxCpUtils.inform(people.getAccount(), message, null); } catch (Exception e) { throw new RuntimeException(e); } }); } else { // 监控结果评价 if (qualityMonitorDetailsEvaluate.getImplementUserId() != null) { Integer userId =SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); // 消息发送 InformationNotification info = new InformationNotification(); // 发送人 info.setCreateUser(user.getName()); info.setMessageType("6"); info.setTheme("CNAS质量监控结果评价"); info.setContent("监控项目为: " + monitorDetails.getMonitorProject() + " 质量监控待评价结论"); info.setSenderId(userId); // 接收人 info.setConsigneeId(qualityMonitorDetailsEvaluate.getImplementUserId()); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); // 发送企业微信通知 threadPoolTaskExecutor.execute(() -> { // 查询发送人 User people = userMapper.selectById(qualityMonitorDetailsEvaluate.getImplementUserId()); String message = ""; message += "CNAS质量监控结果评价"; message += "\n请去过程要求-质量监控计划"; message += "\n" + "监控项目为: " + monitorDetails.getMonitorProject() + " 质量监控待评价结论"; //发送企业微信消息通知 try { WxCpUtils.inform(people.getAccount(), message, null); } catch (Exception e) { throw new RuntimeException(e); } }); } } return qualityMonitorDetailsEvaluateService.saveOrUpdate(qualityMonitorDetailsEvaluate); } /** * 监控评价审批意见 * @param qualityMonitorDetailsEvaluate * @return */ @Override public boolean addMonitorEvaluateOpinion(QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate) { qualityMonitorDetailsEvaluateService.update(Wrappers.lambdaUpdate() .eq(QualityMonitorDetailsEvaluate::getDetailsEvaluateId, qualityMonitorDetailsEvaluate.getDetailsEvaluateId()) .set(QualityMonitorDetailsEvaluate::getRatifyOpinion, qualityMonitorDetailsEvaluate.getRatifyOpinion()) .set(QualityMonitorDetailsEvaluate::getRatifyTime, LocalDateTime.now()) .set(QualityMonitorDetailsEvaluate::getIsFinish, 1)); return true; } /** * 新增监控评价附件表 * @param qualityMonitorDetailsId * @param file * @return */ @Override public boolean uploadEvaluateFile(Integer qualityMonitorDetailsId, MultipartFile file) { if (qualityMonitorDetailsId == null) { throw new ErrorException("缺少监控详情id"); } String urlString; String pathName; String path; String filename = file.getOriginalFilename(); String contentType = file.getContentType(); QualityMonitorDetailsEvaluateFile evaluateFile = new QualityMonitorDetailsEvaluateFile(); evaluateFile.setDetailsEvaluateId(qualityMonitorDetailsId); evaluateFile.setFileName(filename); if (contentType != null && contentType.startsWith("image/")) { // 是图片 path = imgUrl; evaluateFile.setType(1); } else { // 是文件 path = wordUrl; evaluateFile.setType(2); } try { File realpath = new File(path); if (!realpath.exists()) { realpath.mkdirs(); } pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + file.getOriginalFilename(); urlString = realpath + "/" + pathName; file.transferTo(new File(urlString)); evaluateFile.setFileUrl(pathName); qualityMonitorDetailsEvaluateFileMapper.insert(evaluateFile); return true; } catch (Exception e) { e.printStackTrace(); System.err.println("附件上传错误"); return false; } } /** * 查询监控评价附件列表 * @return */ @Override public List getEvaluateFileList(Integer qualityMonitorDetailsId) { return qualityMonitorDetailsEvaluateFileMapper.selectList(Wrappers.lambdaQuery() .eq(QualityMonitorDetailsEvaluateFile::getDetailsEvaluateId, qualityMonitorDetailsId)); } /** * 导出监控评价 * @param detailsEvaluateId 监控评价id */ @Override public void exportQualityMonitorEvaluate(Integer detailsEvaluateId, HttpServletResponse response) { // 查询监控评价信息 QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate = qualityMonitorDetailsEvaluateMapper.selectOne(Wrappers.lambdaQuery().eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId,detailsEvaluateId)); // 渲染word模板对象 QualityMonitorDetailsEvaluateDto qualityMonitorDetailsEvaluateDto = new QualityMonitorDetailsEvaluateDto(); BeanUtils.copyProperties(qualityMonitorDetailsEvaluate, qualityMonitorDetailsEvaluateDto); // 格式化时间 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); qualityMonitorDetailsEvaluateDto.setRatifyTimeStr(qualityMonitorDetailsEvaluate.getRatifyTime() == null ? null : qualityMonitorDetailsEvaluate.getRatifyTime().format(dateTimeFormatter)); // 获取路径 InputStream inputStream = this.getClass().getResourceAsStream("/static/quality-monitor-evaluate.docx"); Configure configure = Configure.builder() .build(); XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( new HashMap() {{ put("qualityMonitorDetailsEvaluate", qualityMonitorDetailsEvaluateDto); put("implementUserUrl", UserUtils.getFinalUserSignatureUrl(Integer.valueOf(qualityMonitorDetailsEvaluate.getImplementUserId()))); put("ratifyUserUrl", UserUtils.getFinalUserSignatureUrl(qualityMonitorDetailsEvaluate.getRatifyUserId())); }}); try { response.setContentType("application/msword"); String fileName = URLEncoder.encode( "监控评价", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx"); OutputStream os = response.getOutputStream(); template.write(os); os.flush(); os.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("导出失败"); } } /************************************************** 监控完成报告 ****************************************************************/ /** * 上传监控完成报告 * @param file * @param qualityMonitorDetailsId * @return */ @Override public boolean uploadFinishReport(MultipartFile file, Integer qualityMonitorDetailsId) { if (qualityMonitorDetailsId == null) { throw new ErrorException("缺少监控详情id"); } LocalDateTime now = LocalDateTime.now(); Integer userId =SecurityUtils.getUserId().intValue(); String contentType = file.getContentType(); String urlString; String pathName; try { String path = wordUrl; File realpath = new File(path); if (!realpath.exists()) { realpath.mkdirs(); } pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + file.getOriginalFilename(); urlString = realpath + "/" + pathName; file.transferTo(new File(urlString)); // 判断是否是pdf if (!contentType.contains("pdf")) { wordInsertUrl(new HashMap() {{ put("writeUrl", UserUtils.getFinalUserSignatureUrl(userId)); put("writeDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(now)).create()); }}, wordUrl + "/" + pathName.replace("/word", wordUrl)); } qualityMonitorDetailsService.update(Wrappers.lambdaUpdate() .eq(QualityMonitorDetails::getQualityMonitorDetailsId, qualityMonitorDetailsId) .set(QualityMonitorDetails::getFinishReportUrl, pathName) .set(QualityMonitorDetails::getWriteTime, now)); return true; } catch (Exception e) { e.printStackTrace(); throw new ErrorException("文件上传失败"); } } /** * 批准完成报告 * @param qualityMonitorDetails * @return */ @Override public boolean ratifyFinishReport(QualityMonitorDetails qualityMonitorDetails) { LocalDateTime now = LocalDateTime.now(); Integer userId =SecurityUtils.getUserId().intValue(); LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate() .eq(QualityMonitorDetails::getQualityMonitorDetailsId, qualityMonitorDetails.getQualityMonitorDetailsId()) .set(QualityMonitorDetails::getRatifyUserId, userId) .set(QualityMonitorDetails::getRatifyRemark, qualityMonitorDetails.getRatifyRemark()) .set(QualityMonitorDetails::getRatifyStatus, qualityMonitorDetails.getRatifyStatus()) .set(QualityMonitorDetails::getRatifyTime, now); if (qualityMonitorDetails.getRatifyStatus().equals(0)) { wrapper.set(QualityMonitorDetails::getFinishReportUrl, null); } qualityMonitorDetailsMapper.update(null, wrapper); // 添加批准人 QualityMonitorDetails details = qualityMonitorDetailsMapper.selectById(qualityMonitorDetails.getQualityMonitorDetailsId()); if (StringUtils.isNotBlank(details.getFinishReportUrl()) && !details.getFinishReportUrl().contains(".pdf")) { wordInsertUrl(new HashMap() {{ put("ratifyUrl", UserUtils.getFinalUserSignatureUrl(userId)); put("ratifyDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(now)).create()); }}, wordUrl + "/" + details.getFinishReportUrl().replace("/word", wordUrl)); } return true; } public int wordInsertUrl(Map map, String url) { XWPFTemplate template = XWPFTemplate.compile(url).render(map); try { template.writeAndClose(Files.newOutputStream(Paths.get(url))); } catch (IOException e) { throw new RuntimeException(e); } return 1; } }