zouyu
2025-09-24 2bb12b1ca40b29b7edcf06ef3f3d6de24dde1c4c
原材料订单拆分功能v1
已添加13个文件
已修改18个文件
1685 ■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/mapper/IfsInventoryQuantityMapper.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/pojo/IfsInventoryQuantity.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/vo/IfsInventoryQuantityVO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/resources/mapper/IfsInventoryQuantityMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderPlanController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/RawMaterialOrderController.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/OrderSplitDTO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/excel/OrderSplitExcelData.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/excel/OrderSplitExcelListener.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/mapper/IfsSplitOrderRecordMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/IfsSplitOrderRecord.java 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/IfsSplitOrderRecordService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderPlanService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderService.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/InsReportService.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/RawMaterialOrderService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/IfsSplitOrderRecordServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java 209 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/RawMaterialOrderServiceImpl.java 232 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/task/RawMaterIalSchedule.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderPlanVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/IfsSplitOrderRecordMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/InsSampleMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/static/split_order_import_template.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/api/MesApiUtils.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/ParameterEscaperUtil.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/mapper/IfsInventoryQuantityMapper.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.basic.dto.IfsInventoryQuantityDto;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.basic.vo.IfsInventoryQuantityVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -24,7 +25,7 @@
     * @param ifsInventoryId
     * @return
     */
    int selectReportCountById(@Param("ifsInventoryId") Integer ifsInventoryId);
    int selectReportCountById(@Param("ifsInventoryId") Long ifsInventoryId);
    /**
@@ -39,4 +40,10 @@
                          @Param("supplierName") String supplierName,
                          @Param("startOfNextQuarter") LocalDateTime startOfNextQuarter,
                          @Param("endOfQuarter") LocalDateTime endOfQuarter);
    List<IfsInventoryQuantityVO> selectSplitOrderList(@Param("partNo")String partNo,
                                                      @Param("lineNo")String lineNo,
                                                      @Param("releaseNo")String releaseNo,
                                                      @Param("receiptNo")Integer receiptNo,
                                                      @Param("orderNo")String orderNo);
}
basic-server/src/main/java/com/ruoyi/basic/pojo/IfsInventoryQuantity.java
@@ -18,8 +18,7 @@
@ExcelIgnoreUnannotated
public class IfsInventoryQuantity  implements Serializable {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private Long id;
    @ApiModelProperty("域")
    private String contract;
@@ -207,4 +206,7 @@
    // æ˜¯å¦æ˜¯è¿‡æœŸææ–™: 0否, 1:是"
    @ApiModelProperty("物料类型")
    private Integer isExpire;
    @ApiModelProperty("是否为拆分订单(1:是,0:否)")
    private Integer isSplitOrder;
}
basic-server/src/main/java/com/ruoyi/basic/vo/IfsInventoryQuantityVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.basic.vo;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * åŽŸææ–™æŠ¥æ£€vo
 */
@Data
public class IfsInventoryQuantityVO extends IfsInventoryQuantity {
    /**
     * æ£€éªŒå•id
     */
    @ApiModelProperty(value = "检验单id")
    private Integer insOrderId;
    /**
     * æ£€éªŒç»“果(0:不合格,1:合格)
     */
    @ApiModelProperty(value = "检验结果(0:不合格,1:合格)")
    private Integer insResult;
    /**
     * åŒæ­¥çŠ¶æ€ï¼ˆ0:未同步,1:已同步)
     */
    @ApiModelProperty(value = "同步状态(0:未同步,1:已同步)")
    private Integer syncStatus;
}
basic-server/src/main/resources/mapper/IfsInventoryQuantityMapper.xml
@@ -71,4 +71,28 @@
          and iiq.supplier_name = #{supplierName}
          and iiq.receiver_date between #{startOfNextQuarter} and #{endOfQuarter}
    </select>
    <select id="selectSplitOrderList" resultType="com.ruoyi.basic.vo.IfsInventoryQuantityVO">
        select
            iiq.*,
            io.id AS ins_order_id,
            io.ins_result,
            isor.sync_status
        from ifs_inventory_quantity iiq
                 join ifs_split_order_record isor
                      on iiq.update_batch_no = isor.lot_batch_no
                          and iiq.order_no=isor.order_no
                          and iiq.line_no=isor.line_no
                          and iiq.release_no=isor.release_no
                          and iiq.receipt_no=isor.receipt_no
                          and iiq.part_no=isor.part_no
                 left join ins_order io on iiq.id=io.ifs_inventory_id
        where iiq.order_no=#{orderNo}
          and iiq.part_no=#{partNo}
          and iiq.line_no=#{lineNo}
          and iiq.release_no=#{releaseNo}
          and iiq.receipt_no=#{receiptNo}
          and iiq.is_split_order=1
          and (iiq.is_finish != 1 or isor.sync_status != 1)
          and (io.id is null or io.is_exemption != 1)
    </select>
</mapper>
inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,86 @@
package com.ruoyi.inspect.aspect;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.common.utils.api.MesApiUtils;
import com.ruoyi.inspect.pojo.IfsSplitOrderRecord;
import com.ruoyi.inspect.service.IfsSplitOrderRecordService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * æ‰§è¡Œifs移库操作后,同步推送mes实时库存
 */
@Aspect
@Slf4j
@Component
public class MoveLocationAfterPushMesStockAspect {
    @Autowired
    private IfsSplitOrderRecordService ifsSplitOrderRecordService;
    @Autowired
    private MesApiUtils mesApiUtils;
    @AfterReturning(value = "execution(* com.ruoyi.inspect.service.impl.InsOrderServiceImpl.moveRawMaterial(..))")
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void doAfterReturning(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        if(Objects.nonNull(args) && args.length>0) {
            IfsInventoryQuantity ifsInventoryQuantity = BeanUtil.toBean(args[0], IfsInventoryQuantity.class);
            if(Objects.nonNull(ifsInventoryQuantity) && ifsInventoryQuantity.getIsSplitOrder()==1){
                //查询对应批号的拆分记录
                IfsSplitOrderRecord one = ifsSplitOrderRecordService.getOne(Wrappers.<IfsSplitOrderRecord>lambdaQuery()
                        .eq(IfsSplitOrderRecord::getPartNo, ifsInventoryQuantity.getPartNo())
                        .eq(IfsSplitOrderRecord::getLotBatchNo, ifsInventoryQuantity.getUpdateBatchNo())
                        .eq(IfsSplitOrderRecord::getLineNo, ifsInventoryQuantity.getLineNo())
                        .eq(IfsSplitOrderRecord::getReleaseNo, ifsInventoryQuantity.getReleaseNo())
                        .eq(IfsSplitOrderRecord::getReceiptNo, ifsInventoryQuantity.getReceiptNo())
                        .eq(IfsSplitOrderRecord::getOrderNo, ifsInventoryQuantity.getOrderNo())
                        .last("limit 1")
                );
                if(Objects.nonNull(one)){
                    //同步MES实时库存
                    Map<String, Object> requestMap = new HashMap<>();
                    requestMap.put("partNo", one.getPartNo()); // é›¶ä»¶ç¼–号
                    requestMap.put("systemNo", one.getSystemNo()); // ç³»ç»Ÿç¼–号
                    requestMap.put("spec", one.getSpec()); // è§„æ ¼
                    requestMap.put("partBatchNo", one.getLotBatchNo()); // é›¶ä»¶æ‰¹å·
                    requestMap.put("stockQuantity", one.getLength()); // åº“存数量1
                    requestMap.put("qty", one.getQtyStock()); // åº“存数量2
                    requestMap.put("insulationColor", one.getInsulationColor()); // ç»ç¼˜é¢œè‰²
                    requestMap.put("outerColor", one.getOuterColor()); // å¤–护颜色
                    requestMap.put("letteringInfo", one.getLetteringInfo()); // å°å­—信息
                    requestMap.put("reelNumber", one.getDrumNo()); // ç›˜å·
                    requestMap.put("locationNo", "1302"); // åº“位编号
                    requestMap.put("customerOrderNo", one.getOrderNo()); // é”€å”®è®¢å•号
                    requestMap.put("stockSource", one.getStockSource()); // åº“存来源
                    requestMap.put("remark", one.getRemark()); // å¤‡æ³¨
                    String jsonStr = JSONUtil.toJsonStr(Collections.singletonList(requestMap));
                    boolean b = mesApiUtils.batchAddStock(jsonStr);
                    //同步成功,更新同步状态
                    if(b){
                        ifsSplitOrderRecordService.update(null,Wrappers.<IfsSplitOrderRecord>lambdaUpdate()
                                .set(IfsSplitOrderRecord::getSyncStatus,1)
                                .eq(IfsSplitOrderRecord::getId,one.getId()));
                    }
                }
            }
        }
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java
@@ -35,6 +35,7 @@
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -158,7 +159,7 @@
        Integer orderId = (Integer) param.get("orderId");
        String ids = (String) param.get("ids");
        Integer typeSource = (Integer) param.get("typeSource");
        Integer ifsInventoryId = (Integer) param.get("ifsInventoryId");
        Long ifsInventoryId = Long.parseLong(param.get("ifsInventoryId").toString());
        if(Objects.nonNull(typeSource) && typeSource == 1){
            ifsInventoryQuantityMapper.update(null,new LambdaUpdateWrapper<IfsInventoryQuantity>()
                    .set(IfsInventoryQuantity::getState,0)
@@ -182,7 +183,10 @@
    @ApiOperation(value = "获取ifs订单")
    @GetMapping("/getIfsOrder")
    public Result<?> getIfsOrder() {
        insOrderService.getIfsOrder();
        HashMap<String, Object> map = new HashMap<>();
        map.put("LOCATION_NO","1302");
        map.put("STATE_DB","To be Inspected");
        insOrderService.getIfsOrder(map,false);
        return Result.success();
    }
inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderPlanController.java
@@ -103,11 +103,10 @@
        return Result.success(insOrderPlanService.checkSubmitPlan(orderId, laboratory));
    }
    @ApiOperation(value = "检验任务提交")
    @PostMapping("/submitPlan")
    public Result<?> submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode) {
        int num = insOrderPlanService.submitPlan(orderId, laboratory, verifyUser, entrustCode);
    public Result<?> submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode,Boolean registerInsResults) {
        int num = insOrderPlanService.submitPlan(orderId, laboratory, verifyUser, entrustCode,registerInsResults);
        return num == 1 ? Result.success() : Result.fail("提交失败,部分项目还未进行检验");
    }
inspect-server/src/main/java/com/ruoyi/inspect/controller/RawMaterialOrderController.java
@@ -1,5 +1,6 @@
package com.ruoyi.inspect.controller;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -7,6 +8,7 @@
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.common.annotation.PersonalScope;
import com.ruoyi.inspect.dto.InsPlaceOrderDto;
import com.ruoyi.inspect.dto.OrderSplitDTO;
import com.ruoyi.inspect.dto.SampleProductDto;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.pojo.RawMaterialOrderTemplate;
@@ -22,7 +24,9 @@
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.List;
@@ -93,7 +97,6 @@
        return Result.success(rawMaterialOrderTemplateService.delRawMaterOrderTemplate(id));
    }
    /**
     * æŠ¥æ£€æ‰¹é‡
     * @param param åŽŸææ–™id
@@ -102,7 +105,7 @@
    @ApiOperation(value = "报检批量")
    @PostMapping("/inspectionReport")
    public Result<?> inspectionReport(@RequestBody Map<String, Object> param) {
        List<Integer> ids = (List<Integer>) param.get("ids");
        List<Long> ids = (List<Long>) param.get("ids");
        return Result.success(rawMaterialOrderService.inspectionReport(ids));
    }
@@ -114,7 +117,7 @@
    @ApiOperation(value = "撤销报检")
    @PostMapping("/revokeInspectionReport")
    public Result<?> revokeInspectionReport(@RequestBody Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        Long id = Long.parseLong(param.get("id").toString());
        return Result.success(rawMaterialOrderService.revokeInspectionReport(id));
    }
@@ -138,7 +141,6 @@
    @ApiOperation(value = "报检")
    @PostMapping("/inspectionReportOne")
    public Result<?> inspectionReportOne(@RequestBody IfsInventoryQuantity ifsInventoryQuantity) {
        return Result.success(rawMaterialOrderService.inspectionReportOne(ifsInventoryQuantity));
    }
@@ -161,7 +163,7 @@
    @ApiOperation(value = "原材料撤销下单")
    @GetMapping("/repealRawOrder")
    public Result<?> repealRawOrder(@RequestBody Map<String, Object> param){
        Integer ifsInventoryId = (Integer) param.get("ifsInventoryId");
        Long ifsInventoryId = Long.parseLong(param.get("ifsInventoryId").toString());
        return Result.success(rawMaterialOrderService.repealRawOrder(ifsInventoryId));
    }
@@ -198,7 +200,7 @@
    @ApiOperation(value = "原材料下单放行免检")
    @PostMapping("/rawOrderRelease")
    public Result<?> rawOrderRelease(@RequestBody Map<String, Object> param){
        Integer ifsInventoryId = (Integer) param.get("ifsInventoryId");
        Long ifsInventoryId = Long.parseLong(param.get("ifsInventoryId").toString());
        String partDetail = (String) param.get("partDetail");
        return Result.success(rawMaterialOrderService.rawOrderRelease(ifsInventoryId, partDetail));
    }
@@ -210,7 +212,7 @@
     */
    @ApiOperation(value = "原材料下单通知免检或者多次检验")
    @GetMapping("/notificationRawOrder")
    public Result<?> notificationRawOrder(Integer ifsInventoryId){
    public Result<?> notificationRawOrder(Long ifsInventoryId){
        return Result.success(rawMaterialOrderService.notificationRawOrder(ifsInventoryId));
    }
@@ -266,7 +268,7 @@
    @ApiOperation(value = "让步放行")
    @PostMapping("/concessionRelease")
    public Result<?> concessionRelease(@RequestBody Map<String, Object> param){
        Integer ifsInventoryId = (Integer) param.get("ifsInventoryId");
        Long ifsInventoryId = Long.parseLong(param.get("ifsInventoryId").toString());
        return Result.success(rawMaterialOrderService.concessionRelease(ifsInventoryId));
    }
@@ -316,8 +318,35 @@
    @ApiOperation(value = "提前入库")
    @PostMapping("/advancedGodown")
    public Result<?> advancedGodown(@RequestBody Map<String, Object> param){
        Integer ifsInventoryId = (Integer) param.get("ifsInventoryId");
        Long ifsInventoryId = Long.parseLong(param.get("ifsInventoryId").toString());
        return Result.success(rawMaterialOrderService.advancedGodown(ifsInventoryId));
    }
    /**
     * ä¸‹è½½è®¢å•拆分导入模板
     */
    @ApiOperation(value = "下载订单拆分导入模板")
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response){
        rawMaterialOrderService.downloadTemplate(response);
    }
    /**
     * ä¸‹è½½è®¢å•拆分导入模板
     */
    @ApiOperation(value = "导入订单拆分数据")
    @PostMapping("/importSplitOrderData")
    public Result importSplitOrderData(@RequestParam(value = "file") MultipartFile file,@RequestParam("ifsId") Long ifsId, HttpServletRequest request){
        return rawMaterialOrderService.importSplitOrderData(file,ifsId,request);
    }
    /**
     * ç¡®è®¤æ‹†åˆ†è®¢å•
     */
    @ApiOperation(value = "确认拆分订单")
    @PostMapping("/confirmSplitOrder")
    public Result confirmSplitOrder(@RequestBody OrderSplitDTO orderSplitDTO){
        return Result.success(rawMaterialOrderService.confirmSplitOrder(orderSplitDTO));
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/dto/OrderSplitDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ruoyi.inspect.dto;
import com.ruoyi.inspect.excel.OrderSplitExcelData;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * è®¢å•拆分dto
 */
@Data
public class OrderSplitDTO implements Serializable {
    /**
     * ifs订单主键id
     */
    @ApiModelProperty("ifs订单主键id")
    private Long ifsId;
    /**
     *拆分详情列表
     */
    @ApiModelProperty("拆分详情列表")
    private List<OrderSplitExcelData> splitDetailList;
    /**
     *是否同步到MES
     */
    @ApiModelProperty("是否同步到MES")
    private Boolean pushToMes;
}
inspect-server/src/main/java/com/ruoyi/inspect/excel/OrderSplitExcelData.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
package com.ruoyi.inspect.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
 * åŽŸææ–™æŠ¥æ£€ï¼šè®¢å•æ‹†åˆ†å¯¼å…¥æ¨¡æ¿å¯¹è±¡
 */
@Data
public class OrderSplitExcelData implements Serializable {
    /**
     * é›¶ä»¶ç¼–号
     */
    @ExcelProperty(index = 0,value = "零件编号")
    @ApiModelProperty("零件编号")
    private String partNo;
    /**
     * ç³»ç»Ÿç¼–号
     */
    @ExcelProperty(index = 1,value = "系统编号")
    @ApiModelProperty("系统编号 ")
    private String systemNo;
    /**
     * è§„æ ¼
     */
    @ExcelProperty(index = 2,value = "规格")
    @ApiModelProperty("规格")
    private String spec;
    /**
     * é›¶ä»¶æ‰¹å·
     */
    @ExcelProperty(index = 3,value = "零件批号")
    @ApiModelProperty("零件批号")
    private String lotBatchNo;
    /**
     * åº“存数量1
     */
    @ExcelProperty(index = 4,value = "库存数量1")
    @ApiModelProperty("库存数量1(用于对接mes分盘计算)")
    private BigDecimal length;
    /**
     * åº“存数量2
     */
    @ExcelProperty(index = 5,value = "库存数量2")
    @ApiModelProperty("库存数量2(ifs对于的库存数量)")
    private BigDecimal qtyStock;
    /**
     * ç»ç¼˜é¢œè‰²
     */
    @ExcelProperty(index = 6,value = "绝缘颜色")
    @ApiModelProperty("绝缘颜色")
    private String insulationColor;
    /**
     * å¤–护颜色
     */
    @ExcelProperty(index = 7,value = "外护颜色")
    @ApiModelProperty("外护颜色")
    private String outerColor;
    /**
     * å°å­—信息
     */
    @ExcelProperty(index = 8,value = "印字信息")
    @ApiModelProperty("印字信息")
    private String letteringInfo;
    /**
     * ç›˜å·
     */
    @ExcelProperty(index = 9,value = "盘号")
    @ApiModelProperty("盘号")
    private String drumNo;
    /**
     * åº“位编号
     */
    @ExcelProperty(index = 10,value = "库位编号")
    @ApiModelProperty("库位编号")
    private String locationNo;
    /**
     * åº“位来源
     */
    @ExcelProperty(index = 11,value = "库位来源")
    @ApiModelProperty("库位来源")
    private String stockSource;
    /**
     * å¤‡æ³¨
     */
    @ExcelProperty(index = 12,value = "备注")
    @ApiModelProperty("备注")
    private String remark;
}
inspect-server/src/main/java/com/ruoyi/inspect/excel/OrderSplitExcelListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,146 @@
package com.ruoyi.inspect.excel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
public class OrderSplitExcelListener extends AnalysisEventListener<Map<Integer,Object>> {
    //表头模板
    private static final String HEAD_TEMPLATE = "[零件编号, ç³»ç»Ÿç¼–号, è§„æ ¼, é›¶ä»¶æ‰¹å·, åº“存数量1, åº“存数量2, ç»ç¼˜é¢œè‰², å¤–护颜色, å°å­—信息, ç›˜å·, åº“位编号, åº“位来源, å¤‡æ³¨]";
    AtomicInteger index = new AtomicInteger(0);//符合表格模板的行数
    @Getter
    List<OrderSplitExcelData> dataList = new ArrayList<>();//导入的数据列表
    IfsInventoryQuantity ifsInventoryQuantity;//对应报检ifs信息
    public String errorMsg = "";
    public OrderSplitExcelListener(IfsInventoryQuantity ifsInventoryQuantity) {
        this.ifsInventoryQuantity = ifsInventoryQuantity;
    }
    AtomicReference<String> prePartLotBatchNo = new AtomicReference<>("");//上一条数据的零件批号
    AtomicReference<BigDecimal> storeQty2Sum = new AtomicReference<>(BigDecimal.ZERO);//导入数据库存数量2的总和
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        String temp = headMap.values().toString();
        if(StringUtils.equals(HEAD_TEMPLATE,temp)){
            index.getAndIncrement();
        }
    }
    @Override
    public void invoke(Map<Integer,Object> mapData, AnalysisContext analysisContext) {
        Integer currentRowNum = analysisContext.getCurrentRowNum();
        OrderSplitExcelData data = transformExcelData(mapData, currentRowNum);
        if(Objects.nonNull(data)){
            dataList.add(data);
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if(index.get()==0){
            throw new RuntimeException("文件内容格式与模板不符");
        }
        if(storeQty2Sum.get().compareTo(ifsInventoryQuantity.getPurQtyInStore())>0){
            throw new RuntimeException("库存数量2不能大于报检零件的抵达采购数量");
        }
    }
    /**
     * æ ¡éªŒæ•°æ®
     * @param mapData
     * @param rowNumber
     */
    private void validateRowData(Map<Integer,Object> mapData,Integer rowNumber){
        String rowStr = "</br>第"+(rowNumber+1)+"行:";
        List<String> errorMsgList = new ArrayList<>();
        //零件编号
        if(Objects.isNull(mapData.get(0))){
            errorMsgList.add("零件编号不能为空");
        }else if(!StringUtils.equals(mapData.get(0).toString(),ifsInventoryQuantity.getPartNo())){
            errorMsgList.add("零件编号与报检零件不一致");
        }
        //零件批号
        if(Objects.isNull(mapData.get(3))){
            errorMsgList.add("零件批号不能为空");
        }else if(StringUtils.equals(mapData.get(3).toString(),ifsInventoryQuantity.getLotBatchNo())){
            errorMsgList.add("零件批号与报检零件批号相同");
        }else if(StringUtils.equals(prePartLotBatchNo.get(),mapData.get(3).toString())){
            errorMsgList.add("零件批号存在重复");
        }
        prePartLotBatchNo.getAndSet(mapData.get(3).toString());
        //库存数量2
        if(Objects.isNull(mapData.get(5))){
            errorMsgList.add("库存数量2不能为空");
        }else{
            BigDecimal storeQty2 = BigDecimal.ZERO;
            try{
                storeQty2 = new BigDecimal(mapData.get(5).toString());
            }catch (Exception e){
                errorMsgList.add("库存数量2格式异常");
            }
            if(storeQty2.compareTo(ifsInventoryQuantity.getPurQtyInStore())>0){
                errorMsgList.add("库存数量2不能大于报检零件的抵达采购数量");
            }
            BigDecimal oldSum = storeQty2Sum.get();
            storeQty2Sum.getAndSet(oldSum.add(storeQty2));
        }
        //库位编号
        if(Objects.isNull(mapData.get(10))){
            errorMsgList.add("库位编号不能为空");
        }else if(!StringUtils.equals(mapData.get(10).toString(),ifsInventoryQuantity.getLocationNo())){
            errorMsgList.add("库位编号与报检零件的库位编号不一致");
        }
        if(!errorMsgList.isEmpty()){
            String errorStr = String.join(";",errorMsgList);
            errorMsg+= rowStr + errorStr ;
        }
    }
    /**
     * è½¬æ¢excel导入行数据
     * @param mapData
     * @return
     */
    private OrderSplitExcelData transformExcelData(Map<Integer,Object> mapData,Integer rowNumber){
        validateRowData(mapData,rowNumber);
        if(StringUtils.isBlank(errorMsg)){
            OrderSplitExcelData data = new OrderSplitExcelData();
            data.setPartNo(mapData.get(0).toString());
            data.setSystemNo(Objects.isNull(mapData.get(1))?"":mapData.get(1).toString());
            data.setSpec(Objects.isNull(mapData.get(2))?"":mapData.get(2).toString());
            data.setLotBatchNo(Objects.isNull(mapData.get(3))?"":mapData.get(3).toString());
            data.setLength(new BigDecimal(mapData.get(4).toString()));
            data.setQtyStock(new BigDecimal(mapData.get(5).toString()));
            data.setInsulationColor(Objects.isNull(mapData.get(6))?"":mapData.get(6).toString());
            data.setOuterColor(Objects.isNull(mapData.get(7))?"":mapData.get(7).toString());
            data.setLetteringInfo(Objects.isNull(mapData.get(8))?"":mapData.get(8).toString());
            data.setDrumNo(Objects.isNull(mapData.get(9))?"":mapData.get(9).toString());
            data.setLocationNo(Objects.isNull(mapData.get(10))?"":mapData.get(10).toString());
            data.setStockSource(Objects.isNull(mapData.get(11))?"":mapData.get(11).toString());
            data.setRemark(Objects.isNull(mapData.get(12))?"":mapData.get(12).toString());
            return data;
        }
        return null;
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/mapper/IfsSplitOrderRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.inspect.mapper;
import com.ruoyi.inspect.pojo.IfsSplitOrderRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€ifs_split_order_record(ifs原材料订单拆分记录表)】的数据库操作Mapper
* @createDate 2025-09-23 11:20:20
* @Entity com.ruoyi.inspect.pojo.IfsSplitOrderRecord
*/
public interface IfsSplitOrderRecordMapper extends BaseMapper<IfsSplitOrderRecord> {
}
inspect-server/src/main/java/com/ruoyi/inspect/pojo/IfsSplitOrderRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,157 @@
package com.ruoyi.inspect.pojo;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * ifs原材料订单拆分记录表
 * @TableName ifs_split_order_record
 */
@TableName(value ="ifs_split_order_record")
@Data
public class IfsSplitOrderRecord implements Serializable {
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®id
     */
    @ApiModelProperty("主键id")
    @TableId
    private Long id;
    /**
     * é”€å”®è®¢å•号
     */
    @ApiModelProperty("销售订单号")
    private String orderNo;
    /**
     * è¡Œå·
     */
    @ApiModelProperty("行号")
    private String lineNo;
    /**
     * ä¸‹è¾¾å·
     */
    @ApiModelProperty("下达号")
    private String releaseNo;
    /**
     * æŽ¥æ”¶å·
     */
    @ApiModelProperty("接收号")
    private Integer receiptNo;
    /**
     * é›¶ä»¶å·
     */
    @ApiModelProperty("零件号")
    private String partNo;
    /**
     * ç³»ç»Ÿç¼–号
     */
    @ApiModelProperty("系统编号")
    private String systemNo;
    /**
     * è§„æ ¼
     */
    @ApiModelProperty("规格")
    private String spec;
    /**
     * é›¶ä»¶æ‰¹å·
     */
    @ApiModelProperty("零件批号")
    private String lotBatchNo;
    /**
     * åº“存数量1(用于对接mes分盘计算)
     */
    @ApiModelProperty("库存数量1(用于对接mes分盘计算)")
    private BigDecimal length;
    /**
     * åº“存数量2(ifs对于的库存数量)
     */
    @ApiModelProperty("库存数量2(ifs对于的库存数量)")
    private BigDecimal qtyStock;
    /**
     * ç»ç¼˜é¢œè‰²
     */
    @ApiModelProperty("绝缘颜色")
    private String insulationColor;
    /**
     * å¤–护颜色
     */
    @ApiModelProperty("外护颜色")
    private String outerColor;
    /**
     * å°å­—信息
     */
    @ApiModelProperty("印字信息")
    private String letteringInfo;
    /**
     * ç›˜å·
     */
    @ApiModelProperty("盘号")
    private String drumNo;
    /**
     * åº“位号
     */
    @ApiModelProperty("库位号")
    private String locationNo;
    /**
     * åº“位来源
     */
    @ApiModelProperty("库位来源")
    private String stockSource;
    /**
     * å¤‡æ³¨
     */
    @ApiModelProperty("备注")
    private String remark;
    /**
     * åŒæ­¥çŠ¶æ€ï¼ˆ0:未同步,1:已同步)
     */
    @ApiModelProperty(value = "同步状态(0:未同步,1:已同步)")
    private Integer syncStatus;
    @ApiModelProperty("创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("修改人")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty("修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
}
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java
@@ -178,7 +178,7 @@
    private Integer typeSource;
    @ApiModelProperty("原材料id")
    private Integer ifsInventoryId;
    private Long ifsInventoryId;
    @ApiModelProperty("抽查数量")
    private String testQuantity;
inspect-server/src/main/java/com/ruoyi/inspect/service/IfsSplitOrderRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.ruoyi.inspect.service;
import com.ruoyi.inspect.pojo.IfsSplitOrderRecord;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€ifs_split_order_record(ifs原材料订单拆分记录表)】的数据库操作Service
* @createDate 2025-09-23 11:20:20
*/
public interface IfsSplitOrderRecordService extends IService<IfsSplitOrderRecord> {
}
inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderPlanService.java
@@ -32,16 +32,15 @@
    int upPlanUser(Integer userId, Integer orderId,String sonLaboratory);
    int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode);
    int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode,Boolean registerInsResults);
    List<InsProduct> getInsProduct(InsOrderPlanProductDto insOrderPlanProductDto);
    List<String> checkSubmitPlan(Integer orderId, String laboratory);
    Map<String,Object> checkSubmitPlan(Integer orderId, String laboratory);
    IPage<InsOrderFile> getFileList(Page page, InsOrderFile insOrderFile);
    int uploadFile(Integer orderId, MultipartFile file);
    List<String> upPlanUser2(Integer orderId);
inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderService.java
@@ -3,6 +3,7 @@
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.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.basic.pojo.StandardProductList;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.inspect.pojo.InsOrder;
@@ -46,7 +47,7 @@
    // èŽ·å–ifs库存信息
    void getIfsOrder();
    void getIfsOrder(Map<String,Object> objectMap,Boolean isSplitOrder);
    /**
     * ä¿®æ”¹è®¢å•单号
@@ -58,7 +59,7 @@
    void updateIfsInventoryQuantity(Integer id);
    void updateIfsInventoryQuantity(Long id);
    /**
     * é“œæä¸‹å•
@@ -123,4 +124,14 @@
     * @return
     */
    Result judgeNotSpotCheckOrder(List<SampleProductDto> sampleList, InsOrder insOrder);
    /**
     * ç§»åº“操作
     * @param one
     * @return
     */
    String moveRawMaterial(IfsInventoryQuantity one);
}
inspect-server/src/main/java/com/ruoyi/inspect/service/InsReportService.java
@@ -43,16 +43,15 @@
    int upAll(MultipartFile file) throws IOException;
    void isRawMaterial(InsOrder insOrder);
    /**
     *
     * @param insOrder æ£€éªŒå•信息
     * @param registerInsResults æ˜¯å¦ç™»è®°æ£€éªŒç»“æžœ
     * @param hasExemption æ˜¯å¦å…æ£€
     */
    void isRawMaterial(InsOrder insOrder,Boolean registerInsResults,Boolean hasExemption);
    Long getUnqualifiedCount(InsOrder insOrder);
    /**
     * ç§»åº“操作
     * @param one
     * @return
     */
    String moveRawMaterial(IfsInventoryQuantity one);
    /**
     * é€€å›žåˆ°æ£€éªŒä»»åŠ¡
inspect-server/src/main/java/com/ruoyi/inspect/service/RawMaterialOrderService.java
@@ -5,11 +5,14 @@
import com.ruoyi.basic.dto.*;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.inspect.dto.OrderSplitDTO;
import com.ruoyi.inspect.dto.SampleProductDto;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.dto.CopperInsOrderDto;
import com.ruoyi.inspect.dto.RawMaterialStandardTreeDto;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.List;
@@ -39,9 +42,9 @@
     */
    IPage<IfsInventoryQuantityDto> getIfsByStateOne(IPage<IfsInventoryQuantityDto> page, IfsInventoryQuantityDto ifsInventoryQuantityDto);
    int inspectionReport(List<Integer> ids);
    int inspectionReport(List<Long> ids);
    int revokeInspectionReport(Integer id);
    int revokeInspectionReport(Long id);
    List<IfsInventoryQuantityDto> printLabel(List<Integer> ids);
@@ -54,7 +57,7 @@
     * @param ifsInventoryId
     * @return
     */
    boolean repealRawOrder(Integer ifsInventoryId);
    boolean repealRawOrder(Long ifsInventoryId);
    /**
     * æ·»åŠ å…æ£€è®¢å•
@@ -81,14 +84,14 @@
     * @param ifsInventoryId
     * @return
     */
    boolean rawOrderRelease(Integer ifsInventoryId, String partDetail);
    boolean rawOrderRelease(Long ifsInventoryId, String partDetail);
    /**
     * åŽŸææ–™ä¸‹å•é€šçŸ¥å…æ£€æˆ–è€…å¤šæ¬¡æ£€éªŒ
     * @param ifsInventoryId
     * @return
     */
    int notificationRawOrder(Integer ifsInventoryId);
    int notificationRawOrder(Long ifsInventoryId);
    /**
     * æ‰‹åŠ¨æ·»åŠ åŽŸæä¿¡æ¯
@@ -109,7 +112,7 @@
     * @param ifsInventoryId
     * @return
     */
    boolean concessionRelease(Integer ifsInventoryId);
    boolean concessionRelease(Long ifsInventoryId);
    /**
     * åŽŸææ–™è¿›åŽ‚æ’¤é”€ä¸‹å•
@@ -145,5 +148,11 @@
     * @param ifsInventoryId
     * @return
     */
    boolean advancedGodown(Integer ifsInventoryId);
    boolean advancedGodown(Long ifsInventoryId);
    void downloadTemplate(HttpServletResponse response);
    Result importSplitOrderData(MultipartFile file,Long ifsId, HttpServletRequest request);
    boolean confirmSplitOrder(OrderSplitDTO orderSplitDTO);
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/IfsSplitOrderRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.inspect.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.inspect.pojo.IfsSplitOrderRecord;
import com.ruoyi.inspect.service.IfsSplitOrderRecordService;
import com.ruoyi.inspect.mapper.IfsSplitOrderRecordMapper;
import org.springframework.stereotype.Service;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€ifs_split_order_record(ifs原材料订单拆分记录表)】的数据库操作Service实现
* @createDate 2025-09-23 11:20:20
*/
@Service
public class IfsSplitOrderRecordServiceImpl extends ServiceImpl<IfsSplitOrderRecordMapper, IfsSplitOrderRecord>
    implements IfsSplitOrderRecordService{
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -30,6 +30,7 @@
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.basic.pojo.StandardTemplate;
import com.ruoyi.basic.service.StandardTemplateService;
import com.ruoyi.basic.vo.IfsInventoryQuantityVO;
import com.ruoyi.common.constant.DictDataConstants;
import com.ruoyi.common.constant.InsOrderTypeConstants;
import com.ruoyi.common.constant.MenuJumpPathConstants;
@@ -277,7 +278,8 @@
    }
    @Override
    public List<String> checkSubmitPlan(Integer orderId, String laboratory) {
    public Map<String,Object> checkSubmitPlan(Integer orderId, String laboratory) {
        Map<String, Object> map = new HashMap<>();
        List<String> collect = new ArrayList<>();
        List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId).select(InsSample::getId));
        List<Integer> ids = insSamples.stream().map(a -> a.getId()).collect(Collectors.toList());
@@ -303,7 +305,19 @@
                return insProduct.getInspectionItem() + "-" + insProduct.getInspectionItemSubclass();
            }).collect(Collectors.toList());
        }
        return collect;
        //查询ifs拆分订单是否有已下单但是未检完的单子
        long count = 0L;
        InsOrder insOrder = insOrderMapper.selectById(orderId);
        if(Objects.nonNull(insOrder.getIfsInventoryId())){
            IfsInventoryQuantity one = ifsInventoryQuantityMapper.selectById(insOrder.getIfsInventoryId());
            //过滤出不合格或未提交的单子
            count = ifsInventoryQuantityMapper.selectSplitOrderList(one.getPartNo(),one.getLineNo(),one.getReleaseNo(),one.getReceiptNo(),one.getOrderNo())
                    .stream()
                    .filter(f->(Objects.nonNull(f.getInsOrderId()) && !Objects.equals(f.getInsOrderId(),orderId)) && (Objects.isNull(f.getInsResult()) || 0==f.getInsResult())).count();
        }
        map.put("errorMsg",collect);
        map.put("unInsOrderCount",count);
        return map;
    }
    @Override
@@ -758,7 +772,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode) {
    public int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode,Boolean registerInsResults) {
        InsOrder order = insOrderMapper.selectById(orderId);
        // 1. åˆ¤æ–­æ˜¯å¦æœ‰é‡å¤ç¼–号, æœ‰é‡å¤ç¼–号做提醒
        Long codeCount = insOrderMapper.selectCount(Wrappers.<InsOrder>lambdaQuery()
@@ -905,30 +919,30 @@
        InsSample insSample = insSampleMapper.selectOne(Wrappers.<InsSample>lambdaQuery()
                .eq(InsSample::getInsOrderId, orderId)
                .last("limit 1"));
        threadPoolTaskExecutor.execute(() -> {
            String message = "";
            message += "耐丝系统检验任务复核通知";
            message += "\n提交人: " + userName;
            message += "\n委托编号: " + order.getEntrustCode();
            message += "\n样品名称: " + insSample.getModel();
            message += "\n规格型号: " + order.getPartDetail();
            if (ifsInventoryQuantity != null) {
                message += "\n批次号: " + ifsInventoryQuantity.getUpdateBatchNo();
            }
            //发送企业微信消息通知  æäº¤å¤æ ¸
            try {
                WxCpUtils.inform(sendUserAccount, message, null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
//        threadPoolTaskExecutor.execute(() -> {
//            String message = "";
//            message += "耐丝系统检验任务复核通知";
//            message += "\n提交人: " + userName;
//            message += "\n委托编号: " + order.getEntrustCode();
//            message += "\n样品名称: " + insSample.getModel();
//            message += "\n规格型号: " + order.getPartDetail();
//            if (ifsInventoryQuantity != null) {
//                message += "\n批次号: " + ifsInventoryQuantity.getUpdateBatchNo();
//            }
//            //发送企业微信消息通知  æäº¤å¤æ ¸
//            try {
//                WxCpUtils.inform(sendUserAccount, message, null);
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        });
        // 14.ifs移库(原材料需要进行移库操作) --> æœ€åŽæ‰§è¡Œ,因为失败无法回滚
        if (ifsInventoryQuantity != null) {
            // ç™»è®°æ£€éªŒç»“æžœ
            // åˆ¤æ–­æ˜¯å¦æœ‰ä¸åˆæ ¼, æœ‰ä¸åˆæ ¼ä¸èƒ½ç§»åº“
            // todo: ifs移库
            insReportService.isRawMaterial(order);
            insReportService.isRawMaterial(order,registerInsResults,false);
            // 15 åˆ¤æ–­å½“前样品是否为原材料, åŽŸææ–™éœ€è¦è¿›è¡Œæ•°æ®åˆ†æž, åˆ¤æ–­ä¹‹å‰10条数据同一个供应商, åŒä¸€ä¸ªæ£€éªŒé¡¹çš„偏差是否超过10%
            // æŸ¥è¯¢ifs信息获取获取前10个供应商一样的, æ£€éªŒé¡¹ä¸€æ ·ä¿¡æ¯
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
@@ -547,12 +547,9 @@
     * @return
     */
    @Override
    public void getIfsOrder() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("LOCATION_NO","1302");
        map.put("STATE_DB","To be Inspected");
    public void getIfsOrder(Map<String, Object> map,Boolean isSplitOrder) {
        List<Map<String, Object>> inventory = ifsApiUtils.getInventory(JSONUtil.toJsonStr(map));
        if(inventory.size() == 0) {
        if(inventory.isEmpty()) {
            return;
        }
        // è¿›è¡Œä¿å­˜
@@ -637,6 +634,9 @@
            );
            if(count == 0) {
                ifsInventoryQuantity.setIsFirst(0);
                if(isSplitOrder){
                    ifsInventoryQuantity.setIsSplitOrder(1);
                }
                // æŸ¥è¯¢äº§ä¸šé“¾æ£€æµ‹æ•°æ®
                String industryChainAttrFields = IndustryChainUtils.getIndustryChainAttrFields(ifsInventoryQuantity.getOrderNo(),
                        ifsInventoryQuantity.getLineNo(),
@@ -719,7 +719,7 @@
     * @param id
     */
    @Transactional
    public void updateIfsInventoryQuantity(Integer id) {
    public void updateIfsInventoryQuantity(Long id) {
        ifsInventoryQuantityMapper.update(null, Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                .set(IfsInventoryQuantity::getIsRegister, 1)
                .eq(IfsInventoryQuantity::getId, id));
@@ -1146,6 +1146,170 @@
    }
    /**
     * ifs移库操作
     * @param one
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String moveRawMaterial(IfsInventoryQuantity one) {
        String toLocation;
        // ç™»è®°é‡‡è´­æ£€éªŒç»“æžœSTD
        if (one.getIsRegister().equals(0)) {
            Map<String, Object> resultMap = new HashMap<>();
            List<Map<String, Object>> resultList = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
            map.put("LINE_NO", one.getLineNo()); // è¡Œå·
            map.put("RELEASE_NO", one.getReleaseNo()); // ä¸‹è¾¾å·
            map.put("RECEIPT_NO", one.getReceiptNo()); // æŽ¥æ”¶å·
            map.put("PURCH_QTY", one.getQtyToInspect()); // è¦æ£€éªŒçš„采购数量
            resultList.add(map);
            resultMap.put("RECORD_ID", UUID.randomUUID().toString());
            resultMap.put("SYSCODE", "LIMS");
            resultMap.put("SYSMODEL", "登记采购检验结果");
            resultMap.put("BATCH_INFO", resultList);
            Result result = ifsApiUtils.getProcurementResults(JSONUtil.toJsonStr(resultMap));
            if (result.getCode() != 200) {
                throw new ErrorException("IFS登记采购检验结果失败: " + result.getMessage());
            }
            //如果是拆分订单,则将同一接受号的订单标记已登记接收
            if(one.getIsSplitOrder()==1){
                //查询其余拆分的订单
                List<IfsInventoryQuantity> quantityList = ifsInventoryQuantityMapper.selectList(Wrappers.<IfsInventoryQuantity>lambdaQuery()
                        .eq(IfsInventoryQuantity::getOrderNo, one.getOrderNo())
                        .eq(IfsInventoryQuantity::getPartNo, one.getPartNo())
                        .eq(IfsInventoryQuantity::getLineNo, one.getLineNo())
                        .eq(IfsInventoryQuantity::getReleaseNo, one.getReleaseNo())
                        .eq(IfsInventoryQuantity::getReceiptNo, one.getReceiptNo())
                        .eq(IfsInventoryQuantity::getIsSplitOrder, 1)
                );
                if(Objects.nonNull(quantityList) && !quantityList.isEmpty()){
                    //修改采购订单登记状态
                    List<Long> ids = quantityList.stream().map(IfsInventoryQuantity::getId).collect(Collectors.toList());
                    ifsInventoryQuantityMapper.update(null,Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                            .set(IfsInventoryQuantity::getIsRegister,1)
                            .in(IfsInventoryQuantity::getId, ids)
                    );
                }
            }else{
                this.updateIfsInventoryQuantity(one.getId());
            }
        }
        /**
         * TODO åŽç»­éœ€è¦è°ƒç”¨IFS的接口 ç§»å…¥çš„库位号 toLocation
         */
        // æ£€éªŒåŽç§»åº“
        toLocation = "1301";
        Map<String, Object> moveResultMap = new HashMap<>();
        List<Map<String, Object>> moveResultList = new ArrayList<>();
        Map<String, Object> moveMap = new HashMap<>();
        moveMap.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
        moveMap.put("LINE_NO", one.getLineNo());
        moveMap.put("RELEASE_NO", one.getReleaseNo());
        moveMap.put("RECEIPT_NO", one.getReceiptNo());
        moveMap.put("PART_NO", one.getPartNo());
        moveMap.put("QTY", one.getPurQtyInStore());
        moveMap.put("LOCATION_NO", one.getLocationNo());
        moveMap.put("TO_LOCATION_NO", toLocation);
        moveMap.put("LOT_BATCH_NO", one.getLotBatchNo());
        moveMap.put("SERIAL_NO", one.getSerialNo());
        moveMap.put("WAIV_DEV_REJ_NO", one.getWaivDevRejNo());
        moveMap.put("ENG_CHG_LEVEL", one.getEngChgLevel());
        moveMap.put("ACTIVITY_SEQ", one.getActivitySeq());
        moveResultList.add(moveMap);
        moveResultMap.put("RECORD_ID", UUID.randomUUID().toString());
        moveResultMap.put("SYSCODE", "LIMS");
        moveResultMap.put("SYSMODEL", "检验后移库");
        moveResultMap.put("BATCH_INFO", moveResultList);
        Result result1 = ifsApiUtils.moveReceipt(JSONUtil.toJsonStr(moveResultMap));
        // å¦‚果有必须为零件指定批号报错需要重新提交移库信息去指定批号
        if (result1.getCode() != 200) {
            String message = result1.getMessage();
            if (message.contains("必须为零件") && message.contains("指定批号")) {
                updaeBatch(one, toLocation);
            } else {
                throw new ErrorException("IFS检验后移库失败: " + result1.getMessage());
            }
        }
        return toLocation;
    }
    /**
     * å…ˆä¿®æ”¹é‡‡è´­è®¢å•批次号, åŽè¿›è¡Œç§»åº“操作
     * @param one
     * @param toLocation
     */
    private void updaeBatch(IfsInventoryQuantity one, String toLocation) {
        if (one.getIsUpdateBatch().equals(0)) {
            // å…ˆä¿®æ”¹æ‰¹æ¬¡å·åŽè¿›è¡Œç§»åº“
            Map<String, Object> resultMap = new HashMap<>();
            List<Map<String, Object>> resultList = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
            map.put("LINE_NO", one.getLineNo()); // è¡Œå·
            map.put("RELEASE_NO", one.getReleaseNo()); // ä¸‹è¾¾å·
            map.put("RECEIPT_NO", one.getReceiptNo()); // æŽ¥æ”¶å·
            map.put("PART_NO", one.getPartNo()); //零件号
            map.put("CONFIGURATION_ID", one.getConfigurationId()); // é…ç½®æ ‡è¯†
            map.put("LOCATION_NO", one.getLocationNo()); // åº“位号
            map.put("LOT_BATCH_NO", one.getLotBatchNo());// æ‰¹æ¬¡å·
            map.put("NEW_LOT_BATCH_NO", one.getUpdateBatchNo()); // ç›®æ ‡æ‰¹æ¬¡å·
            map.put("SERIAL_NO", one.getSerialNo()); // åºåˆ—号
            map.put("ENG_CHG_LEVEL", one.getEngChgLevel()); // ç‰ˆæœ¬å·
            map.put("WAIV_DEV_REJ_NO", one.getWaivDevRejNo()); // wdr号
            map.put("ACTIVITY_SEQ", one.getActivitySeq()); // æ´»åŠ¨åºå·
            map.put("QTY_TO_CHANGE", one.getQtyArrived()); // å˜æ›´æ•°é‡
            resultList.add(map);
            resultMap.put("RECORD_ID", UUID.randomUUID().toString());
            resultMap.put("SYSCODE", "LIMS");
            resultMap.put("SYSMODEL", "修改采购订单批次号");
            resultMap.put("BATCH_INFO", resultList);
            Result result = ifsApiUtils.updateMoveReceiptLot(JSONUtil.toJsonStr(resultMap));
            if (result.getCode() != 200) {
                throw new ErrorException("IFS修改批次号失败: " + result.getMessage());
            }
            ifsInventoryQuantityMapper.update(null, Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                    .set(IfsInventoryQuantity::getIsUpdateBatch, 1)
                    .eq(IfsInventoryQuantity::getId, one.getId()));
        }
        Map<String, Object> moveResultMap = new HashMap<>();
        List<Map<String, Object>> moveResultList = new ArrayList<>();
        Map<String, Object> moveMap = new HashMap<>();
        moveMap.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
        moveMap.put("LINE_NO", one.getLineNo());
        moveMap.put("RELEASE_NO", one.getReleaseNo());
        moveMap.put("RECEIPT_NO", one.getReceiptNo());
        moveMap.put("PART_NO", one.getPartNo());
        moveMap.put("QTY", one.getQtyArrived());
        moveMap.put("LOCATION_NO", one.getLocationNo());
        moveMap.put("TO_LOCATION_NO", toLocation);
        moveMap.put("LOT_BATCH_NO", one.getUpdateBatchNo());
        moveMap.put("SERIAL_NO", one.getSerialNo());
        moveMap.put("WAIV_DEV_REJ_NO", one.getWaivDevRejNo());
        moveMap.put("ENG_CHG_LEVEL", one.getEngChgLevel());
        moveMap.put("ACTIVITY_SEQ", one.getActivitySeq());
        moveResultList.add(moveMap);
        moveResultMap.put("RECORD_ID", UUID.randomUUID().toString());
        moveResultMap.put("SYSCODE", "LIMS");
        moveResultMap.put("SYSMODEL", "检验后移库");
        moveResultMap.put("BATCH_INFO", moveResultList);
        Result result1 = ifsApiUtils.moveReceipt(JSONUtil.toJsonStr(moveResultMap));
        if (result1.getCode() != 200) {
            throw new ErrorException("IFS检验后移库失败: " + result1.getMessage());
        }
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java
@@ -1,8 +1,6 @@
package com.ruoyi.inspect.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
@@ -11,7 +9,6 @@
import com.aspose.words.SaveFormat;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -25,12 +22,10 @@
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.ruoyi.basic.dto.IfsInventoryQuantitySupplierDto;
import com.ruoyi.basic.mapper.IfsInventoryQuantityMapper;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.common.constant.InsOrderTypeConstants;
import com.ruoyi.common.constant.MenuJumpPathConstants;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.config.WechatProperty;
import com.ruoyi.common.utils.*;
@@ -43,10 +38,13 @@
import com.ruoyi.inspect.service.InsOrderService;
import com.ruoyi.inspect.service.InsReportService;
import com.ruoyi.inspect.mapper.InsUnqualifiedHandlerMapper;
import com.ruoyi.basic.vo.IfsInventoryQuantityVO;
import com.ruoyi.inspect.service.RawMaterialOrderService;
import com.ruoyi.system.mapper.UserMapper;
import com.ruoyi.system.service.InformationNotificationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -116,6 +114,9 @@
    private IfsApiUtils ifsApiUtils;
    @Resource
    private InsSampleUserMapper insSampleUserMapper;
    @Autowired
    private RawMaterialOrderService rawMaterialOrderService;
    @Override
@@ -793,8 +794,10 @@
        stamp.close();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void isRawMaterial(InsOrder insOrder) {
    public void isRawMaterial(InsOrder insOrder,Boolean registerInsResults,Boolean hasExemption) {
        IfsInventoryQuantity one = ifsInventoryQuantityMapper.selectOne(new LambdaQueryWrapper<IfsInventoryQuantity>()
                .eq(IfsInventoryQuantity::getId, insOrder.getIfsInventoryId()));
        if (Objects.isNull(one)) {
@@ -808,9 +811,25 @@
        // åˆ¤æ–­æ˜¯å¦æœ‰ä¸åˆæ ¼
        Long unqualifiedCount = getUnqualifiedCount(insOrder);
        if (count.equals(0L) && unqualifiedCount.equals(0L) && one.getIsFinish().equals(0) && one.getIsSource().equals(1)) {
        if (count.equals(0L) && unqualifiedCount.equals(0L) && one.getIsFinish().equals(0) && one.getIsSource().equals(1) && registerInsResults) {
            // åŽŸææ–™ç§»åº“
            toLocation = this.moveRawMaterial(one);
            //如果是拆分的订单,则把拆分的所有批次都移库
            if(one.getIsSplitOrder()==1 && !hasExemption){
                //查询拆分订单详情
                List<IfsInventoryQuantityVO> ifsInventoryQuantityVOS = ifsInventoryQuantityMapper.selectSplitOrderList(one.getPartNo(), one.getLineNo(), one.getReleaseNo(), one.getReceiptNo(), one.getOrderNo());
                for (IfsInventoryQuantityVO vo : ifsInventoryQuantityVOS) {
                    //如果有委托单信息且合格,走登记后移库;如果没有,则走免检;不合格不做处理
                    if(Objects.isNull(vo.getInsOrderId())){
                        rawMaterialOrderService.rawOrderRelease(vo.getId(), vo.getPartDesc());
                    }else if(Objects.equals(vo.getInsOrderId(),insOrder.getId())){
                        toLocation = insOrderService.moveRawMaterial(one);
                    }else if(Objects.nonNull(vo.getInsResult()) && 1 == vo.getInsResult()){
                        toLocation = insOrderService.moveRawMaterial(one);
                    }
                }
            }else{
                toLocation = insOrderService.moveRawMaterial(one);
            }
        }
        // åˆ¤æ–­ç»“束状态修改合格状态
@@ -836,23 +855,23 @@
                        .eq(IfsInventoryQuantity::getId, insOrder.getIfsInventoryId()));
            }
            threadPoolTaskExecutor.execute(() -> {
                // ä¼ä¸šå¾®ä¿¡é€šçŸ¥
                String message = "";
                message += "检测结果提交通知";
                message += "\n批次号: " + one.getUpdateBatchNo();
                message += "\n零件号: " + one.getPartNo();
                message += "\n零件描述: " + one.getPartDesc();
                message += "\n供应商名称: " + one.getSupplierName();
                message += "\n抵达数量: " + one.getQtyArrived().stripTrailingZeros().toPlainString() + one.getBuyUnitMeas();
                // å‘送企业inspectStatus信通知
                if (inspectStatus == 1) {
                    message += "\n检测结果: åˆæ ¼";
                } else {
                    message += "\n检测结果: ä¸åˆæ ¼";
                }
                WxCpUtils.informWebHook(wechatProperty.getExaminingUrl(), message);
            });
//            threadPoolTaskExecutor.execute(() -> {
//                // ä¼ä¸šå¾®ä¿¡é€šçŸ¥
//                String message = "";
//                message += "检测结果提交通知";
//                message += "\n批次号: " + one.getUpdateBatchNo();
//                message += "\n零件号: " + one.getPartNo();
//                message += "\n零件描述: " + one.getPartDesc();
//                message += "\n供应商名称: " + one.getSupplierName();
//                message += "\n抵达数量: " + one.getQtyArrived().stripTrailingZeros().toPlainString() + one.getBuyUnitMeas();
//                // å‘送企业inspectStatus信通知
//                if (inspectStatus == 1) {
//                    message += "\n检测结果: åˆæ ¼";
//                } else {
//                    message += "\n检测结果: ä¸åˆæ ¼";
//                }
//                WxCpUtils.informWebHook(wechatProperty.getExaminingUrl(), message);
//            });
        }
@@ -895,75 +914,6 @@
            }
        }
        return unqualifiedCount;
    }
    /**
     * ifs移库操作
     * @param one
     * @return
     */
    @Override
    public String moveRawMaterial(IfsInventoryQuantity one) {
        String toLocation;
        // ç™»è®°é‡‡è´­æ£€éªŒç»“æžœSTD
        if (one.getIsRegister().equals(0)) {
            Map<String, Object> resultMap = new HashMap<>();
            List<Map<String, Object>> resultList = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
            map.put("LINE_NO", one.getLineNo()); // è¡Œå·
            map.put("RELEASE_NO", one.getReleaseNo()); // ä¸‹è¾¾å·
            map.put("RECEIPT_NO", one.getReceiptNo()); // æŽ¥æ”¶å·
            map.put("PURCH_QTY", one.getQtyToInspect()); // è¦æ£€éªŒçš„采购数量
            resultList.add(map);
            resultMap.put("RECORD_ID", UUID.randomUUID().toString());
            resultMap.put("SYSCODE", "LIMS");
            resultMap.put("SYSMODEL", "登记采购检验结果");
            resultMap.put("BATCH_INFO", resultList);
            Result result = ifsApiUtils.getProcurementResults(JSONUtil.toJsonStr(resultMap));
            if (result.getCode() != 200) {
                throw new ErrorException("IFS登记采购检验结果失败: " + result.getMessage());
            }
        }
        insOrderService.updateIfsInventoryQuantity(one.getId());
        /**
         * TODO åŽç»­éœ€è¦è°ƒç”¨IFS的接口 ç§»å…¥çš„库位号 toLocation
         */
        // æ£€éªŒåŽç§»åº“
        toLocation = "1301";
        Map<String, Object> moveResultMap = new HashMap<>();
        List<Map<String, Object>> moveResultList = new ArrayList<>();
        Map<String, Object> moveMap = new HashMap<>();
        moveMap.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
        moveMap.put("LINE_NO", one.getLineNo());
        moveMap.put("RELEASE_NO", one.getReleaseNo());
        moveMap.put("RECEIPT_NO", one.getReceiptNo());
        moveMap.put("PART_NO", one.getPartNo());
        moveMap.put("QTY", one.getQtyArrived());
        moveMap.put("LOCATION_NO", one.getLocationNo());
        moveMap.put("TO_LOCATION_NO", toLocation);
        moveMap.put("LOT_BATCH_NO", one.getLotBatchNo());
        moveMap.put("SERIAL_NO", one.getSerialNo());
        moveMap.put("WAIV_DEV_REJ_NO", one.getWaivDevRejNo());
        moveMap.put("ENG_CHG_LEVEL", one.getEngChgLevel());
        moveMap.put("ACTIVITY_SEQ", one.getActivitySeq());
        moveResultList.add(moveMap);
        moveResultMap.put("RECORD_ID", UUID.randomUUID().toString());
        moveResultMap.put("SYSCODE", "LIMS");
        moveResultMap.put("SYSMODEL", "检验后移库");
        moveResultMap.put("BATCH_INFO", moveResultList);
        Result result1 = ifsApiUtils.moveReceipt(JSONUtil.toJsonStr(moveResultMap));
        // å¦‚果有必须为零件指定批号报错需要重新提交移库信息去指定批号
        if (result1.getCode() != 200) {
            String message = result1.getMessage();
            if (message.contains("必须为零件") && message.contains("指定批号")) {
                updaeBatch(one, toLocation);
            } else {
                throw new ErrorException("IFS检验后移库失败: " + result1.getMessage());
            }
        }
        return toLocation;
    }
    /**
@@ -1035,77 +985,6 @@
            throw new RuntimeException("导出失败");
        }
    }
    /**
     * å…ˆä¿®æ”¹é‡‡è´­è®¢å•批次号, åŽè¿›è¡Œç§»åº“操作
     * @param one
     * @param toLocation
     */
    private void updaeBatch(IfsInventoryQuantity one, String toLocation) {
        if (one.getIsUpdateBatch().equals(0)) {
            // å…ˆä¿®æ”¹æ‰¹æ¬¡å·åŽè¿›è¡Œç§»åº“
            Map<String, Object> resultMap = new HashMap<>();
            List<Map<String, Object>> resultList = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
            map.put("LINE_NO", one.getLineNo()); // è¡Œå·
            map.put("RELEASE_NO", one.getReleaseNo()); // ä¸‹è¾¾å·
            map.put("RECEIPT_NO", one.getReceiptNo()); // æŽ¥æ”¶å·
            map.put("PART_NO", one.getPartNo()); //零件号
            map.put("CONFIGURATION_ID", one.getConfigurationId()); // é…ç½®æ ‡è¯†
            map.put("LOCATION_NO", one.getLocationNo()); // åº“位号
            map.put("LOT_BATCH_NO", one.getLotBatchNo());// æ‰¹æ¬¡å·
            map.put("NEW_LOT_BATCH_NO", one.getUpdateBatchNo()); // ç›®æ ‡æ‰¹æ¬¡å·
            map.put("SERIAL_NO", one.getSerialNo()); // åºåˆ—号
            map.put("ENG_CHG_LEVEL", one.getEngChgLevel()); // ç‰ˆæœ¬å·
            map.put("WAIV_DEV_REJ_NO", one.getWaivDevRejNo()); // wdr号
            map.put("ACTIVITY_SEQ", one.getActivitySeq()); // æ´»åŠ¨åºå·
            map.put("QTY_TO_CHANGE", one.getQtyArrived()); // å˜æ›´æ•°é‡
            resultList.add(map);
            resultMap.put("RECORD_ID", UUID.randomUUID().toString());
            resultMap.put("SYSCODE", "LIMS");
            resultMap.put("SYSMODEL", "修改采购订单批次号");
            resultMap.put("BATCH_INFO", resultList);
            Result result = ifsApiUtils.updateMoveReceiptLot(JSONUtil.toJsonStr(resultMap));
            if (result.getCode() != 200) {
                throw new ErrorException("IFS修改批次号失败: " + result.getMessage());
            }
            ifsInventoryQuantityMapper.update(null, Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                    .set(IfsInventoryQuantity::getIsUpdateBatch, 1)
                    .eq(IfsInventoryQuantity::getId, one.getId()));
        }
        Map<String, Object> moveResultMap = new HashMap<>();
        List<Map<String, Object>> moveResultList = new ArrayList<>();
        Map<String, Object> moveMap = new HashMap<>();
        moveMap.put("ORDER_NO", one.getOrderNo()); // é‡‡è´­è®¢å•号
        moveMap.put("LINE_NO", one.getLineNo());
        moveMap.put("RELEASE_NO", one.getReleaseNo());
        moveMap.put("RECEIPT_NO", one.getReceiptNo());
        moveMap.put("PART_NO", one.getPartNo());
        moveMap.put("QTY", one.getQtyArrived());
        moveMap.put("LOCATION_NO", one.getLocationNo());
        moveMap.put("TO_LOCATION_NO", toLocation);
        moveMap.put("LOT_BATCH_NO", one.getUpdateBatchNo());
        moveMap.put("SERIAL_NO", one.getSerialNo());
        moveMap.put("WAIV_DEV_REJ_NO", one.getWaivDevRejNo());
        moveMap.put("ENG_CHG_LEVEL", one.getEngChgLevel());
        moveMap.put("ACTIVITY_SEQ", one.getActivitySeq());
        moveResultList.add(moveMap);
        moveResultMap.put("RECORD_ID", UUID.randomUUID().toString());
        moveResultMap.put("SYSCODE", "LIMS");
        moveResultMap.put("SYSMODEL", "检验后移库");
        moveResultMap.put("BATCH_INFO", moveResultList);
        Result result1 = ifsApiUtils.moveReceipt(JSONUtil.toJsonStr(moveResultMap));
        if (result1.getCode() != 200) {
            throw new ErrorException("IFS检验后移库失败: " + result1.getMessage());
        }
    }
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/RawMaterialOrderServiceImpl.java
@@ -1,14 +1,18 @@
package com.ruoyi.inspect.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
@@ -25,16 +29,23 @@
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.WxCpUtils;
import com.ruoyi.common.utils.api.IfsApiUtils;
import com.ruoyi.common.utils.api.MesApiUtils;
import com.ruoyi.inspect.dto.CopperInsOrderDto;
import com.ruoyi.inspect.dto.OrderSplitDTO;
import com.ruoyi.inspect.dto.RawMaterialStandardTreeDto;
import com.ruoyi.basic.mapper.IfsInventoryQuantityMapper;
import com.ruoyi.basic.mapper.StandardTreeMapper;
import com.ruoyi.inspect.dto.SampleProductDto;
import com.ruoyi.inspect.excel.OrderSplitExcelData;
import com.ruoyi.inspect.excel.OrderSplitExcelListener;
import com.ruoyi.inspect.mapper.InsOrderMapper;
import com.ruoyi.inspect.mapper.InsProductMapper;
import com.ruoyi.inspect.mapper.InsSampleMapper;
import com.ruoyi.inspect.pojo.IfsSplitOrderRecord;
import com.ruoyi.inspect.pojo.InsOrder;
import com.ruoyi.inspect.pojo.InsReport;
import com.ruoyi.inspect.service.IfsSplitOrderRecordService;
import com.ruoyi.inspect.service.InsOrderService;
import com.ruoyi.inspect.service.InsReportService;
import com.ruoyi.inspect.service.RawMaterialOrderService;
@@ -46,18 +57,24 @@
import lombok.AllArgsConstructor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
 * @Author zhuo
@@ -79,6 +96,10 @@
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    private InsProductMapper insProductMapper;
    private AuxiliaryOutputWorkingHoursMapper auxiliaryOutputWorkingHoursMapper;
    private IfsApiUtils ifsApiUtils;
    private IfsSplitOrderRecordService ifsSplitOrderRecordService;
    @Override
@@ -142,7 +163,7 @@
     * @return
     */
    @Override
    public int inspectionReport(List<Integer> ids) {
    public int inspectionReport(List<Long> ids) {
        Integer userId = SecurityUtils.getUserId().intValue();
        ifsInventoryQuantityMapper.update(null, Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                .in(IfsInventoryQuantity::getId, ids)
@@ -151,31 +172,31 @@
                .set(IfsInventoryQuantity::getIsInspect, 1)
                .set(IfsInventoryQuantity::getDeclareDate, LocalDateTime.now())
        );
        threadPoolTaskExecutor.execute(() -> {
            List<IfsInventoryQuantity> quantityList = ifsInventoryQuantityMapper.selectList(Wrappers.<IfsInventoryQuantity>lambdaQuery()
                    .in(IfsInventoryQuantity::getId, ids));
            // ä¼ä¸šå¾®ä¿¡é€šçŸ¥
            String message = "";
            message += "新增报检通知";
            for (IfsInventoryQuantity inventoryQuantity : quantityList) {
                message += "\n批次号: " + inventoryQuantity.getUpdateBatchNo();
                message += "\n零件描述: " + inventoryQuantity.getPartDesc();
                message += "\n抵达数量: " + inventoryQuantity.getQtyArrived().stripTrailingZeros().toPlainString() + inventoryQuantity.getBuyUnitMeas();
                // åˆ¤æ–­æœ‰æ²¡æœ‰åˆ°20吨. æˆ–者能否免检
                int result = notificationRawOrder(inventoryQuantity.getId());
                switch (result) {
                    case 1:
                        message += "\n当前样品已检验过, å¯ä»¥å…æ£€";
                        break;
                    case 2:
                        message += "\n当前样品已超过20吨";
                        break;
                }
                message += "\n";
            }
            WxCpUtils.informWebHook(wechatProperty.getExaminingUrl(), message);
        });
//        threadPoolTaskExecutor.execute(() -> {
//            List<IfsInventoryQuantity> quantityList = ifsInventoryQuantityMapper.selectList(Wrappers.<IfsInventoryQuantity>lambdaQuery()
//                    .in(IfsInventoryQuantity::getId, ids));
//            // ä¼ä¸šå¾®ä¿¡é€šçŸ¥
//            String message = "";
//            message += "新增报检通知";
//            for (IfsInventoryQuantity inventoryQuantity : quantityList) {
//                message += "\n批次号: " + inventoryQuantity.getUpdateBatchNo();
//                message += "\n零件描述: " + inventoryQuantity.getPartDesc();
//                message += "\n抵达数量: " + inventoryQuantity.getQtyArrived().stripTrailingZeros().toPlainString() + inventoryQuantity.getBuyUnitMeas();
//
//                // åˆ¤æ–­æœ‰æ²¡æœ‰åˆ°20吨. æˆ–者能否免检
//                int result = notificationRawOrder(inventoryQuantity.getId());
//                switch (result) {
//                    case 1:
//                        message += "\n当前样品已检验过, å¯ä»¥å…æ£€";
//                        break;
//                    case 2:
//                        message += "\n当前样品已超过20吨";
//                        break;
//                }
//                message += "\n";
//            }
//            WxCpUtils.informWebHook(wechatProperty.getExaminingUrl(), message);
//        });
        return 1;
    }
@@ -185,7 +206,7 @@
     * @return
     */
    @Override
    public int revokeInspectionReport(Integer id) {
    public int revokeInspectionReport(Long id) {
        return ifsInventoryQuantityMapper.update(null, Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                .eq(IfsInventoryQuantity::getId, id)
                .set(IfsInventoryQuantity::getIsInspect, 0)
@@ -248,7 +269,7 @@
     * @return
     */
    @Override
    public boolean repealRawOrder(Integer ifsInventoryId) {
    public boolean repealRawOrder(Long ifsInventoryId) {
        // æŸ¥è¯¢åˆ¤æ–­æ˜¯å¦æ˜¯é“œå•丝
        IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(ifsInventoryId);
        if (ifsInventoryQuantity.getIsCopper() != null && ifsInventoryQuantity.getIsCopper().equals(1)) {
@@ -338,7 +359,7 @@
        addAuxiliary(insOrder, ifsInventoryQuantity);
        // todo: ifs直接移库
        insReportService.isRawMaterial(insOrder);
        insReportService.isRawMaterial(insOrder,true,true);
        return insOrder.getId();
    }
@@ -390,7 +411,7 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rawOrderRelease(Integer ifsInventoryId, String partDetail) {
    public boolean rawOrderRelease(Long ifsInventoryId, String partDetail) {
        // ä¿®æ”¹åŽŸææ–™æ•°æ®ç›´æŽ¥ä¸ºå·²æ£€éªŒ
        ifsInventoryQuantityMapper.update(null, new LambdaUpdateWrapper<IfsInventoryQuantity>()
                .set(IfsInventoryQuantity::getState, 2)
@@ -432,7 +453,7 @@
        addAuxiliary(insOrder, ifsInventoryQuantity);
        // todo: ifs直接移库
        insReportService.isRawMaterial(insOrder);
        insReportService.isRawMaterial(insOrder,true,true);
        return true;
    }
@@ -444,7 +465,7 @@
     * @return
     */
    @Override
    public int notificationRawOrder(Integer ifsInventoryId) {
    public int notificationRawOrder(Long ifsInventoryId) {
        IfsInventoryQuantity ifsInventory = ifsInventoryQuantityMapper.selectById(ifsInventoryId);
        // æŸ¥è¯¢å½“前批次, ä¾›åº”商, é›¶ä»¶å·çš„原材料是否超过了20吨, è¶…过了20吨需要进行多次检验提醒
        List<IfsInventoryQuantity> quantityList = ifsInventoryQuantityMapper.selectList(Wrappers.<IfsInventoryQuantity>lambdaQuery()
@@ -570,7 +591,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean concessionRelease(Integer ifsInventoryId) {
    public boolean concessionRelease(Long ifsInventoryId) {
        // æŸ¥è¯¢åŽŸææ–™ä¿¡æ¯
        IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(ifsInventoryId);
        if (!ifsInventoryQuantity.getInspectStatus().equals(2)) {
@@ -578,7 +599,7 @@
        }
        // todo:需要判断oa流程是否是让步放行
        String toLocation = insReportService.moveRawMaterial(ifsInventoryQuantity);
        String toLocation = insOrderService.moveRawMaterial(ifsInventoryQuantity);
        ifsInventoryQuantityMapper.update(null, new LambdaUpdateWrapper<IfsInventoryQuantity>()
                .set(IfsInventoryQuantity::getInspectStatus, 4)
@@ -759,7 +780,7 @@
     * @return
     */
    @Override
    public boolean advancedGodown(Integer ifsInventoryId) {
    public boolean advancedGodown(Long ifsInventoryId) {
        // æŸ¥è¯¢åŽŸææ–™ä¿¡æ¯
        IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(ifsInventoryId);
        if (!ifsInventoryQuantity.getInspectStatus().equals(0)
@@ -768,7 +789,7 @@
        }
        // todo:需要判断oa流程是否是让步放行
        String toLocation = insReportService.moveRawMaterial(ifsInventoryQuantity);
        String toLocation = insOrderService.moveRawMaterial(ifsInventoryQuantity);
        ifsInventoryQuantityMapper.update(null, new LambdaUpdateWrapper<IfsInventoryQuantity>()
                .set(IfsInventoryQuantity::getInspectStatus, 1)
@@ -779,6 +800,145 @@
        return true;
    }
    @Override
    public void downloadTemplate(HttpServletResponse response) {
        response.reset();
        try{
            String fileName = "订单拆分导入模板" + ExcelTypeEnum.XLSX.getValue();
            fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            //订单拆分导入模板文件
            InputStream inputStream = this.getClass().getResourceAsStream("/static/split_order_import_template.xlsx");
            IoUtil.copy(inputStream,response.getOutputStream());
            inputStream.close();
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("模板下载失败");
        }
    }
    @Override
    public Result importSplitOrderData(MultipartFile file,Long ifsId, HttpServletRequest request) {
        try {
            IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(ifsId);
            OrderSplitExcelListener listener = new OrderSplitExcelListener(ifsInventoryQuantity);
            EasyExcel.read(file.getInputStream(), listener).sheet().headRowNumber(2).doRead();
            if(StringUtils.isNotBlank(listener.errorMsg)){
                return Result.fail(201,listener.errorMsg);
            }
            return Result.success(listener.getDataList());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("导入失败:"+e.getMessage());
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public boolean confirmSplitOrder(OrderSplitDTO orderSplitDTO) {
        //1.查询ifs订单信息
        IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(orderSplitDTO.getIfsId());
        if(Objects.isNull(ifsInventoryQuantity)){
            throw new RuntimeException("未查询到该IFS订单信息");
        }
        //2.对接ifs采购接收更改批号接口
        //组装请求参数inAttr
        List<String> newLotBathNo = new ArrayList<>();//新批号列表
        Map<String,Object> inAttrMap = new HashMap<>();
        inAttrMap.put("RECORD_ID",UUID.randomUUID().toString());
        inAttrMap.put("SYSCODE","LIMS_NS");
        inAttrMap.put("SYSMODEL","耐丝LIMS订单拆分");
        List<Map<String,Object>> batchInfoData = new ArrayList<>();
        if(Objects.nonNull(orderSplitDTO.getSplitDetailList()) && !orderSplitDTO.getSplitDetailList().isEmpty()){
            for (OrderSplitExcelData data : orderSplitDTO.getSplitDetailList()) {
                Map<String, Object> infoMap = new HashMap<>();
                infoMap.put("ORDER_NO",ifsInventoryQuantity.getOrderNo());
                infoMap.put("LINE_NO",ifsInventoryQuantity.getLineNo());
                infoMap.put("RELEASE_NO",ifsInventoryQuantity.getReleaseNo());
                infoMap.put("RECEIPT_NO",ifsInventoryQuantity.getReceiptNo());
                infoMap.put("PART_NO",ifsInventoryQuantity.getPartNo());
                infoMap.put("CONFIGURATION_ID",ifsInventoryQuantity.getConfigurationId());
                infoMap.put("LOCATION_NO",ifsInventoryQuantity.getLocationNo());
                infoMap.put("LOT_BATCH_NO",ifsInventoryQuantity.getLotBatchNo());
                infoMap.put("NEW_LOT_BATCH_NO",data.getLotBatchNo());
                newLotBathNo.add(data.getLotBatchNo());
                infoMap.put("SERIAL_NO",ifsInventoryQuantity.getSerialNo());
                infoMap.put("ENG_CHG_LEVEL",ifsInventoryQuantity.getEngChgLevel());
                infoMap.put("WAIV_DEV_REJ_NO",ifsInventoryQuantity.getWaivDevRejNo());
                infoMap.put("ACTIVITY_SEQ",ifsInventoryQuantity.getActivitySeq());
                infoMap.put("QTY_TO_CHANGE",data.getQtyStock());
                batchInfoData.add(infoMap);
            }
        }
        inAttrMap.put("BATCH_INFO", batchInfoData);
        String inAttr = JSONObject.toJSONString(inAttrMap);
        //调用ifs接口
        Result result = ifsApiUtils.updateMoveReceiptLot(inAttr);
        if(result.getCode()!=200){
            throw new RuntimeException("IFS采购接收更改批号请求异常:"+result.getMessage());
        }
        //更新主订单的抵达采购数量
        BigDecimal purQtyInStore = orderSplitDTO.getSplitDetailList()
                .stream()
                .map(OrderSplitExcelData::getQtyStock)
                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        BigDecimal newPurQtyInStore = ifsInventoryQuantity.getPurQtyInStore().subtract(purQtyInStore);
        //如果拆分后,剩余的库存数量为0,则删除批号为*的订单信息
        if(newPurQtyInStore.compareTo(BigDecimal.ZERO)==0){
            ifsInventoryQuantityMapper.deleteById(ifsInventoryQuantity.getId());
        }else{
            ifsInventoryQuantityMapper.update(null,Wrappers.<IfsInventoryQuantity>lambdaUpdate()
                    .set(IfsInventoryQuantity::getPurQtyInStore,newPurQtyInStore)
                    .set(IfsInventoryQuantity::getInvQtyInStore,newPurQtyInStore)
                    .eq(IfsInventoryQuantity::getId,ifsInventoryQuantity.getId())
            );
        }
        //ifs更改批号接口调用成功,拉取新拆分的ifs订单并报检
        Map<String, Object> map = new HashMap<>();
        map.put("LOCATION_NO","1302");
        map.put("STATE_DB","To be Inspected");
        map.put("PART_NO",ifsInventoryQuantity.getPartNo());
        map.put("ORDER_NO",ifsInventoryQuantity.getOrderNo());
        map.put("LINE_NO",ifsInventoryQuantity.getLineNo());
        map.put("RELEASE_NO",ifsInventoryQuantity.getReleaseNo());
        map.put("RECEIPT_NO",ifsInventoryQuantity.getReceiptNo());
        map.put("LOT_BATCH_NO",String.join(";",newLotBathNo));
        insOrderService.getIfsOrder(map,true);
        //查询新拆分的订单信息
        List<IfsInventoryQuantity> splitOrderList = ifsInventoryQuantityMapper.selectList(Wrappers.<IfsInventoryQuantity>lambdaQuery()
                .eq(IfsInventoryQuantity::getLocationNo, "1302")
                .eq(IfsInventoryQuantity::getStatusDb, "To be Inspected")
                .eq(IfsInventoryQuantity::getPartNo, ifsInventoryQuantity.getPartNo())
                .eq(IfsInventoryQuantity::getOrderNo, ifsInventoryQuantity.getOrderNo())
                .eq(IfsInventoryQuantity::getLineNo, ifsInventoryQuantity.getLineNo())
                .eq(IfsInventoryQuantity::getReleaseNo, ifsInventoryQuantity.getReleaseNo())
                .eq(IfsInventoryQuantity::getReceiptNo, ifsInventoryQuantity.getReceiptNo())
                .in(IfsInventoryQuantity::getLotBatchNo, newLotBathNo)
        );
        //执行报检操作
        if(Objects.nonNull(splitOrderList) && !splitOrderList.isEmpty()){
            List<Long> ids = splitOrderList.stream().map(IfsInventoryQuantity::getId).collect(Collectors.toList());
            ids.add(ifsInventoryQuantity.getId());
            this.inspectionReport(ids);
        }
        //勾选同步到MES,保存订单拆分记录
        if(orderSplitDTO.getPushToMes()){
            List<IfsSplitOrderRecord> collect = orderSplitDTO.getSplitDetailList().stream().map(m -> {
                IfsSplitOrderRecord record = new IfsSplitOrderRecord();
                BeanUtil.copyProperties(m, record);
                record.setOrderNo(ifsInventoryQuantity.getOrderNo());
                record.setLineNo(ifsInventoryQuantity.getLineNo());
                record.setReleaseNo(ifsInventoryQuantity.getReleaseNo());
                record.setReceiptNo(ifsInventoryQuantity.getReceiptNo());
                return record;
            }).collect(Collectors.toList());
            return ifsSplitOrderRecordService.saveBatch(collect);
        }
        return false;
    }
    /**
     * æ·»åŠ å·¥æ—¶
inspect-server/src/main/java/com/ruoyi/inspect/task/RawMaterIalSchedule.java
@@ -5,6 +5,8 @@
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
 * @Author zhuo
@@ -21,6 +23,9 @@
     */
    @Scheduled(fixedDelay = 1200000)
    public void getIfsOrderTiming() {
        insOrderService.getIfsOrder();
        Map<String, Object> map = new HashMap<>();
        map.put("LOCATION_NO","1302");
        map.put("STATE_DB","To be Inspected");
        insOrderService.getIfsOrder(map,false);
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderPlanVO.java
@@ -75,4 +75,7 @@
    @ApiModelProperty("报告id")
    private Integer insReportId;
    @ApiModelProperty(value = "是否为拆分订单(0:否 1:是)")
    private Integer isSplitOrder;
}
inspect-server/src/main/resources/mapper/IfsSplitOrderRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
<?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.IfsSplitOrderRecordMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.inspect.pojo.IfsSplitOrderRecord">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="orderNo" column="order_no" jdbcType="VARCHAR"/>
            <result property="lineNo" column="line_no" jdbcType="VARCHAR"/>
            <result property="releaseNo" column="release_no" jdbcType="VARCHAR"/>
            <result property="receiptNo" column="receipt_no" jdbcType="VARCHAR"/>
            <result property="partNo" column="part_no" jdbcType="VARCHAR"/>
            <result property="systemNo" column="system_no" jdbcType="VARCHAR"/>
            <result property="spec" column="spec" jdbcType="VARCHAR"/>
            <result property="lotBatchNo" column="lot_batch_no" jdbcType="VARCHAR"/>
            <result property="length" column="length" jdbcType="DECIMAL"/>
            <result property="qtyStock" column="qty_stock" jdbcType="DECIMAL"/>
            <result property="insulationColor" column="insulation_color" jdbcType="VARCHAR"/>
            <result property="outerColor" column="outer_color" jdbcType="VARCHAR"/>
            <result property="letteringInfo" column="lettering_info" jdbcType="VARCHAR"/>
            <result property="drumNo" column="drum_no" jdbcType="VARCHAR"/>
            <result property="locationNo" column="location_no" jdbcType="VARCHAR"/>
            <result property="stockSource" column="stock_source" jdbcType="VARCHAR"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
            <result property="syncStatus" column="sync_status" jdbcType="TINYINT"/>
            <result property="createUser" column="create_user" jdbcType="INTEGER"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateUser" column="update_user" jdbcType="INTEGER"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,order_no,line_no,release_no,receipt_no,part_no,
        system_no,spec,lot_batch_no,`length`,
        qty_stock,insulation_color,outer_color,
        lettering_info,drum_no,location_no,
        stock_source,remark,sync_status,create_user,create_time,
        update_user,update_time
    </sql>
</mapper>
inspect-server/src/main/resources/mapper/InsSampleMapper.xml
@@ -192,7 +192,8 @@
        ira.url,
        ira.url_s,
        ira.temp_url_pdf,
        iiq.is_copper
        iiq.is_copper,
        iiq.is_split_order
        FROM
        ins_order io
        LEFT JOIN ins_sample isa ON isa.ins_order_id = io.id
inspect-server/src/main/resources/static/split_order_import_template.xlsx
Binary files differ
ruoyi-common/src/main/java/com/ruoyi/common/utils/api/MesApiUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
package com.ruoyi.common.utils.api;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class MesApiUtils {
    @Value("${mes.ztzb.ip}")
    String ip;
    @Value("${mes.ztzb.user}")
    String user;
    @Value("${mes.ztzb.password}")
    String password;
    /**
     * èŽ·å–token请求链接
     * @return
     */
    private String getAuthTokenUrl() {
        return ip + "/auth/oauth/token?randomStr=blockPuzzle&grant_type=password";
    }
    /**
     * æ–°å¢žå®žæ—¶åº“存请求链接
     * @return
     */
    private String getBatchAddStockUrl(){
        return ip + "/mes/stock/batchAddStock";
    }
    /**
     * èŽ·å–mes系统token
     * @return æŽ¥å£å“åº”结果
     */
    public String getToken(){
        try{
            Map<String,Object> bodyMap = new HashMap<>();
            bodyMap.put("username",user);
            String bodyStr = "username="+user+"&password="+password;
            String response = HttpRequest.post(getAuthTokenUrl())
                    .header("Authorization", "Basic cGlnOnBpZw==")
                    .header("Content-Type", "application/x-www-form-urlencoded")
                    .body(bodyStr,"application/x-www-form-urlencoded").execute().body();
            JSONObject responseObj = JSONUtil.parseObj(response);
            if(Objects.nonNull(responseObj.getStr("access_token"))){
                return "Bearer " + responseObj.getStr("access_token");
            }else{
                throw new RuntimeException(responseObj.getStr("msg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("获取MES系统token接口异常:"+e.getMessage());
        }
    }
    /**
     * mes新增实时库存接口
     * @param requestJsonStr è¯·æ±‚参数json字符串
     * @return æŽ¥å£å“åº”结果
     */
    public boolean batchAddStock(String requestJsonStr){
        try{
            String response = HttpRequest.post(getBatchAddStockUrl())
                    .header("Authorization", getToken())
                    .header("Content-Type", "application/json")
                    .body(requestJsonStr)
                    .execute()
                    .body();
            JSONObject entries = JSONUtil.parseObj(response);
            if(entries.getInt("code")==0){
                return true;
            }else{
                throw new RuntimeException("同步到MES失败:"+entries.getStr("msg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("同步MES实时库存接口异常:"+e.getMessage());
        }
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/ParameterEscaperUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.common.utils.http;
import java.util.HashMap;
import java.util.Map;
/**
 * è¯·æ±‚参数特殊字符转义工具类
 * ç”¨äºŽå¤„理HTTP请求参数中的特殊字符,防止XSS攻击和参数解析错误
 */
public class ParameterEscaperUtil {
    // ç‰¹æ®Šå­—符转义映射表
    private static final Map<Character, String> ESCAPE_MAP;
    // è½¬ä¹‰å­—符反转映射表
    private static final Map<String, Character> UNESCAPE_MAP;
    static {
        // åˆå§‹åŒ–转义映射
        ESCAPE_MAP = new HashMap<>();
        ESCAPE_MAP.put('&', "&amp;");
        ESCAPE_MAP.put('<', "&lt;");
        ESCAPE_MAP.put('>', "&gt;");
        ESCAPE_MAP.put('"', "&quot;");
        ESCAPE_MAP.put('\'', "&#39;");
        ESCAPE_MAP.put('/', "&#47;");
        ESCAPE_MAP.put('\\', "&#92;");
        ESCAPE_MAP.put(' ', "%20");
        ESCAPE_MAP.put('?', "%3F");
        ESCAPE_MAP.put('=', "%3D");
        ESCAPE_MAP.put('+', "%2B");
        ESCAPE_MAP.put('%', "%25");
        ESCAPE_MAP.put('#', "%23");
        ESCAPE_MAP.put(':', "%3A");
        ESCAPE_MAP.put(';', "%3B");
        // åˆå§‹åŒ–反转义映射
        UNESCAPE_MAP = new HashMap<>();
        for (Map.Entry<Character, String> entry : ESCAPE_MAP.entrySet()) {
            UNESCAPE_MAP.put(entry.getValue(), entry.getKey());
        }
    }
    /**
     * è½¬ä¹‰è¯·æ±‚参数中的特殊字符
     * @param input åŽŸå§‹è¾“å…¥å­—ç¬¦ä¸²
     * @return è½¬ä¹‰åŽçš„字符串
     */
    public static String escape(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            // å¦‚果是需要转义的字符,则使用转义后的字符串,否则直接添加
            String escaped = ESCAPE_MAP.get(c);
            sb.append(escaped != null ? escaped : c);
        }
        return sb.toString();
    }
    /**
     * åè½¬ä¹‰è¯·æ±‚参数中的特殊字符
     * @param input è½¬ä¹‰åŽçš„字符串
     * @return åŽŸå§‹å­—ç¬¦ä¸²
     */
    public static String unescape(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        StringBuilder sb = new StringBuilder();
        int i = 0;
        while (i < input.length()) {
            boolean found = false;
            // æ£€æŸ¥æ˜¯å¦æ˜¯è½¬ä¹‰åºåˆ—
            for (String escapeSeq : UNESCAPE_MAP.keySet()) {
                if (input.startsWith(escapeSeq, i)) {
                    sb.append(UNESCAPE_MAP.get(escapeSeq));
                    i += escapeSeq.length();
                    found = true;
                    break;
                }
            }
            if (!found) {
                sb.append(input.charAt(i));
                i++;
            }
        }
        return sb.toString();
    }
}