liding
9 小时以前 51786b723d0a91d11476776d9ce50af7994dc4bd
feat(inspect): 完善检验订单状态管理和样品接收流程

- 更新订单状态枚举,新增已检验(4)和作废(5)状态
- 添加分包内容、分包单位、样品处置、结果评价、报告交付等委托要求字段
- 优化报告生成中的日期格式化逻辑和设备清单显示
- 添加委托要求必填校验和字段联动验证
- 实现新聚下单免审核直接进入样品接收流程
- 修复报告审核和批准人为同一人时的冲突检查
- 优化样品查询中的实验室参数过滤逻辑
- 更新CNAS流程中样品处置记录的数据源和处理逻辑
已添加12个文件
已修改19个文件
1036 ■■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/listener/NewJuOrderInspectionListener.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/pojo/ProcessDeal.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessTotaldealServiceImpl.java 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsSampleReceiptController.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleOrderDto.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleReceiptActionDto.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleReceiptPageDto.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleReceiptQueryDto.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/event/NewJuOrderPlacedEvent.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsOrderMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsSampleReceiptMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderTemplate.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsReport.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsSampleReceipt.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderTemplateService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/InsSampleReceiptService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderTemplateServiceImpl.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderPrintingVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderTemplateDetailVo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/InsOrderMapper.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/InsSampleMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/InsSampleReceiptMapper.xml 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/static/detection-report-template-v2.docx 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/static/inspection-report-template-v2.docx 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java
@@ -52,10 +52,7 @@
                    continue;
                }
                Integer row = cell.getInteger("r");
                String item = value.getString("v");
                if (!StringUtils.hasText(item)) {
                    item = value.getString("m");
                }
                String item = getCellText(value);
                if (row == null || !StringUtils.hasText(item)) {
                    throw new BaseException("“检验项”标记所在单元格必须填写检验项名称");
                }
@@ -74,6 +71,36 @@
        return result;
    }
    /**
     * è¯»å– Luckysheet å•元格文本,兼容普通文本和 inlineStr å¯Œæ–‡æœ¬ã€‚
     */
    private static String getCellText(JSONObject value) {
        String text = value.getString("v");
        if (StringUtils.hasText(text)) {
            return text;
        }
        text = value.getString("m");
        if (StringUtils.hasText(text)) {
            return text;
        }
        JSONObject cellType = value.getJSONObject("ct");
        JSONArray segments = cellType == null ? null : cellType.getJSONArray("s");
        if (segments == null || segments.isEmpty()) {
            return text;
        }
        StringBuilder richText = new StringBuilder();
        for (Object segmentObject : segments) {
            if (segmentObject instanceof JSONObject) {
                String segmentText = ((JSONObject) segmentObject).getString("v");
                if (segmentText != null) {
                    richText.append(segmentText);
                }
            }
        }
        return richText.toString();
    }
    private static boolean isInspectionItem(JSONObject value) {
        JSONObject ps = value.getJSONObject("ps");
        return ps != null && INSPECTION_ITEM_MARK.equals(ps.getString("value"));
cnas-process/src/main/java/com/ruoyi/process/listener/NewJuOrderInspectionListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.ruoyi.process.listener;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.inspect.event.NewJuOrderPlacedEvent;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.service.InsOrderService;
import com.ruoyi.process.mapper.InspectionOrderMapper;
import com.ruoyi.process.pojo.InspectionOrder;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
/**
 * æ–°èšæˆå“ä¸‹å•成功后,自动生成一条检验委托单。
 */
@Component
@AllArgsConstructor
public class NewJuOrderInspectionListener {
    private final InsOrderService insOrderService;
    private final InspectionOrderMapper inspectionOrderMapper;
    @EventListener
    public void onNewJuOrderPlaced(NewJuOrderPlacedEvent event) {
        InsOrder order = insOrderService.getById(event.getInsOrderId());
        if (order == null) {
            return;
        }
        // å¹‚等:同一成品订单已有检验委托单则跳过
        Long count = inspectionOrderMapper.selectCount(Wrappers.<InspectionOrder>lambdaQuery()
                .eq(InspectionOrder::getInsOrderId, order.getId()));
        if (count > 0) {
            return;
        }
        InspectionOrder inspectionOrder = new InspectionOrder();
        inspectionOrder.setInsOrderId(order.getId());
        inspectionOrder.setEntrustCode(order.getEntrustCode());
        // è¯•样名称优先取报告展示字段
        inspectionOrder.setSampleName(StringUtils.isNotBlank(order.getSampleView())
                ? order.getSampleView() : order.getSample());
        inspectionOrder.setProduction(order.getProduction());
        inspectionOrder.setQuantity(order.getTestQuantity());
        inspectionOrder.setCommissionDate(LocalDate.now());
        inspectionOrder.setCommissionUnit(order.getCompany());
        inspectionOrder.setCommissionUser(order.getPrepareUser());
        inspectionOrder.setCommissionPhone(order.getPhone());
        inspectionOrder.setSampleStatus("完好");
        // æ˜¯å¦ç•™æ ·è¯­ä¹‰è½¬æ¢ï¼šins 0否/1是 -> cnas 1是/2否
        inspectionOrder.setIsLeave(Integer.valueOf(1).equals(order.getIsLeave()) ? 1 : 2);
        // æ ·å“å¤„置:1委托方取回/2检测方处置 -> processing 0委托单位取回/1实验室处理;未选时沿用旧字段
        if (Integer.valueOf(1).equals(order.getSampleDisposal())) {
            inspectionOrder.setProcessing(0);
        } else if (Integer.valueOf(2).equals(order.getSampleDisposal())) {
            inspectionOrder.setProcessing(1);
        } else {
            inspectionOrder.setProcessing(order.getProcessing());
        }
        // æŠ¥å‘Šäº¤ä»˜æ–¹å¼ï¼š1自取 -> send 1,其余 0;未选时沿用旧字段
        if (order.getReportDelivery() != null) {
            inspectionOrder.setSend(Integer.valueOf(1).equals(order.getReportDelivery()) ? 1 : 0);
        } else {
            inspectionOrder.setSend(order.getSend());
        }
        // æŠ¥å‘Šæ–‡ä»¶ä¸Žçº¦å®šæ—¶é—´ç”Ÿæˆæ—¶ä¸ºç©ºï¼ŒåŽç»­åœ¨æ£€éªŒå§”托单页面编辑/上传
        inspectionOrderMapper.insert(inspectionOrder);
    }
}
cnas-process/src/main/java/com/ruoyi/process/pojo/ProcessDeal.java
@@ -26,6 +26,7 @@
public class ProcessDeal implements Serializable {
    @ApiModelProperty("主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
@@ -48,21 +49,28 @@
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate dealTime;
    @ApiModelProperty("创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("更新人")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("关联的历史总表id")
    private Integer totaldealId;
    @ApiModelProperty("关联的样品接收id")
    @ApiModelProperty("关联的历史处置样品id")
    private Integer processSampleId;
    @ApiModelProperty("关联的检验样品id(ins_sample)")
    private Integer insSampleId;
}
cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessTotaldealServiceImpl.java
@@ -15,16 +15,19 @@
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.InspectionOrderMapper;
import com.ruoyi.process.mapper.ProcessDealMapper;
import com.ruoyi.process.mapper.ProcessSampleMapper;
import com.ruoyi.process.mapper.ProcessTotaldealMapper;
import com.ruoyi.process.pojo.InspectionOrder;
import com.ruoyi.process.pojo.ProcessDeal;
import com.ruoyi.process.pojo.ProcessSample;
import com.ruoyi.process.pojo.ProcessTotaldeal;
import com.ruoyi.process.service.ProcessDealService;
import com.ruoyi.process.service.ProcessTotaldealService;
@@ -44,12 +47,17 @@
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;
/**
 * <p>
@@ -67,13 +75,7 @@
    private ProcessTotaldealMapper processTotaldealMapper;
    @Resource
    private ProcessSampleMapper processSampleMapper;
    @Resource
    private ProcessDealService processDealService;
    @Resource
    private InspectionOrderMapper inspectionOrderMapper;
   @Resource
   private ProcessDealMapper processDealMapper;
@@ -84,6 +86,15 @@
    @Resource
    private UserMapper userMapper;
    @Resource
    private InsOrderMapper insOrderMapper;
    @Resource
    private InsSampleMapper insSampleMapper;
    @Resource
    private InsSampleReceiptMapper insSampleReceiptMapper;
    @Override
    public IPage<ProcessTotaldeal> pageProcessTotaldeal(Page page, ProcessTotaldeal processTotaldeal) {
@@ -139,49 +150,93 @@
    @Override
    public int addProcessTotaldeal(String month) {
        //新增总表
        ProcessTotaldeal processTotaldeal = new ProcessTotaldeal();
        //新增总表(同一月份复用已有总表)
        ProcessTotaldeal processTotaldeal;
        List<ProcessTotaldeal> processTotaldeals = processTotaldealMapper.selectList(Wrappers.<ProcessTotaldeal>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);
        LocalDate firstDay = yearMonth.atDay(1);
        LocalDate lastDay = yearMonth.atEndOfMonth();
        //2.查询在这个时间范围内的所有样品登记的数据
        List<ProcessSample> processSamples = processSampleMapper.selectList(Wrappers.<ProcessSample>lambdaQuery()
                .between(ProcessSample::getLeaveDate, firstDay, lastDay));
        if (processSamples.size()>0){
            //获取处理方式
            InspectionOrder inspectionOrder = inspectionOrderMapper.selectById(processSamples.get(0).getInspectionOrderId());
        LocalDateTime startTime = yearMonth.atDay(1).atStartOfDay();
        LocalDateTime endTime = yearMonth.atEndOfMonth().atTime(LocalTime.MAX);
        //2.该月下单的委托单(排除原材料,typeSource ä¸ºç©ºè§†ä¸ºæˆå“ï¼‰
        List<InsOrder> orders = insOrderMapper.selectList(Wrappers.<InsOrder>lambdaQuery()
                .ge(InsOrder::getCreateTime, startTime)
                .le(InsOrder::getCreateTime, endTime));
        if (orders.isEmpty()) {
            return 0;
        }
        //3.只保留已生成样品接收记录的委托(已审核受理)
        List<Integer> orderIds = orders.stream().map(InsOrder::getId).collect(Collectors.toList());
        List<InsSampleReceipt> receipts = insSampleReceiptMapper.selectList(Wrappers.<InsSampleReceipt>lambdaQuery()
                .in(InsSampleReceipt::getInsOrderId, orderIds));
        Set<Integer> receiptOrderIds = receipts.stream().map(InsSampleReceipt::getInsOrderId).collect(Collectors.toSet());
        Map<Integer, InsOrder> 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<InsSample> samples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery()
                .in(InsSample::getInsOrderId, orderMap.keySet()));
        if (samples.isEmpty()) {
            return 0;
        }
        //5.已进入任何处置批次的样品跳过(跨月也不会重复带入)
        List<Integer> sampleIds = samples.stream().map(InsSample::getId).collect(Collectors.toList());
        Set<Integer> dealtSampleIds = processDealService.list(Wrappers.<ProcessDeal>lambdaQuery()
                .select(ProcessDeal::getInsSampleId)
                .in(ProcessDeal::getInsSampleId, sampleIds))
                .stream().map(ProcessDeal::getInsSampleId).filter(Objects::nonNull).collect(Collectors.toSet());
            List<ProcessDeal> processDeals = new ArrayList<>();
            for (ProcessSample processSample : processSamples) {
                long count = processDealService.count(Wrappers.<ProcessDeal>lambdaQuery().eq(ProcessDeal::getProcessSampleId, processSample.getId()));
                if (count>0){
        for (InsSample insSample : samples) {
            if (dealtSampleIds.contains(insSample.getId())) {
                    continue;
                }
            InsOrder order = orderMap.get(insSample.getInsOrderId());
                ProcessDeal processDeal = new ProcessDeal();
                processDeal.setSampleName(processSample.getSampleName());//样品名称
                processDeal.setSampleCode(processSample.getSampleCode());//样品编号
                processDeal.setSampleSupplier(processSample.getSampleSupplier());//供样单位
                processDeal.setNum(processSample.getNum());//样品数量
                processDeal.setDealMethod(inspectionOrder.getProcessing()==1?"实验室处理":"委托单位取回");//处理方式
            //样品名称优先取报告展示字段
            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.setProcessSampleId(processSample.getId());//样品接收id
            processDeal.setInsSampleId(insSample.getId());//检验样品id
                processDeals.add(processDeal);
            }
        if (!processDeals.isEmpty()) {
            processDealService.saveBatch(processDeals);
        }
        return 0;
        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
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java
@@ -75,7 +75,7 @@
    @ApiOperation(value = "检验分配")
    @PostMapping("/upInsOrder")
    public Result<?> upInsOrder(Integer orderId, Integer sampleId, String appointed, Integer userId,String sonLaboratory) {
        return Result.success(insOrderService.upInsOrder(orderId, sampleId, appointed, userId,sonLaboratory));
        return Result.fail("请在样品接收页面选择主检验人后提交检验");
    }
    @ApiOperation(value = "添加检验下单数据")
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsSampleReceiptController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi.inspect.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.inspect.dto.SampleReceiptActionDto;
import com.ruoyi.inspect.dto.SampleReceiptQueryDto;
import com.ruoyi.inspect.service.InsSampleReceiptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/insSampleReceipt")
@Api(tags = "样品接收")
@AllArgsConstructor
public class InsSampleReceiptController {
    private final InsSampleReceiptService insSampleReceiptService;
    @ApiOperation("样品接收分页")
    @GetMapping("/page")
    public Result page(Page<?> page, SampleReceiptQueryDto query) {
        return Result.success(insSampleReceiptService.page(page, query));
    }
    @ApiOperation("样品接收详情")
    @GetMapping("/{id}")
    public Result detail(@PathVariable Integer id) {
        return Result.success(insSampleReceiptService.detail(id));
    }
    @ApiOperation("提交检验")
    @PostMapping("/submit")
    public Result submit(@RequestBody SampleReceiptActionDto dto) {
        insSampleReceiptService.submit(dto);
        return Result.success();
    }
    @ApiOperation("拒收样品")
    @PostMapping("/reject")
    public Result reject(@RequestBody SampleReceiptActionDto dto) {
        insSampleReceiptService.reject(dto);
        return Result.success();
    }
    @ApiOperation("样品接收导出")
    @GetMapping("/export")
    public void export(SampleReceiptQueryDto query, HttpServletResponse response) {
        insSampleReceiptService.export(query, response);
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleOrderDto.java
@@ -28,6 +28,7 @@
    @ApiModelProperty("样品型号")
    private String sampleModel;
    @ApiModelProperty("指派检验人id")
    private String assign;
    @ExcelProperty(index = 4, value = "样品数量")
@@ -44,11 +45,14 @@
    @ApiModelProperty("报告id")
    private String reportId;
    @ApiModelProperty("系统生成报告地址")
    @TableField("`url`")
    private String url;
    @ApiModelProperty("手动上传报告地址")
    private String urlS;
    @ApiModelProperty("下单人姓名")
    private String name;
    @ExcelProperty(index = 5, value = "检验人")
@@ -86,6 +90,7 @@
    @ApiModelProperty("子实验室")
    private String sonLaboratory;
    @ApiModelProperty("样品名称(原材料取样品字段,成品取报告展示字段)")
    private String sampleStr;
@@ -95,5 +100,7 @@
    @ApiModelProperty("订单id(导出用)")
    private String ids;
    @ApiModelProperty("拒收原因")
    private String sampleRejectRemark;
}
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleReceiptActionDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.inspect.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SampleReceiptActionDto {
    @ApiModelProperty("样品接收记录ID")
    private Integer receiptId;
    @ApiModelProperty("主检验人ID")
    private Integer mainInspectorId;
    @ApiModelProperty("接收备注,拒收时为拒收备注")
    private String remark;
}
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleReceiptPageDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.ruoyi.inspect.dto;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@ExcelIgnoreUnannotated
public class SampleReceiptPageDto {
    @ApiModelProperty("样品接收记录ID")
    private Integer receiptId;
    @ApiModelProperty("委托单ID")
    private Integer orderId;
    @ApiModelProperty("样品ID")
    private Integer sampleId;
    @ApiModelProperty("样品接收状态 0待接收 1已提交检验 2已拒收 3已取消")
    private Integer status;
    @ExcelProperty(value = "样品名称", index = 0)
    @ApiModelProperty("样品名称")
    private String sampleName;
    @ExcelProperty(value = "样品编号", index = 1)
    @ApiModelProperty("样品编号")
    private String sampleCode;
    @ExcelProperty(value = "检测项目", index = 2)
    @ApiModelProperty("检测项目")
    private String inspectionItem;
    @ExcelProperty(value = "委托编号", index = 3)
    @ApiModelProperty("委托编号")
    private String entrustCode;
    @ExcelProperty(value = "方法标准", index = 4)
    @ApiModelProperty("方法标准")
    private String methodStandard;
    @ApiModelProperty("主检验人ID")
    private Integer mainInspectorId;
    @ExcelProperty(value = "主检人签字", index = 5)
    @ApiModelProperty("主检验人姓名")
    private String mainInspectorName;
    @ExcelProperty(value = "备注", index = 6)
    @ApiModelProperty("接收备注")
    private String remark;
    @ExcelProperty(value = "拒收备注", index = 7)
    @ApiModelProperty("拒收备注")
    private String rejectRemark;
    @ApiModelProperty("接收处理时间")
    private LocalDateTime receiveTime;
    @ApiModelProperty("接收处理人")
    private String receiveUserName;
}
inspect-server/src/main/java/com/ruoyi/inspect/dto/SampleReceiptQueryDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.inspect.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SampleReceiptQueryDto {
    @ApiModelProperty("样品接收状态 0待接收 1已提交检验 2已拒收 3已取消")
    private Integer status;
    @ApiModelProperty("委托编号")
    private String entrustCode;
    @ApiModelProperty("样品编号")
    private String sampleCode;
    @ApiModelProperty("样品名称")
    private String sampleName;
}
inspect-server/src/main/java/com/ruoyi/inspect/event/NewJuOrderPlacedEvent.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.inspect.event;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
 * æ–°èšç›´ç»‘模板下单成功事件。
 */
@Data
@AllArgsConstructor
public class NewJuOrderPlacedEvent {
    private Integer insOrderId;
}
inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsOrderMapper.java
@@ -30,7 +30,7 @@
public interface InsOrderMapper extends BaseMapper<InsOrder> {
    //获取检验下单数据
    IPage<SampleOrderDto> selectInsOrderPage(@Param("page") IPage<InsOrder> page, @Param("ew") QueryWrapper<SampleOrderDto> ew, @Param("laboratory") String laboratory, @Param("isOrderAll") String isOrderAll);
    IPage<SampleOrderDto> selectInsOrderPage(@Param("page") IPage<InsOrder> page, @Param("ew") QueryWrapper<SampleOrderDto> ew, @Param("laboratory") String laboratory, @Param("isOrderAll") String isOrderAll, @Param("receiptSubmitted") String receiptSubmitted);
    String getLaboratoryCode(@Param("name") String name);
inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsSampleReceiptMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.inspect.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.inspect.dto.SampleReceiptPageDto;
import com.ruoyi.inspect.dto.SampleReceiptQueryDto;
import com.ruoyi.inspect.pojo.InsSampleReceipt;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface InsSampleReceiptMapper extends BaseMapper<InsSampleReceipt> {
    IPage<SampleReceiptPageDto> selectPage(Page<?> page, @Param("query") SampleReceiptQueryDto query);
    SampleReceiptPageDto selectDetail(@Param("id") Integer id);
    InsSampleReceipt selectForUpdate(@Param("id") Integer id);
    int insertIgnore(@Param("orderId") Integer orderId, @Param("sampleId") Integer sampleId);
    List<SampleReceiptPageDto> selectExportList(@Param("query") SampleReceiptQueryDto query);
}
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java
@@ -67,7 +67,7 @@
    @ApiModelProperty("是否留样")
    private Integer isLeave;
    @ApiModelProperty("状态:-1:原材料撤回  1:检验处理 0:待审核 2:退回 3:撤销")
    @ApiModelProperty("状态:-1:原材料撤回 0:待审核 1:样品接收/检验处理 2:退回 3:撤销 4:已检验 5:作废")
    private Integer state;
    @ExcelProperty(index = 7, value = "备注")
@@ -160,6 +160,7 @@
    private Integer prepareUserId;
    @ExcelProperty(index = 12, value = "委托人")
    @ApiModelProperty("委托人")
    private String prepareUser;
    @ApiModelProperty(name = "委托人英文")
@@ -233,6 +234,27 @@
    @ApiModelProperty("首次保存检验模板值时间")
    private LocalDateTime firstInspectDate;
    @ApiModelProperty("分包内容 0无 1有")
    private Integer subcontractType;
    @ApiModelProperty("分包单位信息")
    private String subcontractCompany;
    @ApiModelProperty("样品处置 1委托方取回 2检测方处置")
    private Integer sampleDisposal;
    @ApiModelProperty("对结果评价 0否 1是")
    private Integer resultEvaluation;
    @ApiModelProperty("报告交付方式 1自取 2快递 3电子传送")
    private Integer reportDelivery;
    @ApiModelProperty("报告寄送地址")
    private String reportAddress;
    @ApiModelProperty("收件人及电话")
    private String reportReceiver;
    @ApiModelProperty("样机员(除了其他成品外这个字段必选,用于企业微信推送)")
    @TableField(exist = false)
    private Integer issueUser;
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderTemplate.java
@@ -18,6 +18,7 @@
    /**
     *
     */
    @ApiModelProperty("主键")
    @TableId(type = IdType.AUTO)
    private Integer id;
@@ -33,6 +34,10 @@
    @ApiModelProperty("模板内容")
    private String thing;
    @ApiModelProperty("绑定的标准库二级标准ID")
    private Integer standardTreeId;
    @ApiModelProperty("创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsReport.java
@@ -18,6 +18,7 @@
    /**
     *
     */
    @ApiModelProperty("主键")
    @TableId(type = IdType.AUTO)
    private Integer id;
@@ -27,7 +28,7 @@
    /**
     * å¤–键:检验单id
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("检验单id")
    private Integer insOrderId;
    /** 0:检测报告(仅检测数据),1:检验报告(含判定结果) */
@@ -37,7 +38,7 @@
    /**
     * ç³»ç»Ÿç”ŸæˆæŠ¥å‘Šåœ°å€
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("系统生成报告地址")
    private String url;
    /**
@@ -49,13 +50,13 @@
    /**
     * æ‰‹åŠ¨ä¸Šä¼ æŠ¥å‘Šåœ°å€
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("手动上传报告地址")
    private String urlS;
    /**
     * ä¸´æ—¶æŠ¥å‘Šåœ°å€
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("临时报告地址")
    private String tempUrlPdf;
    /**
@@ -79,21 +80,22 @@
    /**
     * å¤–键:用户id(提交人)
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("提交人用户id")
    private Integer writeUserId;
    /**
     * å¤–键:用户id(批准人)
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("批准人用户id")
    private Integer ratifyUserId;
    /**
     * å¤–键:用户id(审核人)
     */
    @ApiModelProperty("创建时间")
    @ApiModelProperty("审核人用户id")
    private Integer examineUserId;
    @ApiModelProperty("创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
@@ -102,6 +104,7 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("更新人")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsSampleReceipt.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.inspect.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("ins_sample_receipt")
public class InsSampleReceipt {
    @ApiModelProperty("主键")
    @TableId(type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("委托单ID")
    private Integer insOrderId;
    @ApiModelProperty("样品ID")
    private Integer insSampleId;
    @ApiModelProperty("样品接收状态 0待接收 1已提交检验 2已拒收 3已取消")
    private Integer status;
    @ApiModelProperty("主检验人ID")
    private Integer mainInspectorId;
    @ApiModelProperty("接收处理人ID")
    private Integer receiveUserId;
    @ApiModelProperty("接收处理时间")
    private LocalDateTime receiveTime;
    @ApiModelProperty("提交检验时间")
    private LocalDateTime submitTime;
    @ApiModelProperty("拒收备注")
    private String rejectRemark;
    @ApiModelProperty("创建人")
    private Integer createUser;
    @ApiModelProperty("创建时间")
    private LocalDateTime createTime;
    @ApiModelProperty("更新人")
    private Integer updateUser;
    @ApiModelProperty("更新时间")
    private LocalDateTime updateTime;
}
inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderTemplateService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.inspect.pojo.InsOrderTemplate;
import com.ruoyi.inspect.vo.InsOrderTemplateDetailVo;
import java.util.List;
@@ -16,7 +17,7 @@
    List<InsOrderTemplate> selectInsOrderTemplate(String company);
    String selectInsOrderTemplateById(Integer id);
    InsOrderTemplateDetailVo selectInsOrderTemplateById(Integer id);
    int delInsOrderTemplate(Integer id);
inspect-server/src/main/java/com/ruoyi/inspect/service/InsSampleReceiptService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.inspect.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.inspect.dto.SampleReceiptActionDto;
import com.ruoyi.inspect.dto.SampleReceiptPageDto;
import com.ruoyi.inspect.dto.SampleReceiptQueryDto;
import com.ruoyi.inspect.pojo.InsSampleReceipt;
import javax.servlet.http.HttpServletResponse;
public interface InsSampleReceiptService extends IService<InsSampleReceipt> {
    IPage<SampleReceiptPageDto> page(Page<?> page, SampleReceiptQueryDto query);
    SampleReceiptPageDto detail(Integer id);
    void submit(SampleReceiptActionDto dto);
    void reject(SampleReceiptActionDto dto);
    void export(SampleReceiptQueryDto query, HttpServletResponse response);
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -274,11 +274,11 @@
        // æŸ¥è¯¢è®¢å•Id
        InsOrder order = insOrderMapper.selectFirstSubmit(dto.getId());
        if (order == null) {
            return BeanUtil.isEmpty(insProducts) ? null : insProducts;
            return BeanUtil.isEmpty(insProducts) ? Collections.emptyList() : insProducts;
        }
        insProducts = mergeDirectTemplateSnapshots(order, dto.getId(), dto.getLaboratory(), insProducts);
        if (BeanUtil.isEmpty(insProducts)) {
            return null;
            return Collections.emptyList();
        }
        getTemplateThing(order, insProducts, dto.getLaboratory());
        return insProducts;
@@ -300,14 +300,6 @@
        if (snapshots.isEmpty()) {
            return source;
        }
        InsSample sample = insSampleMapper.selectById(sampleId);
        boolean directTemplateOrder = source.stream()
                .anyMatch(product -> product.getTemplateRowIndex() != null)
                || isDirectTemplateSample(order, sample);
        if (!directTemplateOrder) {
            return source;
        }
        Map<Integer, List<InsProduct>> productsByTemplate = source.stream()
                .filter(product -> product.getTemplateId() != null)
                .collect(Collectors.groupingBy(InsProduct::getTemplateId, LinkedHashMap::new, Collectors.toList()));
@@ -3588,10 +3580,7 @@
            firstInspectDate = submitTime;
        }
        String insTime = firstInspectDate.format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日")) + "-"
                + submitTime.format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日"));
        String testStartDate = firstInspectDate.format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日"));
        String testEndDate = submitTime.format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日"));
        String insTime = formatReportTestDate(firstInspectDate, submitTime);
        String insTimeEn = monthNames[firstInspectDate.getMonthValue() - 1] + " " + firstInspectDate.format(DateTimeFormatter.ofPattern("dd, yyyy")) + "-"
                + monthNames[submitTime.getMonthValue() - 1] + " " + submitTime.format(DateTimeFormatter.ofPattern("dd, yyyy"));
@@ -3738,8 +3727,6 @@
                    put("batch", finalBatchNo);
                    put("phone", defaultReportText(insOrder.getPhone(), "/"));
                    put("testDate", insTime);
                    put("testStartDate", testStartDate);
                    put("testEndDate", testEndDate);
                    put("entrustNo", defaultReportText(insOrder.getEntrustCode(), "/"));
                    put("sampling", "/");
                    put("standard", finalStandardMethodText);
@@ -3954,16 +3941,21 @@
        if (CollectionUtils.isEmpty(deviceList)) {
            return "/";
        }
        Set<String> lines = new LinkedHashSet<>();
        int sequence = 1;
        Set<String> equipmentItems = new LinkedHashSet<>();
        for (Map<String, String> device : deviceList) {
            String name = getMapText(device, "deviceName", "device_name");
            String managementNumber = getMapText(device, "managementNumber", "management_number");
            String line = sequence++ + ". " + defaultReportText(name, "/");
            String item = defaultReportText(name, "/");
            if (StringUtils.isNotBlank(managementNumber)) {
                line += ":" + managementNumber;
                item += ":" + managementNumber;
            }
            lines.add(line);
            equipmentItems.add(item);
        }
        List<String> items = new ArrayList<>(equipmentItems);
        List<String> lines = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            String punctuation = i == items.size() - 1 ? "。" : ";";
            lines.add((i + 1) + ". " + items.get(i) + punctuation);
        }
        return String.join("\n", lines);
    }
@@ -3984,7 +3976,7 @@
                .collect(Collectors.toList());
        String temperature = formatConditionRange(temperatures, order.getTemperature(), "℃");
        String humidity = formatConditionRange(humidities, order.getHumidity(), "%");
        String humidity = formatConditionRange(humidities, order.getHumidity(), "%RH");
        return Stream.of(temperature, humidity)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.joining(" "));
@@ -4057,6 +4049,14 @@
        return StringUtils.isNotBlank(fallback) ? fallback : "/";
    }
    private static String formatReportTestDate(LocalDateTime startTime, LocalDateTime endTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日");
        if (startTime.toLocalDate().equals(endTime.toLocalDate())) {
            return startTime.format(formatter);
        }
        return startTime.format(formatter) + "至" + endTime.format(formatter);
    }
    /**
     * è®¡ç®—表格列宽度
     *
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
@@ -57,6 +57,7 @@
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
@@ -107,6 +108,8 @@
    private StandardTemplateService standardTemplateService;
    private InsOrderStandardTemplateMapper insOrderStandardTemplateMapper;
    private InsOrderTemplateDeviceMapper insOrderTemplateDeviceMapper;
    private InsSampleReceiptMapper insSampleReceiptMapper;
    private ApplicationEventPublisher applicationEventPublisher;
@@ -120,7 +123,10 @@
            isOrderAll = "1";
            sampleOrderDto.setState(null);
        }
        return insOrderMapper.selectInsOrderPage(page, QueryWrappers.queryWrappers(sampleOrderDto), laboratory, isOrderAll);
        // æ£€éªŒä¸­ï¼šæ–°èšä¸‹å•免审核即受理,需样品接收提交后(ins_sample_receipt.status=1)才展示
        String receiptSubmitted = sampleOrderDto.getState() != null && sampleOrderDto.getState() == 1 ? "1" : null;
        return insOrderMapper.selectInsOrderPage(page, QueryWrappers.queryWrappers(sampleOrderDto), laboratory,
                isOrderAll, receiptSubmitted);
    }
@@ -175,13 +181,17 @@
        }
        if (userId != null) {
            Set<String> assignedLaboratories = StringUtils.isBlank(sonLaboratory)
                    ? taskLaboratories
                    : Collections.singleton(sonLaboratory);
            for (String laboratory : assignedLaboratories) {
            InsSampleUser insSampleUser = new InsSampleUser();
            insSampleUser.setState(0);
            insSampleUser.setUserId(userId);
            insSampleUser.setInsSampleId(orderId);
            insSampleUser.setSonLaboratory(directTemplateOrder
                    ? DIRECT_TEMPLATE_LABORATORY : sonLaboratory);
                insSampleUser.setSonLaboratory(laboratory);
            insSampleUserMapper.insert(insSampleUser);
            }
        }
        // åˆ¤æ–­è®¢å•有没有绑定抽样计划
@@ -412,9 +422,7 @@
            // å®¡æ ¸æ£€éªŒå•
            upInsOrderOfState(insOrder);
            // åˆ†é…æ£€éªŒäºº
            String sonLaboratory = insOrder.getTypeSource().equals(1)?"原材料":"成品实验室";
            upInsOrder(insOrder.getId(), null, appointed != null ? appointed.toString() : null, SecurityUtils.getUserId().intValue(), sonLaboratory);
            // å®¡æ ¸é€šè¿‡åŽä»…进入样品接收;由样品接收页面选择主检验人后再创建检验任务。
            //是否为原材料下单
            if(insOrder.getTypeSource().equals(1)){
@@ -477,6 +485,24 @@
        if (StringUtils.isBlank(sampleCode) || sampleCode.length() < 2) {
            throw new ErrorException("样品编号不能为空且不能少于2位");
        }
        // å§”托要求字段校验:四组单选必选,分包/快递联动必填
        InsOrder reqOrder = dto.getInsOrder();
        if (reqOrder.getSubcontractType() == null || reqOrder.getSampleDisposal() == null
                || reqOrder.getResultEvaluation() == null || reqOrder.getReportDelivery() == null) {
            throw new ErrorException("请选择分包内容、样品处置、对结果评价和报告交付方式");
        }
        if (Integer.valueOf(1).equals(reqOrder.getSubcontractType())
                && StringUtils.isBlank(reqOrder.getSubcontractCompany())) {
            throw new ErrorException("分包内容为有时,分包单位信息不能为空");
        }
        if (Integer.valueOf(2).equals(reqOrder.getReportDelivery())) {
            if (StringUtils.isBlank(reqOrder.getReportAddress())) {
                throw new ErrorException("报告交付方式为快递时,报告寄送地址不能为空");
            }
            if (StringUtils.isBlank(reqOrder.getReportReceiver())) {
                throw new ErrorException("报告交付方式为快递时,收件人及电话不能为空");
            }
        }
        StandardTree standard = standardTreeService.getById(dto.getStandardTreeId());
        if (standard == null || StringUtils.isBlank(standard.getSample())
                || standard.getSampleType() != null || standard.getModel() != null) {
@@ -537,7 +563,9 @@
        InsOrder order = dto.getInsOrder();
        order.setId(null);
        order.setState(0);
        // æ–°èšä¸‹å•免审核:直接受理,下单即流转到样品接收
        order.setState(1);
        order.setExamineTime(LocalDateTime.now());
        order.setIsExemption(0);
        order.setFactory(null);
        order.setLaboratory(standard.getLaboratory());
@@ -549,6 +577,14 @@
        // æ–°èšè®¢å•的环境条件由检验任务填写,避免下单模板或浏览器缓存带入旧值。
        order.setTemperature(null);
        order.setHumidity(null);
        // æœªå‘½ä¸­è”动条件时清空对应文本字段,避免模板快照或浏览器缓存带入旧值。
        if (!Integer.valueOf(1).equals(order.getSubcontractType())) {
            order.setSubcontractCompany(null);
        }
        if (!Integer.valueOf(2).equals(order.getReportDelivery())) {
            order.setReportAddress(null);
            order.setReportReceiver(null);
        }
        insOrderMapper.insert(order);
        InsSample sample = new InsSample();
@@ -590,6 +626,10 @@
        insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate()
                .eq(InsOrder::getId, order.getId())
                .set(InsOrder::getEntrustCode, entrustCode));
        // å…å®¡æ ¸åŽç”±ä¸‹å•生成待接收的样品接收记录,主检验人仍在样品接收页面选择后才创建检验任务
        insSampleReceiptMapper.insertIgnore(order.getId(), sample.getId());
        // åŒäº‹åŠ¡å†…å‘å¸ƒä¸‹å•äº‹ä»¶ï¼Œç”± cnas-process è‡ªåŠ¨ç”Ÿæˆæ£€éªŒå§”æ‰˜å•ï¼›ç›‘å¬å™¨å¼‚å¸¸ä¼šè¿žå¸¦ä¸‹å•å›žæ»š
        applicationEventPublisher.publishEvent(new com.ruoyi.inspect.event.NewJuOrderPlacedEvent(order.getId()));
        return order.getId();
    }
@@ -701,6 +741,7 @@
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int upInsOrderOfState(InsOrder insOrder) {
        insOrder.setExamineTime(LocalDateTime.now());
        if (insOrder.getState() == 1) {
@@ -746,7 +787,17 @@
            insOrder.setEntrustCode(no);
        }
        return insOrderMapper.updateById(insOrder);
        int updated = insOrderMapper.updateById(insOrder);
        if (updated > 0 && Integer.valueOf(1).equals(insOrder.getState())) {
            List<InsSample> samples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery()
                    .eq(InsSample::getInsOrderId, insOrder.getId())
                    .orderByAsc(InsSample::getId));
            if (samples.size() != 1) {
                throw new ErrorException("委托单必须且只能包含一个样品,不能进入样品接收流程");
            }
            insSampleReceiptMapper.insertIgnore(insOrder.getId(), samples.get(0).getId());
        }
        return updated;
    }
    /**
@@ -1104,7 +1155,7 @@
        insOrder.setState(1);
        upInsOrderOfState(insOrder);
        upInsOrder(insOrder.getId(), null, appointed != null ? appointed.toString() : null, SecurityUtils.getUserId().intValue(), "原材料");
        // å®¡æ ¸é€šè¿‡åŽä»…进入样品接收;由样品接收页面选择主检验人后再创建检验任务。
        return insOrder.getId();
    }
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderTemplateServiceImpl.java
@@ -1,14 +1,21 @@
package com.ruoyi.inspect.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.StandardTreeTemplateBindingVo;
import com.ruoyi.basic.service.StandardTreeService;
import com.ruoyi.inspect.mapper.InsOrderTemplateMapper;
import com.ruoyi.inspect.pojo.InsOrderTemplate;
import com.ruoyi.inspect.service.InsOrderTemplateService;
import com.ruoyi.inspect.vo.InsOrderTemplateDetailVo;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
@@ -22,6 +29,8 @@
        implements InsOrderTemplateService {
    private InsOrderTemplateMapper insOrderTemplateMapper;
    private StandardTreeService standardTreeService;
    @Override
    public int addInsOrderTemplate(InsOrderTemplate insOrderTemplate) {
@@ -42,8 +51,39 @@
    }
    @Override
    public String selectInsOrderTemplateById(Integer id) {
        return insOrderTemplateMapper.selectById(id).getThing();
    public InsOrderTemplateDetailVo selectInsOrderTemplateById(Integer id) {
        InsOrderTemplate template = insOrderTemplateMapper.selectById(id);
        InsOrderTemplateDetailVo vo = new InsOrderTemplateDetailVo();
        if (template == null) {
            vo.setTemplateBindings(new ArrayList<>());
            return vo;
        }
        vo.setThing(template.getThing());
        // ä¼˜å…ˆå–模板列上持久化的标准ID,历史数据回退到从表单快照 addObj.standardTreeId è§£æž
        Integer standardTreeId = template.getStandardTreeId();
        if (standardTreeId == null) {
            standardTreeId = parseStandardTreeId(template.getThing());
        }
        vo.setStandardTreeId(standardTreeId);
        if (standardTreeId != null) {
            List<StandardTreeTemplateBindingVo> bindings = standardTreeService.selectTemplateBindings(standardTreeId);
            vo.setTemplateBindings(bindings == null ? new ArrayList<>() : bindings);
        } else {
            vo.setTemplateBindings(new ArrayList<>());
        }
        return vo;
    }
    private Integer parseStandardTreeId(String thing) {
        if (StringUtils.isBlank(thing)) {
            return null;
        }
        try {
            JSONObject addObj = JSON.parseObject(thing).getJSONObject("addObj");
            return addObj == null ? null : addObj.getInteger("standardTreeId");
        } catch (Exception ignored) {
            return null;
        }
    }
    @Override
@@ -51,7 +91,3 @@
        return insOrderTemplateMapper.deleteById(id);
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java
@@ -6,6 +6,7 @@
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -87,6 +88,12 @@
@Slf4j
public class InsReportServiceImpl extends ServiceImpl<InsReportMapper, InsReport>
        implements InsReportService {
    static {
        // Linux æœåŠ¡å™¨ç¼ºå°‘ä¸­æ–‡å­—ä½“ï¼ŒæŠ¥å‘Šè½¬ PDF æ—¶ä¸­æ–‡ä¼šå˜æˆæ–¹å—;将模板字体映射到 Noto CJK å…œåº•。
        FontSettings.addFontSubstitutes("宋体", "Noto Serif CJK SC");
        FontSettings.addFontSubstitutes("黑体", "Noto Sans CJK SC");
    }
    private static final int DETECTION_REPORT = 0;
    private static final int INSPECTION_REPORT = 1;
@@ -307,6 +314,9 @@
            if (userId == null) {
                throw new ErrorException("缺少批准人");
            }
            if (Objects.equals(insReport.getExamineUserId(), userId)) {
                throw new ErrorException("审核人和批准人不能为同一人,请重新选择批准人");
            }
        }
        insReport.setRatifyUserId(userId);//批准人
        //获取审核人的签名地址
@@ -389,6 +399,9 @@
    @Transactional(rollbackFor = Exception.class)
    public int ratifyReport(Integer id, Integer isRatify, String ratifyTell) {
        InsReport insReport = insReportMapper.selectById(id);
        if (Objects.equals(insReport.getExamineUserId(), SecurityUtils.getUserId().intValue())) {
            throw new ErrorException("审核人和批准人不能为同一人,请重新选择批准人");
        }
        insReport.setIsRatify(isRatify);
        if (ObjectUtils.isNotEmpty(ratifyTell)) {
            insReport.setRatifyTell(ratifyTell);
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,165 @@
package com.ruoyi.inspect.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
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.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.inspect.dto.SampleReceiptActionDto;
import com.ruoyi.inspect.dto.SampleReceiptPageDto;
import com.ruoyi.inspect.dto.SampleReceiptQueryDto;
import com.ruoyi.inspect.mapper.InsOrderMapper;
import com.ruoyi.inspect.mapper.InsOrderStandardTemplateMapper;
import com.ruoyi.inspect.mapper.InsProductMapper;
import com.ruoyi.inspect.mapper.InsSampleMapper;
import com.ruoyi.inspect.mapper.InsSampleReceiptMapper;
import com.ruoyi.inspect.mapper.InsSampleUserMapper;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.pojo.InsOrderStandardTemplate;
import com.ruoyi.inspect.pojo.InsProduct;
import com.ruoyi.inspect.pojo.InsSample;
import com.ruoyi.inspect.pojo.InsSampleReceipt;
import com.ruoyi.inspect.pojo.InsSampleUser;
import com.ruoyi.inspect.service.InsOrderService;
import com.ruoyi.inspect.service.InsOrderStateService;
import com.ruoyi.inspect.service.InsSampleReceiptService;
import com.ruoyi.system.mapper.UserMapper;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Service
@AllArgsConstructor
public class InsSampleReceiptServiceImpl extends ServiceImpl<InsSampleReceiptMapper, InsSampleReceipt>
        implements InsSampleReceiptService {
    private final InsSampleReceiptMapper receiptMapper;
    private final InsOrderMapper insOrderMapper;
    private final InsOrderStandardTemplateMapper insOrderStandardTemplateMapper;
    private final InsSampleMapper insSampleMapper;
    private final InsProductMapper insProductMapper;
    private final InsSampleUserMapper insSampleUserMapper;
    private final InsOrderStateService insOrderStateService;
    private final InsOrderService insOrderService;
    private final UserMapper userMapper;
    @Override
    public com.baomidou.mybatisplus.core.metadata.IPage<SampleReceiptPageDto> page(Page<?> page, SampleReceiptQueryDto query) {
        return receiptMapper.selectPage(page, query);
    }
    @Override
    public SampleReceiptPageDto detail(Integer id) {
        return receiptMapper.selectDetail(id);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(SampleReceiptActionDto dto) {
        if (dto == null || dto.getReceiptId() == null || dto.getMainInspectorId() == null) {
            throw new ErrorException("请选择主检验人");
        }
        InsSampleReceipt receipt = receiptMapper.selectForUpdate(dto.getReceiptId());
        ensurePending(receipt);
        InsOrder order = insOrderMapper.selectById(receipt.getInsOrderId());
        if (order == null || !Integer.valueOf(1).equals(order.getState())) {
            throw new ErrorException("该委托当前状态不允许样品接收");
        }
        List<InsSample> samples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery()
                .eq(InsSample::getInsOrderId, order.getId()).orderByAsc(InsSample::getId));
        if (samples.size() != 1 || !samples.get(0).getId().equals(receipt.getInsSampleId())) {
            throw new ErrorException("该委托的样品数量异常,请检查下单数据");
        }
        InsSample sample = samples.get(0);
        // åªèµ°æ–°èšç›´ç»‘模板流程:委托单必须已绑定原始记录模板(下单时生成订单模板快照)
        Long snapshotCount = insOrderStandardTemplateMapper.selectCount(Wrappers.<InsOrderStandardTemplate>lambdaQuery()
                .eq(InsOrderStandardTemplate::getInsOrderId, order.getId()));
        if (snapshotCount == 0) {
            throw new ErrorException("该委托未绑定原始记录模板,不能提交检验");
        }
        Long productCount = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
                .eq(InsProduct::getInsSampleId, sample.getId()).eq(InsProduct::getState, 1));
        if (productCount == 0) {
            throw new ErrorException("该委托未绑定检验项目,不能提交检验");
        }
        if (userMapper.selectById(dto.getMainInspectorId()) == null) {
            throw new ErrorException("主检验人不存在或已停用");
        }
        if (insOrderStateService.count(Wrappers.lambdaQuery(com.ruoyi.inspect.pojo.InsOrderState.class)
                .eq(com.ruoyi.inspect.pojo.InsOrderState::getInsOrderId, order.getId())) > 0
                || insSampleUserMapper.selectCount(Wrappers.<InsSampleUser>lambdaQuery()
                .eq(InsSampleUser::getInsSampleId, order.getId())) > 0) {
            throw new ErrorException("该委托已进入检验任务,不能重复提交");
        }
        String appointed = LocalDateTime.now().plusHours(insProductMapper.selectOrderManDay(order.getId()))
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        insOrderService.upInsOrder(order.getId(), sample.getId(), appointed, dto.getMainInspectorId(), null);
        receipt.setStatus(1);
        receipt.setMainInspectorId(dto.getMainInspectorId());
        receipt.setReceiveUserId(SecurityUtils.getUserId().intValue());
        receipt.setReceiveTime(LocalDateTime.now());
        receipt.setSubmitTime(LocalDateTime.now());
        receiptMapper.updateById(receipt);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reject(SampleReceiptActionDto dto) {
        if (dto == null || dto.getReceiptId() == null || StringUtils.isBlank(dto.getRemark())) {
            throw new ErrorException("请填写拒收备注");
        }
        if (dto.getRemark().trim().length() > 500) {
            throw new ErrorException("拒收备注不能超过500个字符");
        }
        InsSampleReceipt receipt = receiptMapper.selectForUpdate(dto.getReceiptId());
        ensurePending(receipt);
        if (insOrderStateService.count(Wrappers.lambdaQuery(com.ruoyi.inspect.pojo.InsOrderState.class)
                .eq(com.ruoyi.inspect.pojo.InsOrderState::getInsOrderId, receipt.getInsOrderId())) > 0) {
            throw new ErrorException("该委托已进入检验任务,不能拒收");
        }
        receipt.setStatus(2);
        receipt.setRejectRemark(dto.getRemark().trim());
        receipt.setReceiveUserId(SecurityUtils.getUserId().intValue());
        receipt.setReceiveTime(LocalDateTime.now());
        receiptMapper.updateById(receipt);
        InsOrder order = new InsOrder();
        order.setId(receipt.getInsOrderId());
        order.setState(5);
        insOrderMapper.updateById(order);
    }
    private void ensurePending(InsSampleReceipt receipt) {
        if (receipt == null || !Integer.valueOf(0).equals(receipt.getStatus())) {
            throw new ErrorException("该样品接收记录已被处理,请刷新后重试");
        }
    }
    @Override
    public void export(SampleReceiptQueryDto query, HttpServletResponse response) {
        List<SampleReceiptPageDto> list = receiptMapper.selectExportList(query);
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        try {
            String fileName = URLEncoder.encode("样品接收导出", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
            WriteSheet sheet = EasyExcel.writerSheet(0, "样品接收导出").head(SampleReceiptPageDto.class).build();
            excelWriter.write(list, sheet);
            excelWriter.finish();
        } catch (IOException e) {
            throw new RuntimeException("导出失败");
        }
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderPrintingVo.java
@@ -35,6 +35,9 @@
    @ApiModelProperty("检测编号")
    private String entrustCode;
    @ApiModelProperty("样品编码")
    private String sampleCode;
    @ApiModelProperty("样品数量")
    private String testQuantity;
inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderTemplateDetailVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.inspect.vo;
import com.ruoyi.basic.dto.StandardTreeTemplateBindingVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/** å§”托单模板详情:表单快照 + ç»‘定的标准 + è¯¥æ ‡å‡†ä¸‹çš„原始记录模板。 */
@Data
public class InsOrderTemplateDetailVo {
    @ApiModelProperty("表单快照JSON")
    private String thing;
    @ApiModelProperty("绑定的标准库二级标准ID")
    private Integer standardTreeId;
    @ApiModelProperty("标准绑定的原始记录模板")
    private List<StandardTreeTemplateBindingVo> templateBindings = new ArrayList<>();
}
inspect-server/src/main/resources/mapper/InsOrderMapper.xml
@@ -115,12 +115,14 @@
        GROUP_CONCAT(DISTINCT isa.model SEPARATOR ' ') AS sample_model,
        u.name,
        testing_name,
        ip.son_laboratory
        ip.son_laboratory,
        isr.reject_remark AS sample_reject_remark
        FROM
        ins_order io
        LEFT JOIN
        ins_sample isa ON io.id = isa.ins_order_id
        left join ins_product ip on ip.ins_sample_id = isa.id
        LEFT JOIN ins_sample_receipt isr ON isr.ins_order_id = io.id
        LEFT JOIN
        ins_sample_user isau ON isau.ins_sample_id = io.id
        LEFT JOIN
@@ -152,7 +154,10 @@
        ORDER BY ins_sample_id) isu ON isu.ins_sample_id = io.id
        where (io.ifs_inventory_id IS NULL OR TRIM(io.ifs_inventory_id)  = '')
        <if test="isOrderAll != null and isOrderAll != ''">
            AND io.state in (1, 4)
            AND io.state in (1, 4, 5)
        </if>
        <if test="receiptSubmitted != null and receiptSubmitted != ''">
            AND isr.status = 1
        </if>
        <if test="laboratory!=null and laboratory!=''">
            AND io.laboratory=#{laboratory}
@@ -411,6 +416,7 @@
                     GROUP_CONCAT(DISTINCT isa.model SEPARATOR ' ') AS sample_model,
                     io2.prepare_user,
                     io2.entrust_code,
                     GROUP_CONCAT(DISTINCT isa.sample_code SEPARATOR ' ') AS sample_code,
                     io2.test_quantity,
                     io2.ins_state,
                     JSON_OBJECT(
@@ -433,7 +439,7 @@
        from ( <include refid="selectInsOrderExport"/>
        where (io.ifs_inventory_id IS NULL OR TRIM(io.ifs_inventory_id)  = '')
        <if test="isOrderAll != null and isOrderAll != ''">
            AND io.state in (1, 4)
            AND io.state in (1, 4, 5)
        </if>
        <if test="laboratory!=null and laboratory!=''">
            AND io.laboratory=#{laboratory}
inspect-server/src/main/resources/mapper/InsSampleMapper.xml
@@ -491,6 +491,7 @@
                 left join ins_product ip on isa.id = ip.ins_sample_id
                 left join ins_product_result ipr on ip.id = ipr.ins_product_id
        where ins_order_id = #{id}
        <if test="laboratory != null and laboratory != ''">
          and (
              (ip.state = 1 and ip.son_laboratory = #{laboratory})
              or (
@@ -503,6 +504,7 @@
                  )
              )
          )
        </if>
    </select>
    <select id="getSampleEn" resultType="java.lang.String">
        select name_en
@@ -608,10 +610,12 @@
                 left join ins_product_result ipr on ip.id = ipr.ins_product_id
        where ins_sample_id = #{id}
          and state = 1
        <if test="laboratory != null and laboratory != ''">
          and ip.son_laboratory = #{laboratory}
        </if>
          and ins_fiber_id is null
          and ins_fibers_id is null
          and (standard_method_list_id is not null or template_row_index is not null)
          and template_id is not null
        /* ç”µç¼†é…ç½®æ ‡è¯† */
        <if test="cableTag == null or cableTag == ''">
            and ip.cable_tag is null
@@ -635,10 +639,12 @@
        left join ins_product_result ipr on ip.id = ipr.ins_product_id
        where ins_sample_id = #{id}
        and state = 1
        <if test="laboratory != null and laboratory != ''">
        and ip.son_laboratory = #{laboratory}
        </if>
        and ins_fiber_id is null
        and ins_fibers_id is null
        and (standard_method_list_id is not null or template_row_index is not null)
        and template_id is not null
        and ip.raw_material_tag = #{rawMaterialTag}
        order by sort asc
    </select>
inspect-server/src/main/resources/mapper/InsSampleReceiptMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.inspect.mapper.InsSampleReceiptMapper">
    <sql id="receiptColumns">
        r.id receipt_id, r.ins_order_id order_id, r.ins_sample_id sample_id, r.status,
        isa.sample sample_name, isa.sample_code, io.entrust_code,
        COALESCE(iost.method_standard, sm.code) method_standard,
        ip.inspection_item, r.main_inspector_id, u.name main_inspector_name,
        COALESCE(isa.remark, io.remark) remark, r.reject_remark, r.receive_time,
        ru.name receive_user_name
    </sql>
    <select id="selectPage" resultType="com.ruoyi.inspect.dto.SampleReceiptPageDto">
        SELECT
        <include refid="receiptColumns"/>
        FROM ins_sample_receipt r
        JOIN ins_order io ON io.id = r.ins_order_id
        JOIN ins_sample isa ON isa.id = r.ins_sample_id
        LEFT JOIN standard_method sm ON sm.id = isa.standard_method_list_id
        LEFT JOIN (
        SELECT ins_order_id,
        GROUP_CONCAT(DISTINCT number ORDER BY sort SEPARATOR '\n') method_standard
        FROM ins_order_standard_template
        GROUP BY ins_order_id
        ) iost ON iost.ins_order_id = io.id
        LEFT JOIN (
        SELECT ins_sample_id,
        GROUP_CONCAT(DISTINCT inspection_item ORDER BY sort SEPARATOR '\n') inspection_item
        FROM ins_product
        WHERE state = 1
        GROUP BY ins_sample_id
        ) ip ON ip.ins_sample_id = isa.id
        LEFT JOIN user u ON u.id = r.main_inspector_id
        LEFT JOIN user ru ON ru.id = r.receive_user_id
        WHERE 1 = 1
        <if test="query.status != null">AND r.status = #{query.status}</if>
        <if test="query.entrustCode != null and query.entrustCode != ''">AND io.entrust_code LIKE CONCAT('%',
            #{query.entrustCode}, '%')
        </if>
        <if test="query.sampleCode != null and query.sampleCode != ''">AND isa.sample_code LIKE CONCAT('%',
            #{query.sampleCode}, '%')
        </if>
        <if test="query.sampleName != null and query.sampleName != ''">AND isa.sample LIKE CONCAT('%',
            #{query.sampleName}, '%')
        </if>
        GROUP BY r.id
        ORDER BY r.create_time DESC
    </select>
    <select id="selectDetail" resultType="com.ruoyi.inspect.dto.SampleReceiptPageDto">
        SELECT <include refid="receiptColumns"/>
        FROM ins_sample_receipt r
        JOIN ins_order io ON io.id = r.ins_order_id
        JOIN ins_sample isa ON isa.id = r.ins_sample_id
        LEFT JOIN standard_method sm ON sm.id = isa.standard_method_list_id
        LEFT JOIN (
            SELECT ins_order_id,
                   GROUP_CONCAT(DISTINCT number ORDER BY sort SEPARATOR '\n') method_standard
            FROM ins_order_standard_template
            GROUP BY ins_order_id
        ) iost ON iost.ins_order_id = io.id
        LEFT JOIN (
            SELECT ins_sample_id,
                   GROUP_CONCAT(DISTINCT inspection_item ORDER BY sort SEPARATOR '\n') inspection_item
            FROM ins_product
            WHERE state = 1
            GROUP BY ins_sample_id
        ) ip ON ip.ins_sample_id = isa.id
        LEFT JOIN user u ON u.id = r.main_inspector_id
        LEFT JOIN user ru ON ru.id = r.receive_user_id
        WHERE r.id = #{id}
        GROUP BY r.id
    </select>
    <select id="selectExportList" resultType="com.ruoyi.inspect.dto.SampleReceiptPageDto">
        SELECT <include refid="receiptColumns"/>
        FROM ins_sample_receipt r
        JOIN ins_order io ON io.id = r.ins_order_id
        JOIN ins_sample isa ON isa.id = r.ins_sample_id
        LEFT JOIN standard_method sm ON sm.id = isa.standard_method_list_id
        LEFT JOIN (
            SELECT ins_order_id,
                   GROUP_CONCAT(DISTINCT number ORDER BY sort SEPARATOR '\n') method_standard
            FROM ins_order_standard_template
            GROUP BY ins_order_id
        ) iost ON iost.ins_order_id = io.id
        LEFT JOIN (
            SELECT ins_sample_id,
                   GROUP_CONCAT(DISTINCT inspection_item ORDER BY sort SEPARATOR '\n') inspection_item
            FROM ins_product
            WHERE state = 1
            GROUP BY ins_sample_id
        ) ip ON ip.ins_sample_id = isa.id
        LEFT JOIN user u ON u.id = r.main_inspector_id
        LEFT JOIN user ru ON ru.id = r.receive_user_id
        WHERE 1 = 1
        <if test="query.status != null"> AND r.status = #{query.status}</if>
        <if test="query.entrustCode != null and query.entrustCode != ''"> AND io.entrust_code LIKE CONCAT('%', #{query.entrustCode}, '%')</if>
        <if test="query.sampleCode != null and query.sampleCode != ''"> AND isa.sample_code LIKE CONCAT('%', #{query.sampleCode}, '%')</if>
        <if test="query.sampleName != null and query.sampleName != ''"> AND isa.sample LIKE CONCAT('%', #{query.sampleName}, '%')</if>
        GROUP BY r.id
        ORDER BY r.create_time DESC
    </select>
    <select id="selectForUpdate" resultType="com.ruoyi.inspect.pojo.InsSampleReceipt">
        SELECT * FROM ins_sample_receipt WHERE id = #{id} FOR UPDATE
    </select>
    <insert id="insertIgnore">
        INSERT IGNORE INTO ins_sample_receipt(ins_order_id, ins_sample_id, status, create_time, update_time)
        VALUES(#{orderId}, #{sampleId}, 0, NOW(), NOW())
    </insert>
</mapper>
inspect-server/src/main/resources/static/detection-report-template-v2.docx
Binary files differ
inspect-server/src/main/resources/static/inspection-report-template-v2.docx
Binary files differ