package com.ruoyi.process.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.ruoyi.common.numgen.NumberGenerator;
import com.ruoyi.common.core.domain.entity.Custom;
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.dto.InsPlaceOrderDto;
import com.ruoyi.inspect.mapper.InsProductResultMapper;
import com.ruoyi.inspect.mapper.InsSampleMapper;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.pojo.InsProductResult;
import com.ruoyi.inspect.pojo.InsReport;
import com.ruoyi.inspect.service.InsOrderService;
import com.ruoyi.inspect.service.InsReportService;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
import com.ruoyi.process.dto.InspectionOrderDto;
import com.ruoyi.process.dto.InspectionOrderExportDto;
import com.ruoyi.process.mapper.InspectionOrderBindLogMapper;
import com.ruoyi.process.mapper.InspectionOrderMapper;
import com.ruoyi.process.mapper.ProcessOrderDeviceMapper;
import com.ruoyi.process.mapper.ProcessSampleMapper;
import com.ruoyi.process.pojo.InspectionOrder;
import com.ruoyi.process.pojo.InspectionOrderBindLog;
import com.ruoyi.process.pojo.InspectionOrderDetail;
import com.ruoyi.process.pojo.ProcessOrderDevice;
import com.ruoyi.process.service.*;
import com.ruoyi.system.mapper.UserMapper;
import com.ruoyi.system.mapper.CustomMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
*
* 检验委托单 服务实现类
*
*
* @author 江苏鵷雏网络科技有限公司
* @since 2024-12-09
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class InspectionOrderServiceImpl extends ServiceImpl implements InspectionOrderService {
@Resource
private InspectionOrderBindLogMapper inspectionOrderBindLogMapper;
@Resource
private InspectionOrderDetailService inspectionOrderDetailService;
@Resource
private InsOrderService insOrderService;
@Resource
private InsSampleMapper insSampleMapper;
@Resource
private InsReportService insReportService;
@Value("${wordUrl}")
private String wordUrl;
@Resource
private ProcessReportService processReportService;
@Resource
private ProcessOrderDeviceMapper processOrderDeviceMapper;
@Resource
private InsProductResultMapper insProductResultMapper;
@Resource
private ProcessOrderDeviceService processOrderDeviceService;
@Resource
private UserMapper userMapper;
@Resource
private CustomMapper customMapper;
@Resource
private ProcessSampleService processSampleService;
@Resource
private ProcessSampleMapper processSampleMapper;
@Resource
private ProcessDealService processDealService;
@Resource
private NumberGenerator numberGenerator;
/**
* 检验委托单分页查询
*
* @param page
* @param InspectionOrder
* @return
*/
@Override
public IPage pageInspectionOrder(Page page, InspectionOrder InspectionOrder) {
return baseMapper.pageInspectionOrder(page, QueryWrappers.queryWrappers(InspectionOrder));
}
/**
* 检验委托单新增
*
* @param inspectionOrder
* @return
*/
@Override
public InspectionOrderDto addInspectionOrder(InspectionOrderDto inspectionOrder) {
if (inspectionOrder.getInsOrderId() != null) {
throw new ErrorException("新增检验委托单不允许直接绑定成品下单,请在成品下单页面选择委托单");
}
normalizeCommissionParty(inspectionOrder);
inspectionOrder.setInspectionOrderCode(numberGenerator.generateNumberWithPrefix(4,
"WTD" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")),
InspectionOrder::getInspectionOrderCode));
// 委托编号由成品下单流程生成,委托单新增阶段不得手工填写。
inspectionOrder.setEntrustCode(null);
inspectionOrder.setFileUrl(null);
baseMapper.insert(inspectionOrder);
// 新增详情
if (CollectionUtils.isNotEmpty(inspectionOrder.getOrderDetailList())) {
for (InspectionOrderDetail InspectionOrderDetail : inspectionOrder.getOrderDetailList()) {
InspectionOrderDetail.setInspectionOrderId(inspectionOrder.getInspectionOrderId());
}
inspectionOrderDetailService.saveBatch(inspectionOrder.getOrderDetailList());
}
return inspectionOrder;
}
private synchronized void addDeviceRecord(InspectionOrder inspectionOrder, Integer userId) {
// 查询设备使用记录查询该订单的使用记录
Set recordCodeset = processOrderDeviceMapper.selectDeviceNumber(inspectionOrder.getInspectionOrderId());
// 获取订单设备编号
List resultList = insProductResultMapper.selectResultByOrderId(inspectionOrder.getInsOrderId());
Set deviceCodeSet = new HashSet<>();
for (InsProductResult result : resultList) {
// 添加设备编号
List jsonObjects = JSON.parseArray(result.getEquipValue(), JSONObject.class);
for (JSONObject jsonObject : jsonObjects) {
if (!"".equals(jsonObject.get("v") + "")) {
List v = StrUtil.split(jsonObject.get("v") + "", ",");
deviceCodeSet.addAll(v);
}
}
}
// 1.判断是否有没有添加的使用记录
Set orderDeviceNumbers = getDeviceDifference(deviceCodeSet, recordCodeset);
// 添加使用记录, 根据编号查询设备id
if (CollectionUtils.isNotEmpty(orderDeviceNumbers)) {
List orderDeviceIds = processOrderDeviceMapper.selectDeviceIdsByNumbers(orderDeviceNumbers);
List collect = orderDeviceIds.stream().map(deviceId -> {
ProcessOrderDevice processOrderDevice = new ProcessOrderDevice();
processOrderDevice.setInspectionOrderId(inspectionOrder.getInspectionOrderId());
processOrderDevice.setDeviceId(deviceId);
processOrderDevice.setSampleCode(inspectionOrder.getEntrustCode());
processOrderDevice.setUseBefore(1);
processOrderDevice.setUseAfter(1);
processOrderDevice.setUsePerson(userMapper.selectById(userId).getName());//使用人
processOrderDevice.setUsePersonId(userId);//使用人id
return processOrderDevice;
}).collect(Collectors.toList());
processOrderDeviceService.saveBatch(collect);
}
}
private static Set getDeviceDifference(Set number1, Set number2) {
return number1.stream().filter(s1 -> number2.stream().noneMatch(s2 -> s1.equals(s2)))
.collect(Collectors.toSet());
}
/**
* 检验委托单修改
*
* @param InspectionOrder
* @return
*/
@Override
public boolean updateInspectionOrder(InspectionOrderDto InspectionOrder) {
InspectionOrder oldInspectionOrder = baseMapper.selectById(InspectionOrder.getInspectionOrderId());
if (oldInspectionOrder == null) {
throw new ErrorException("检验委托单不存在");
}
normalizeCommissionParty(InspectionOrder);
// 编号、关联关系、正式委托编号和报告地址只能由专用流程维护。
InspectionOrder.setInspectionOrderCode(null);
InspectionOrder.setInsOrderId(null);
InspectionOrder.setEntrustCode(null);
InspectionOrder.setFileUrl(null);
InspectionOrder.setSampleTakerUserId(null);
InspectionOrder.setSampleTakerUser(null);
baseMapper.updateById(InspectionOrder);
// 删除之前的详情
inspectionOrderDetailService.remove(Wrappers.lambdaQuery()
.eq(InspectionOrderDetail::getInspectionOrderId, InspectionOrder.getInspectionOrderId()));
// 新增详情
if (CollectionUtils.isNotEmpty(InspectionOrder.getOrderDetailList())) {
for (InspectionOrderDetail InspectionOrderDetail : InspectionOrder.getOrderDetailList()) {
InspectionOrderDetail.setInspectionOrderId(InspectionOrder.getInspectionOrderId());
}
inspectionOrderDetailService.saveBatch(InspectionOrder.getOrderDetailList());
}
return true;
}
/**
* 检验委托单删除
*
* @param inspectionOrderId
* @return
*/
@Override
public boolean delInspectionOrder(Integer inspectionOrderId) {
InspectionOrder inspectionOrder = baseMapper.selectById(inspectionOrderId);
if (inspectionOrder == null) {
throw new ErrorException("检验委托单不存在");
}
if (inspectionOrder.getInsOrderId() != null) {
throw new ErrorException("已绑定成品下单的检验委托单不允许删除");
}
inspectionOrderDetailService.remove(Wrappers.lambdaQuery()
.eq(InspectionOrderDetail::getInspectionOrderId, inspectionOrderId));
baseMapper.deleteById(inspectionOrderId);
return true;
}
/**
* 检验委托单查看详情
*
* @param inspectionOrderId
* @return
*/
@Override
public InspectionOrderDto getInspectionOrderOne(Integer inspectionOrderId) {
InspectionOrder inspectionOrder = baseMapper.selectById(inspectionOrderId);
InspectionOrderDto inspectionOrderDto = new InspectionOrderDto();
BeanUtils.copyProperties(inspectionOrder, inspectionOrderDto);
// 查询详细信息
inspectionOrderDto.setOrderDetailList(inspectionOrderDetailService.list(Wrappers.lambdaQuery()
.eq(InspectionOrderDetail::getInspectionOrderId, inspectionOrderId)));
return inspectionOrderDto;
}
@Override
public IPage pageUnboundInspectionOrder(Page page, InspectionOrder inspectionOrder) {
return baseMapper.pageUnboundInspectionOrder(page, QueryWrappers.queryWrappers(inspectionOrder));
}
@Override
public InspectionOrderDto getInspectionOrderForPlaceOrder(Integer inspectionOrderId) {
InspectionOrder inspectionOrder = baseMapper.selectById(inspectionOrderId);
if (inspectionOrder == null) {
throw new ErrorException("检验委托单不存在");
}
if (inspectionOrder.getInsOrderId() != null) {
throw new ErrorException("该检验委托单已绑定成品下单,不能重复选择");
}
return getInspectionOrderOne(inspectionOrderId);
}
@Override
public Integer addInsOrderWithInspectionOrder(InsPlaceOrderDto insPlaceOrderDto) {
if (insPlaceOrderDto == null || insPlaceOrderDto.getInspectionOrderId() == null) {
throw new ErrorException("请选择检验委托单");
}
if (insPlaceOrderDto.getInsOrder() == null) {
throw new ErrorException("缺少成品下单信息");
}
InspectionOrder inspectionOrder = baseMapper.selectById(insPlaceOrderDto.getInspectionOrderId());
if (inspectionOrder == null) {
throw new ErrorException("检验委托单不存在");
}
if (inspectionOrder.getInsOrderId() != null) {
throw new ErrorException("该检验委托单已绑定成品下单,不能重复提交");
}
if (inspectionOrder.getCommissionUnitId() == null) {
throw new ErrorException("请先完善委托单位");
}
if (inspectionOrder.getCommissionUserId() == null) {
throw new ErrorException("请先完善委托人");
}
fillInsOrderFromInspectionOrder(inspectionOrder, insPlaceOrderDto.getInsOrder());
Integer insOrderId = insOrderService.addInsOrder(insPlaceOrderDto.getSampleList(), insPlaceOrderDto.getInsOrder());
Long sampleTakerUserId = SecurityUtils.getUserId();
User sampleTaker = sampleTakerUserId == null ? null : userMapper.selectById(sampleTakerUserId);
int updated = baseMapper.update(null, Wrappers.lambdaUpdate()
.eq(InspectionOrder::getInspectionOrderId, inspectionOrder.getInspectionOrderId())
.isNull(InspectionOrder::getInsOrderId)
.set(InspectionOrder::getInsOrderId, insOrderId)
.set(InspectionOrder::getSampleTakerUserId, sampleTakerUserId == null ? null : sampleTakerUserId.intValue())
.set(InspectionOrder::getSampleTakerUser, sampleTaker == null ? null : sampleTaker.getName()));
if (updated != 1) {
throw new ErrorException("检验委托单已被其他下单绑定,请刷新后重试");
}
return insOrderId;
}
private void fillInsOrderFromInspectionOrder(InspectionOrder inspectionOrder, InsOrder insOrder) {
insOrder.setEntrustCode(null);
insOrder.setSample(inspectionOrder.getSampleName());
insOrder.setCompany(inspectionOrder.getCommissionUnit());
insOrder.setCompanyId(inspectionOrder.getCommissionUnitId());
insOrder.setProduction(inspectionOrder.getProduction());
insOrder.setPrepareUser(inspectionOrder.getCommissionUser());
insOrder.setPhone(inspectionOrder.getCommissionPhone());
insOrder.setSampleStatus(inspectionOrder.getSampleStatus());
insOrder.setIsLeave(inspectionOrder.getIsLeave());
insOrder.setProcessing(inspectionOrder.getProcessing());
insOrder.setAppointed(inspectionOrder.getAppointed());
insOrder.setSend(inspectionOrder.getSend());
}
/** 仅信任客户和人员主数据,名称与电话均以主数据快照为准。 */
private void normalizeCommissionParty(InspectionOrder inspectionOrder) {
if (inspectionOrder.getCommissionUnitId() == null) {
throw new ErrorException("请选择委托单位");
}
Custom custom = customMapper.selectById(inspectionOrder.getCommissionUnitId());
if (custom == null) {
throw new ErrorException("委托单位不存在或已停用");
}
inspectionOrder.setCommissionUnit(custom.getCompany());
if (inspectionOrder.getCommissionUserId() == null) {
throw new ErrorException("请选择委托人");
}
User commissionUser = userMapper.selectById(inspectionOrder.getCommissionUserId());
if (commissionUser == null) {
throw new ErrorException("委托人不存在或已停用");
}
inspectionOrder.setCommissionUser(commissionUser.getName());
inspectionOrder.setCommissionPhone(commissionUser.getPhone());
}
@Override
public void syncEntrustCode(Integer insOrderId) {
if (insOrderId == null) {
return;
}
InsOrder insOrder = insOrderService.getById(insOrderId);
if (insOrder == null || StrUtil.isBlank(insOrder.getEntrustCode())) {
return;
}
baseMapper.update(null, Wrappers.lambdaUpdate()
.eq(InspectionOrder::getInsOrderId, insOrderId)
.set(InspectionOrder::getEntrustCode, insOrder.getEntrustCode()));
}
@Override
public void syncReportFile(Integer insReportId) {
if (insReportId == null) {
return;
}
InsReport insReport = insReportService.getById(insReportId);
if (insReport == null || !Integer.valueOf(1).equals(insReport.getIsRatify())) {
return;
}
InspectionOrder inspectionOrder = baseMapper.selectOne(Wrappers.lambdaQuery()
.eq(InspectionOrder::getInsOrderId, insReport.getInsOrderId())
.last("limit 1"));
if (inspectionOrder == null) {
return;
}
String sourceUrl = StrUtil.isBlank(insReport.getUrlS()) ? insReport.getUrl() : insReport.getUrlS();
if (StrUtil.isBlank(sourceUrl)) {
throw new ErrorException("正式报告文件不存在,无法同步到检验委托单");
}
String sourceFileName = sourceUrl.substring(sourceUrl.lastIndexOf('/') + 1);
String extension = sourceFileName.lastIndexOf('.') >= 0
? sourceFileName.substring(sourceFileName.lastIndexOf('.')) : ".docx";
String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"))
+ "_" + inspectionOrder.getInspectionOrderCode() + "_委托单报告" + extension;
Path sourcePath = Paths.get(wordUrl + sourceUrl.replaceFirst("/word", ""));
Path targetPath = Paths.get(wordUrl, fileName);
try {
if (!Files.exists(sourcePath)) {
throw new ErrorException("正式报告文件不存在,无法同步到检验委托单");
}
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
baseMapper.update(null, Wrappers.lambdaUpdate()
.eq(InspectionOrder::getInspectionOrderId, inspectionOrder.getInspectionOrderId())
.set(InspectionOrder::getFileUrl, "/word/" + fileName));
} catch (ErrorException e) {
throw e;
} catch (Exception e) {
throw new ErrorException("报告同步失败");
}
}
@Override
public boolean changeBinding(Integer insOrderId, Integer inspectionOrderId, String reason) {
if (insOrderId == null || inspectionOrderId == null || StrUtil.isBlank(reason)) {
throw new ErrorException("缺少变更关联所需参数");
}
InsOrder insOrder = insOrderService.getById(insOrderId);
if (insOrder == null) {
throw new ErrorException("成品下单不存在");
}
if (!(Integer.valueOf(0).equals(insOrder.getState()) || Integer.valueOf(2).equals(insOrder.getState()))
|| StrUtil.isNotBlank(insOrder.getEntrustCode())) {
throw new ErrorException("当前下单已进入检验流程或已生成委托编号,不允许变更关联");
}
InspectionOrder target = baseMapper.selectById(inspectionOrderId);
if (target == null || target.getInsOrderId() != null) {
throw new ErrorException("目标检验委托单不存在或已被绑定");
}
InspectionOrder oldInspectionOrder = baseMapper.selectOne(Wrappers.lambdaQuery()
.eq(InspectionOrder::getInsOrderId, insOrderId));
baseMapper.update(null, Wrappers.lambdaUpdate()
.eq(InspectionOrder::getInsOrderId, insOrderId)
.set(InspectionOrder::getInsOrderId, null));
int updated = baseMapper.update(null, Wrappers.lambdaUpdate()
.eq(InspectionOrder::getInspectionOrderId, inspectionOrderId)
.isNull(InspectionOrder::getInsOrderId)
.set(InspectionOrder::getInsOrderId, insOrderId));
if (updated != 1) {
throw new ErrorException("目标检验委托单已被其他下单绑定,请刷新后重试");
}
InspectionOrderBindLog bindLog = new InspectionOrderBindLog();
bindLog.setInsOrderId(insOrderId);
bindLog.setOldInspectionOrderId(oldInspectionOrder == null ? null : oldInspectionOrder.getInspectionOrderId());
bindLog.setNewInspectionOrderId(inspectionOrderId);
bindLog.setChangeReason(reason.trim());
bindLog.setCreateUser(SecurityUtils.getUserId().intValue());
bindLog.setCreateTime(LocalDateTime.now());
inspectionOrderBindLogMapper.insert(bindLog);
return true;
}
/**
* 委托单成品报告上传
*
* @param file
* @param inspectionOrderId
* @return
*/
@Override
public boolean uploadInspectionOrderFile(MultipartFile file, Integer inspectionOrderId) {
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));
baseMapper.update(null, Wrappers.lambdaUpdate()
.eq(InspectionOrder::getInspectionOrderId, inspectionOrderId)
.set(InspectionOrder::getFileUrl, "/word/" + pathName));
} catch (Exception e) {
throw new ErrorException("文件上传失败");
}
return true;
}
@Override
public void exportInspectionOrder(Integer inspectionOrderId, HttpServletResponse response) {
InspectionOrder inspectionOrder = baseMapper.selectById(inspectionOrderId);
InspectionOrderExportDto inspectionOrderExportDto = extracted(inspectionOrder);
List list = inspectionOrderDetailService.list(Wrappers.lambdaQuery()
.eq(InspectionOrderDetail::getInspectionOrderId, inspectionOrderId));
int index = 1;
for (InspectionOrderDetail inspectionOrderDetail : list) {
inspectionOrderDetail.setIndex(index);
index++;
}
// 获取路径
InputStream inputStream = this.getClass().getResourceAsStream("/static/inspection-order.docx");
Configure configure = Configure.builder()
.bind("inspectionOrderDetailList", new HackLoopTableRenderPolicy())
.build();
XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
new HashMap() {{
put("inspectionOrder", inspectionOrderExportDto);
put("inspectionOrderDetailList", list);
}});
try {
response.setContentType("application/msword");
String fileName = URLEncoder.encode(
inspectionOrderExportDto.getSampleName(), "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("导出失败");
}
}
private InspectionOrderExportDto extracted(InspectionOrder inspectionOrder) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
InspectionOrderExportDto inspectionOrderExportDto = new InspectionOrderExportDto();
BeanUtils.copyProperties(inspectionOrder, inspectionOrderExportDto);
if (inspectionOrder.getCommissionDate() != null) {
inspectionOrderExportDto.setCommissionDateString(inspectionOrder.getCommissionDate().format(formatter));
}
if (inspectionOrder.getReceiptData() != null) {
inspectionOrderExportDto.setReceiptDataString(inspectionOrder.getReceiptData().format(formatter));
}
if (inspectionOrder.getSampleData() != null) {
inspectionOrderExportDto.setSampleDataString(inspectionOrder.getSampleData().format(formatter));
}
if (inspectionOrder.getAppointed() != null) {
inspectionOrderExportDto.setAppointedString(inspectionOrder.getAppointed().format(formatter));
}
inspectionOrderExportDto.setIsLeave1(inspectionOrder.getIsLeave() != null && inspectionOrder.getIsLeave() == 1 ? "☑" : "□");
inspectionOrderExportDto.setIsLeave2(inspectionOrder.getIsLeave() != null && inspectionOrder.getIsLeave() == 0 ? "☑" : "□");
inspectionOrderExportDto.setSend0(inspectionOrder.getSend() != null && inspectionOrder.getSend() == 1 ? "☑" : "□");
inspectionOrderExportDto.setSend1(inspectionOrder.getSend() != null && inspectionOrder.getSend() == 0 ? "☑" : "□");
inspectionOrderExportDto.setProcessing0(inspectionOrder.getProcessing() != null && inspectionOrder.getProcessing() == 0 ? "☑" : "□");
inspectionOrderExportDto.setProcessing1(inspectionOrder.getProcessing() != null && inspectionOrder.getProcessing() == 1 ? "☑" : "□");
inspectionOrderExportDto.setCriterionRule0(inspectionOrder.getCriterionRule() != null && inspectionOrder.getCriterionRule() == 0 ? "☑" : "□");
inspectionOrderExportDto.setCriterionRule1(inspectionOrder.getCriterionRule() != null && inspectionOrder.getCriterionRule() == 1 ? "☑" : "□");
return inspectionOrderExportDto;
}
}