Bladeren bron

aps-车间作业跟踪导入

sucheng 3 maanden geleden
bovenliggende
commit
5b84f92f90

+ 2 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/dao/ApsProcessOperationProcessEquDao.java

@@ -141,6 +141,8 @@ public interface ApsProcessOperationProcessEquDao extends BaseMapper<ApsProcessO
     void myUpdateConflictdes(@Param("apsProcessOperationProcessEquDo") ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo);
 
     void updateProcessPlanTimeByProcessIds(@Param("processIdList") Set<String> processIdList);
+
+    List<ApsProcessOperationProcessEquDoAndWidthVo> getAllWaitDoList();
 }
 
 

+ 32 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/listener/WorkShopImportListener.java

@@ -0,0 +1,32 @@
+package com.rongwei.bscommon.sys.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.rongwei.bsentity.vo.WorkShopExportVo;
+import com.rongwei.rwcommon.base.exception.CustomException;
+import com.rongwei.rwcommon.utils.StringUtils;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author :sc
+ * @since :2025/4/18
+ */
+@Getter
+public class WorkShopImportListener extends AnalysisEventListener<WorkShopExportVo> {
+    private final List<String> errorMessages = new ArrayList<>();
+    private final List<WorkShopExportVo> resData = new ArrayList<>();
+
+    @Override
+    public void invoke(WorkShopExportVo data, AnalysisContext context) {
+        resData.add(data);
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+
+    }
+
+}

+ 3 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/ApsProcessOperationProcessEquService.java

@@ -6,6 +6,7 @@ import com.rongwei.bsentity.domain.ApsProcessOperationProcessEquDo;
 import com.rongwei.bsentity.vo.*;
 import com.rongwei.rwcommon.base.R;
 import com.rongwei.rwcommon.vo.CriteriaQuery;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -55,4 +56,6 @@ public interface ApsProcessOperationProcessEquService extends IService<ApsProces
     List<String> updateDetails2(JobDetailsVo jobDetailsVo);
 
     void workShopExport(CriteriaQuery query, HttpServletResponse response) throws IOException;
+
+    R workShopImport(MultipartFile multipartFile, HttpServletResponse response) throws IOException;
 }

+ 235 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsProcessOperationProcessEquServiceImpl.java

@@ -17,6 +17,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Maps;
 import com.rongwei.bscommon.sys.dao.ApsProcessOperationProcessEquDao;
+import com.rongwei.bscommon.sys.listener.WorkShopImportListener;
 import com.rongwei.bscommon.sys.service.*;
 import com.rongwei.bscommon.sys.utils.ApsUtils;
 import com.rongwei.bsentity.domain.*;
@@ -44,16 +45,20 @@ import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.DefaultTransactionDefinition;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import static com.rongwei.bscommon.sys.utils.ApsUtils.addNewConflictsDesc;
@@ -116,6 +121,8 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
     private ApsRollerTypeService apsRollerTypeService;
     @Autowired
     private CXAdminFeginClient cxAdminFeginClient;
+    @Autowired
+    private ApsProductionProcessesService apsProductionProcessesService;
 
 //    /**
 //     * 更新工序的待加工批次号信息
@@ -2637,6 +2644,234 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
         return result;
     }
 
+
+    @Override
+    public R workShopImport(MultipartFile multipartFile, HttpServletResponse response) throws IOException {
+        WorkShopImportListener listener = new WorkShopImportListener();
+        // 读取数据
+        EasyExcel.read(multipartFile.getInputStream(), WorkShopExportVo.class, listener).sheet().headRowNumber(1).doRead();
+        // 解析有误信息
+        List<String> errorData = listener.getErrorMessages();
+        if (!errorData.isEmpty()) {
+            return R.error(JSON.toJSONString(errorData));
+        }
+        // 解析数据
+        List<WorkShopExportVo> list = listener.getResData();
+
+        //查询所有工序管理
+        List<ApsProductionProcessesDo> allProcessList = apsProductionProcessesService.list();
+        //查询所有设备信息
+        List<AspCheckItemsDo> allDeviceList = aspCheckItemsService.list(new LambdaQueryWrapper<AspCheckItemsDo>()
+                .eq(AspCheckItemsDo::getDeleted, "0")
+                .isNotNull(AspCheckItemsDo::getCheckitemcode)
+                .ne(AspCheckItemsDo::getCheckitemcode, ""));
+        //查询所有设备辊类型
+        List<ApsRollerTypeDo> allRollerList = apsRollerTypeService.list();
+        //查询所有待开工的作业明细
+        List<ApsProcessOperationProcessEquDoAndWidthVo> apsProcessOperationProcessEquDoList = this.baseMapper.getAllWaitDoList();
+        apsProcessOperationProcessEquService.list(new LambdaQueryWrapper<ApsProcessOperationProcessEquDo>()
+                .eq(ApsProcessOperationProcessEquDo::getWorkstatus, "待开工"));
+
+        //==================数据处理======================
+        List<String> errorMessageList = new LinkedList<>();
+        Map<String, List<ApsProcessOperationProcessEquDo>> resMap = new HashMap<>();
+        for (int i = 0; i < list.size(); i++) {
+            //需要更新的实体类
+            ApsProcessOperationProcessEquDo needUpdate = new ApsProcessOperationProcessEquDo();
+            //行号
+            int num = i + 2;
+            //行数据
+            WorkShopExportVo workShopExportVo = list.get(i);
+            //如果当前作业明细ID为空,则遍历下一个作业明细,并添加错误信息:第{行号}行作业明细为空;
+            if (StringUtils.isBlank(workShopExportVo.getId())) {
+                errorMessageList.add("第" + num + "行作业明细为空;");
+                continue;
+            }
+            needUpdate.setId(workShopExportVo.getId());
+            //查找【当前待开工作业明细】=(待开工作业明细列表中查找ID=当前作业明细ID的作业明细)
+            //如果没有找到,则遍历下一个作业明细
+            ApsProcessOperationProcessEquDoAndWidthVo equDo = apsProcessOperationProcessEquDoList.stream().filter(item -> item.getId().equals(workShopExportVo.getId())).findFirst().orElse(null);
+            if (equDo == null) {
+                continue;
+            }
+            //记录一下对应的工序ID
+            needUpdate.setProcessid(equDo.getProcessid());
+            //记录一下对应的坯料计划ID
+            needUpdate.setBlankid(equDo.getBlankid());
+            //如果当前作业明细加工设备编号为空,则遍历下一个作业明细,并添加错误信息:第{行号}行加工设备编号为空;
+            if (StringUtils.isBlank(workShopExportVo.getProcessdevicecode())) {
+                errorMessageList.add("第" + num + "行加工设备编号为空;");
+                continue;
+            }
+            //查找【当前加工设备】=(生产设备列表查找设备编号=当前作业明细设备编号的设备)
+            AspCheckItemsDo aspCheckItemsDo = allDeviceList.stream().filter(item -> item.getCheckitemcode().equals(workShopExportVo.getProcessdevicecode())).findFirst().orElse(null);
+            //如果没找到,则遍历下一个作业明细,并添加错误信息:第{行号}行的加工设备编号{加工设备编号}不正确;
+            if (aspCheckItemsDo == null) {
+                errorMessageList.add("第" + num + "行的加工设备编号" + workShopExportVo.getProcessdevicecode() + "不正确;");
+                continue;
+            }
+            //查找【当前工序】=(工序列表中工序=当前作业明细工序的工序)
+            String process = workShopExportVo.getProcess();
+            ApsProductionProcessesDo apsProductionProcessesDo = allProcessList.stream().filter(item -> item.getProductprocessname().equals(process)).findFirst().orElse(null);
+            if (apsProductionProcessesDo == null) {
+                errorMessageList.add("第" + num + "行的工序" + workShopExportVo.getProcess() + "不正确;");
+                continue;
+            }
+            //如果【当前加工设备】的设备类型不是【当前工序】的可选设备类型,
+            // 则添加错误信息:第{行号}行的设备类型不是工序的可选设备类型;
+            //当前加工设备的设备类型
+            String checkitemtype = aspCheckItemsDo.getCheckitemtype();
+            if (StringUtils.isBlank(checkitemtype)) {
+                errorMessageList.add("第" + num + "行的当前加工设备的设备类型为空;");
+                continue;
+            }
+            //当前工序的可选设备类型
+            String equipmenttype = apsProductionProcessesDo.getEquipmenttype();
+            if (StringUtils.isBlank(equipmenttype)) {
+                errorMessageList.add("第" + num + "行的工序的可选设备类型为空;");
+                continue;
+            }
+            List<String> equipmenttypeList = new LinkedList<>(Arrays.asList(equipmenttype.split(",")));
+            if (!equipmenttypeList.contains(checkitemtype)) {
+                errorMessageList.add("第" + num + "行的设备类型不是工序的可选设备类型;");
+                continue;
+            }
+            needUpdate.setProcessdeviceid(aspCheckItemsDo.getId());
+            needUpdate.setProcessdevice(aspCheckItemsDo.getCheckitemname());
+            needUpdate.setProcessworkshopid(aspCheckItemsDo.getUsedeptid());
+            needUpdate.setProcessworkshop(aspCheckItemsDo.getUsedeptname());
+            //如果【当前工序】的工序类别=轧机,则
+            //查找【当前辊类型ID】=从设备辊类型列表中设备编号=当前作业明细设备编号的辊类型的辊ID
+            //如果没有找到,则添加错误信息:第{行号}行的辊类型不是加工设备的可选辊类型;
+            if (apsProductionProcessesDo.getProcesscategory().equals("20")) {//轧机
+                if (StringUtils.isBlank(workShopExportVo.getRollertype())) {
+                    errorMessageList.add("第" + num + "行的辊类型不可为空;");
+                    continue;
+                }
+                //查询设备辊类型中对应加工设备的辊集合
+                ApsRollerTypeDo apsRollerTypeDo = allRollerList.stream().filter(item -> item.getCheckitemid().equals(aspCheckItemsDo.getId())).filter(item -> item.getRollertype().equals(workShopExportVo.getRollertype())).findFirst().orElse(null);
+                if (apsRollerTypeDo == null) {
+                    errorMessageList.add("第" + num + "行的辊类型不是加工设备的可选辊类型;");
+                    continue;
+                }
+                needUpdate.setRollerid(apsRollerTypeDo.getId());
+            }
+
+            //计算作业时长
+            int workTime = (int) DateUtil.between(equDo.getPlanstartdate(), equDo.getPlanenddate(), DateUnit.MINUTE);
+
+            if (!resMap.containsKey(aspCheckItemsDo.getId())) {
+                if (workShopExportVo.getPlanstartdate() == null) {
+                    errorMessageList.add("第" + num + "行是该设备第一个作业,计划开工时间不能为空;");
+                    continue;
+                }
+                List<ApsProcessOperationProcessEquDo> myList = new LinkedList<>();
+                needUpdate.setPlanstartdate(workShopExportVo.getPlanstartdate());
+                needUpdate.setPlanenddate(DateUtil.offsetMinute(workShopExportVo.getPlanstartdate(), workTime));
+                myList.add(needUpdate);
+                resMap.put(aspCheckItemsDo.getId(), myList);
+            } else {
+                List<ApsProcessOperationProcessEquDo> apsProcessOperationProcessEquDos = resMap.get(aspCheckItemsDo.getId());
+                ApsProcessOperationProcessEquDo lastEquDo = apsProcessOperationProcessEquDos.get(apsProcessOperationProcessEquDos.size() - 1);
+                if (workShopExportVo.getPlanstartdate() != null
+                        && lastEquDo.getPlanenddate().after(workShopExportVo.getPlanstartdate())) {
+                    errorMessageList.add("第" + num + "行计划开工时间填写错误,和该设备上一道作业时间重叠;");
+                    continue;
+                }
+                if (workShopExportVo.getPlanstartdate() != null) {
+                    needUpdate.setPlanstartdate(workShopExportVo.getPlanstartdate());
+                } else {
+                    needUpdate.setPlanstartdate(lastEquDo.getPlanenddate());
+                    if (apsProductionProcessesDo.getProcesscategory().equals("20")) {//当前工序为轧机
+                        //获取输出物料的宽度
+                        BigDecimal width = equDo.getWidth();
+                        //上道作业的宽度
+                        ApsProcessOperationProcessEquDoAndWidthVo lastEqu = apsProcessOperationProcessEquDoList.stream().filter(item -> item.getId().equals(lastEquDo.getId())).findFirst().orElse(null);
+                        BigDecimal lastWidth = lastEqu.getWidth();
+                        if (width.compareTo(lastWidth) > 0
+                                || needUpdate.getRollerid() != lastEquDo.getRollerid()) {
+                            needUpdate.setPlanstartdate(DateUtil.offsetMinute(needUpdate.getPlanstartdate(), 40));
+                        }
+                    }
+                }
+                needUpdate.setPlanenddate(DateUtil.offsetMinute(workShopExportVo.getPlanstartdate(), workTime));
+            }
+        }
+        if (!errorMessageList.isEmpty()) {
+            // 设置响应头
+            response.setContentType("text/plain");
+            response.setHeader("Content-Disposition", "attachment; filename=\"车间作业跟踪导入错误日志" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss") + ".txt\"");
+            response.setCharacterEncoding("utf-8");
+
+            // 生成内容并写入响应
+            try (PrintWriter out = response.getWriter()) {
+                for (String error : errorMessageList) {
+                    out.println(error);
+                }
+            }
+            return R.error("数据错误,请下载错误日志查看!");
+        } else {
+            List<ApsProcessOperationProcessEquDo> allNeedUpdateList = new LinkedList<>();
+            for (String key : resMap.keySet()) {
+                List<ApsProcessOperationProcessEquDo> apsProcessOperationProcessEquDos = resMap.get(key);
+                allNeedUpdateList.addAll(apsProcessOperationProcessEquDos);
+            }
+            //所有需要更新的工序作业ID
+            Set<String> processIdList = allNeedUpdateList.stream().map(ApsProcessOperationProcessEquDo::getProcessid).distinct().collect(Collectors.toSet());
+            //所有需要更新的坯料计划ID
+            List<String> blankIdList = allNeedUpdateList.stream().map(ApsProcessOperationProcessEquDo::getBlankid).distinct().collect(Collectors.toList());
+
+            // 定义事务属性
+            TransactionDefinition definition = new DefaultTransactionDefinition();
+            // 开始事务
+            TransactionStatus status = transactionManager.getTransaction(definition);
+            try {
+                //更新所有明细
+                for (ApsProcessOperationProcessEquDo equDo : allNeedUpdateList) {
+                    LambdaUpdateWrapper<ApsProcessOperationProcessEquDo> wrapper = new LambdaUpdateWrapper<>();
+                    if (StringUtils.isNotBlank(equDo.getProcessdeviceid())) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getProcessdeviceid, equDo.getProcessdeviceid());
+                    }
+                    if (StringUtils.isNotBlank(equDo.getProcessdevice())) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getProcessdevice, equDo.getProcessdevice());
+                    }
+                    if (StringUtils.isNotBlank(equDo.getProcessworkshopid())) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getProcessworkshopid, equDo.getProcessworkshopid());
+                    }
+                    if (StringUtils.isNotBlank(equDo.getProcessworkshop())) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getProcessworkshop, equDo.getProcessworkshop());
+                    }
+                    if (StringUtils.isNotBlank(equDo.getRollerid())) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getRollerid, equDo.getRollerid());
+                    }
+                    if (equDo.getPlanstartdate() != null) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getPlanstartdate, equDo.getPlanstartdate());
+                    }
+                    if (equDo.getPlanenddate() != null) {
+                        wrapper.set(ApsProcessOperationProcessEquDo::getPlanenddate, equDo.getPlanenddate());
+                    }
+                    wrapper.eq(ApsProcessOperationProcessEquDo::getId, equDo.getId())
+                            .eq(ApsProcessOperationProcessEquDo::getWorkstatus, "待开工");
+                    apsProcessOperationProcessEquService.update(wrapper);
+                }
+                if (!processIdList.isEmpty()) {
+                    //更新对应工序作业的 计划完工时间和计划开工时间
+                    this.baseMapper.updateProcessPlanTimeByProcessIds(processIdList);
+                }
+                for (String data : blankIdList) {
+                    // 更新坯料交货期
+                    apsBlankOrderService.updateBlankDeliveryDate(null, data);
+                }
+                // 提交事务
+                transactionManager.commit(status);
+            } catch (Exception e) {
+                // 捕获异常并回滚事务
+                transactionManager.rollback(status);
+                throw e;
+            }
+            return R.ok("导入成功!");
+        }
+    }
 }
 
 

+ 15 - 0
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsProcessOperationProcessEquDao.xml

@@ -680,4 +680,19 @@
         AND apope.TENANTID = #{tenantId}
         AND apope.MODIFYDATE > #{startTime}
     </select>
+    <select id="getAllWaitDoList"
+            resultType="com.rongwei.bsentity.vo.ApsProcessOperationProcessEquDoAndWidthVo">
+        SELECT
+            apope.*,
+            apoom.PROWIDTH AS 'width'
+        FROM
+            aps_process_operation_process_equ apope
+                JOIN aps_process_operation apo ON apope.PROCESSID = apo.ID
+                JOIN aps_process_operation_out_mater apoom ON apoom.MAINID = apo.ID
+        WHERE
+            apope.DELETED = 0
+          AND apo.DELETED = 0
+          AND apoom.DELETED = 0
+          AND apope.WORKSTATUS = '待开工'
+    </select>
 </mapper>

+ 16 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/ApsProcessOperationProcessEquDoAndWidthVo.java

@@ -0,0 +1,16 @@
+package com.rongwei.bsentity.vo;
+
+import com.rongwei.bsentity.domain.ApsProcessOperationProcessEquDo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author :sc
+ * @since :2025/4/18
+ */
+@Data
+public class ApsProcessOperationProcessEquDoAndWidthVo extends ApsProcessOperationProcessEquDo {
+    //宽
+    private BigDecimal width;
+}

+ 4 - 2
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/WorkShopExportVo.java

@@ -3,6 +3,8 @@ package com.rongwei.bsentity.vo;
 import com.alibaba.excel.annotation.ExcelProperty;
 import lombok.Data;
 
+import java.util.Date;
+
 /**
  * @author :sc
  * @since :2025/4/18
@@ -16,9 +18,9 @@ public class WorkShopExportVo {
     @ExcelProperty("加工设备")
     private String processdevice;
     @ExcelProperty("计划开工时间")
-    private String planstartdate;
+    private Date planstartdate;
     @ExcelProperty("计划完工时间")
-    private String planenddate;
+    private Date planenddate;
     @ExcelProperty("输入物料")
     private String planinput;
     @ExcelProperty("输出物料")

+ 11 - 4
cx-aps/cx-aps-server/src/main/java/com/rongwei/bsserver/controller/ApsProcessOperationProcessEquController.java

@@ -9,10 +9,8 @@ import com.rongwei.rwcommon.vo.CriteriaQuery;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -161,5 +159,14 @@ public class ApsProcessOperationProcessEquController {
         log.info("车间作业跟踪,导出");
         apsProcessOperationProcessEquService.workShopExport(query,response);
     }
+
+    /**
+     * 车间作业跟踪,导入
+     */
+    @PostMapping("workShopImport")
+    public R workShopImport(@RequestParam("file") MultipartFile multipartFile, HttpServletResponse response) throws IOException {
+        log.info("车间作业跟踪,导入");
+        return apsProcessOperationProcessEquService.workShopImport(multipartFile, response);
+    }
 }