|
@@ -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("导入成功!");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|