package com.ruoyi.process.service.impl; import cn.hutool.core.lang.UUID; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; 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.config.ConfigureBuilder; import com.deepoove.poi.data.*; import com.deepoove.poi.data.style.*; import com.ruoyi.common.core.domain.entity.User; import com.ruoyi.common.utils.QueryWrappers; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.mapper.InsOrderMapper; import com.ruoyi.inspect.mapper.InsSampleMapper; import com.ruoyi.inspect.mapper.InsSampleReceiptMapper; import com.ruoyi.inspect.pojo.InsOrder; import com.ruoyi.inspect.pojo.InsSample; import com.ruoyi.inspect.pojo.InsSampleReceipt; import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; import com.ruoyi.inspect.util.UserUtils; import org.apache.commons.lang3.StringUtils; import com.ruoyi.process.dto.ProcessDealDto; import com.ruoyi.process.mapper.ProcessDealMapper; import com.ruoyi.process.mapper.ProcessTotaldealMapper; import com.ruoyi.process.pojo.ProcessDeal; import com.ruoyi.process.pojo.ProcessTotaldeal; import com.ruoyi.process.service.ProcessDealService; import com.ruoyi.process.service.ProcessTotaldealService; import com.ruoyi.system.mapper.UserMapper; import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.parameters.P; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.xml.soap.SAAJMetaFactory; import java.io.*; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Paths; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.YearMonth; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** *

* 检测或校准物品的处置总表(历史) 服务实现类 *

* * @author * @since 2024-11-02 03:59:09 */ @Service @Transactional(rollbackFor = Exception.class) public class ProcessTotaldealServiceImpl extends ServiceImpl implements ProcessTotaldealService { @Resource private ProcessTotaldealMapper processTotaldealMapper; @Resource private ProcessDealService processDealService; @Resource private ProcessDealMapper processDealMapper; @Value("${file.path}") private String imgUrl; @Resource private UserMapper userMapper; @Resource private InsOrderMapper insOrderMapper; @Resource private InsSampleMapper insSampleMapper; @Resource private InsSampleReceiptMapper insSampleReceiptMapper; @Override public IPage pageProcessTotaldeal(Page page, ProcessTotaldeal processTotaldeal) { return processTotaldealMapper.pageProcessTotaldeal(page, QueryWrappers.queryWrappers(processTotaldeal)); } @Override public int submitProcessTotaldeal(Integer id) { Integer userId = SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); if (ObjectUtils.isEmpty(user.getSignatureUrl())) { throw new ErrorException("未找到填表人的电子签名,请上传自己的电子签名!"); } ProcessTotaldeal processTotaldeal = processTotaldealMapper.selectById(id); processTotaldeal.setSubmitUser(userId); processTotaldeal.setSubmitState("已提交"); return processTotaldealMapper.updateById(processTotaldeal); } @Override public int checkProcessTotaldeal(Integer id, String state) { Integer userId = SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); if (ObjectUtils.isEmpty(user.getSignatureUrl())) { throw new ErrorException("未找到审核人的电子签名,请上传自己的电子签名!"); } ProcessTotaldeal processTotaldeal = processTotaldealMapper.selectById(id); processTotaldeal.setExamineUser(userId); processTotaldeal.setExamineState(state); if (state.equals("不通过")) { processTotaldeal.setSubmitState("待提交"); } return processTotaldealMapper.updateById(processTotaldeal); } @Override public int ratifyProcessTotaldeal(Integer id, String state) { Integer userId = SecurityUtils.getUserId().intValue(); User user = userMapper.selectById(userId); if (ObjectUtils.isEmpty(user.getSignatureUrl())) { throw new ErrorException("未找到批准人的电子签名,请上传自己的电子签名!"); } ProcessTotaldeal processTotaldeal = processTotaldealMapper.selectById(id); processTotaldeal.setRatifyUser(userId); processTotaldeal.setRatifyState(state); if (state.equals("不通过")) { processTotaldeal.setExamineState(state); processTotaldeal.setSubmitState("待提交"); } return processTotaldealMapper.updateById(processTotaldeal); } @Override public int addProcessTotaldeal(String month) { //新增总表(同一月份复用已有总表) ProcessTotaldeal processTotaldeal; List processTotaldeals = processTotaldealMapper.selectList(Wrappers.lambdaQuery() .eq(ProcessTotaldeal::getMonth, month)); if (processTotaldeals.size() <= 0) { processTotaldeal = new ProcessTotaldeal(); processTotaldeal.setMonth(month);//月份 processTotaldeal.setSubmitState("待提交"); processTotaldealMapper.insert(processTotaldeal); } else { processTotaldeal = processTotaldeals.get(0); } //1.获取该月份的第一天和最后一天 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); YearMonth yearMonth = YearMonth.parse(month, formatter); LocalDateTime startTime = yearMonth.atDay(1).atStartOfDay(); LocalDateTime endTime = yearMonth.atEndOfMonth().atTime(LocalTime.MAX); //2.该月下单的委托单(排除原材料,typeSource 为空视为成品) List orders = insOrderMapper.selectList(Wrappers.lambdaQuery() .ge(InsOrder::getCreateTime, startTime) .le(InsOrder::getCreateTime, endTime)); if (orders.isEmpty()) { return 0; } //3.只保留已生成样品接收记录的委托(已审核受理) List orderIds = orders.stream().map(InsOrder::getId).collect(Collectors.toList()); List receipts = insSampleReceiptMapper.selectList(Wrappers.lambdaQuery() .in(InsSampleReceipt::getInsOrderId, orderIds)); Set receiptOrderIds = receipts.stream().map(InsSampleReceipt::getInsOrderId).collect(Collectors.toSet()); Map orderMap = orders.stream() .filter(order -> !Integer.valueOf(1).equals(order.getTypeSource())) .filter(order -> receiptOrderIds.contains(order.getId())) .collect(Collectors.toMap(InsOrder::getId, order -> order, (a, b) -> a)); if (orderMap.isEmpty()) { return 0; } //4.委托对应的样品 List samples = insSampleMapper.selectList(Wrappers.lambdaQuery() .in(InsSample::getInsOrderId, orderMap.keySet())); if (samples.isEmpty()) { return 0; } //5.已进入任何处置批次的样品跳过(跨月也不会重复带入) List sampleIds = samples.stream().map(InsSample::getId).collect(Collectors.toList()); Set dealtSampleIds = processDealService.list(Wrappers.lambdaQuery() .select(ProcessDeal::getInsSampleId) .in(ProcessDeal::getInsSampleId, sampleIds)) .stream().map(ProcessDeal::getInsSampleId).filter(Objects::nonNull).collect(Collectors.toSet()); List processDeals = new ArrayList<>(); for (InsSample insSample : samples) { if (dealtSampleIds.contains(insSample.getId())) { continue; } InsOrder order = orderMap.get(insSample.getInsOrderId()); ProcessDeal processDeal = new ProcessDeal(); //样品名称优先取报告展示字段 processDeal.setSampleName(order != null && StringUtils.isNotBlank(order.getSampleView()) ? order.getSampleView() : insSample.getSample()); processDeal.setSampleCode(insSample.getSampleCode());//样品编号 processDeal.setSampleSupplier(order == null ? null : order.getCompany());//供样单位=委托单位 processDeal.setNum(insSample.getQuantity() == null ? 1 : insSample.getQuantity());//样品数量 processDeal.setDealMethod(resolveDealMethod(order));//处理方式=下单时选择的样品处置 processDeal.setDealTime(LocalDate.now());//时间=当前时间 processDeal.setTotaldealId(processTotaldeal.getId());//总表id processDeal.setInsSampleId(insSample.getId());//检验样品id processDeals.add(processDeal); } if (!processDeals.isEmpty()) { processDealService.saveBatch(processDeals); } return processDeals.size(); } /** * 处理方式:下单时的样品处置 1委托方取回 2检测方处置;历史单无该字段时回退旧的处理方式字段 */ private String resolveDealMethod(InsOrder order) { if (order == null) { return StringUtils.EMPTY; } if (Integer.valueOf(1).equals(order.getSampleDisposal())) { return "委托单位取回"; } if (Integer.valueOf(2).equals(order.getSampleDisposal())) { return "实验室处理"; } return Integer.valueOf(1).equals(order.getProcessing()) ? "实验室处理" : "委托单位取回"; } @Override public void exportProcessTotaldeal(Integer id, HttpServletResponse response) { List sampleDealDtos = processDealMapper.selectDeal(id); ProcessTotaldeal processTotaldeal = processTotaldealMapper.selectById(id); // 获取路径 InputStream inputStream = this.getClass().getResourceAsStream("/static/sample-deal.docx"); Configure configure = Configure.builder() .bind("sampleList", new HackLoopTableRenderPolicy()) .build(); XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( new HashMap() {{ put("sampleList", sampleDealDtos); put("writeUrl",UserUtils.getFinalUserSignatureUrl(processTotaldeal.getSubmitUser()));//提交人 put("examineUrl", UserUtils.getFinalUserSignatureUrl(processTotaldeal.getExamineUser()));//审核人 put("ratifyUrl", UserUtils.getFinalUserSignatureUrl(processTotaldeal.getRatifyUser()));//批准人 }}); 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("导出失败"); } } }