diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/SfcOperationPlanningMainController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/SfcOperationPlanningMainController.java index 12bff34..2ac84cc 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/SfcOperationPlanningMainController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/SfcOperationPlanningMainController.java @@ -26,6 +26,7 @@ import com.ruoyi.common.core.page.TableDataInfo; import cn.dev33.satoken.annotation.SaIgnore; import com.ruoyi.system.domain.dto.OperationPlanResultDTO; +import com.ruoyi.system.domain.dto.OperationPlanningUpdateOperatorsReq; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.PageQuery; @@ -64,6 +65,13 @@ public class SfcOperationPlanningMainController extends BaseController { return iSfcOperationPlanningMainService.queryCascadePageList(bo, pageQuery); } + @SaIgnore + @Log(title = "工序作业人员更新", businessType = BusinessType.UPDATE) + @PutMapping("/updateOperators") + public R updateOperators(@Validated @RequestBody OperationPlanningUpdateOperatorsReq req) { + return toAjax(iSfcOperationPlanningMainService.updateOperators(req)); + } + /** * 查询工序计划主列表 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SfcOperationPlanningDetail.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SfcOperationPlanningDetail.java index f30e5f2..4cb9f2f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SfcOperationPlanningDetail.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SfcOperationPlanningDetail.java @@ -39,6 +39,8 @@ public class SfcOperationPlanningDetail extends BaseEntity { * 单据体内码(K3明细内码) */ private Long entityEntryId; + + private Long k3DetailId; /** * 工序号 */ @@ -95,6 +97,10 @@ public class SfcOperationPlanningDetail extends BaseEntity { * 工序序列-计划完成时间 */ private Date seqPlanFinishTime; + + private Date operPlanStartTime; + + private Date operPlanFinishTime; /** * 工序控制码 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningDTO.java index 1ebafd8..dc58d26 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningDTO.java @@ -18,6 +18,9 @@ public class OperationPlanningDTO { @JsonProperty("FENTITY_FEntryID") private Long fEntityFEntryId; + @JsonProperty("FSubEntity_FDetailID") + private Long fSubEntityFDetailId; + /** * 生产令号 */ @@ -173,4 +176,10 @@ public class OperationPlanningDTO { */ @JsonProperty("FOperDescription") private String fOperDescription; + + @JsonProperty("FPlanStartTime") + private String fPlanStartTime; + + @JsonProperty("FPlanFinishTime") + private String fPlanFinishTime; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningUpdateOperatorItem.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningUpdateOperatorItem.java new file mode 100644 index 0000000..dfca735 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningUpdateOperatorItem.java @@ -0,0 +1,15 @@ +package com.ruoyi.system.domain.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class OperationPlanningUpdateOperatorItem { + @NotNull + private Long entityEntryId; + private Integer operNo; + private String operator; + private String processName; +} + diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningUpdateOperatorsReq.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningUpdateOperatorsReq.java new file mode 100644 index 0000000..b88756a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/OperationPlanningUpdateOperatorsReq.java @@ -0,0 +1,21 @@ +package com.ruoyi.system.domain.dto; + +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class OperationPlanningUpdateOperatorsReq { + private Long orderId; + private Long fid; + private String billNo; + private String moNumber; + private String batchNo; + + @NotEmpty + @Valid + private List updates; +} + diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessDetailDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessDetailDTO.java index 501d0cd..5cadc96 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessDetailDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessDetailDTO.java @@ -29,6 +29,8 @@ public class ProcessDetailDTO { * 转入数量 */ private Double inQty; + + private Double progress; /** * 合格数量 @@ -44,6 +46,8 @@ public class ProcessDetailDTO { * 状态 */ private String status; + + private String k3Status; /** * 转出数量 */ @@ -74,6 +78,10 @@ public class ProcessDetailDTO { */ private String seqPlanFinishTime; + private String operPlanStartTime; + + private String operPlanFinishTime; + /** * 工序控制码 */ @@ -94,6 +102,8 @@ public class ProcessDetailDTO { */ private String operDescription; + private Long k3DetailId; + /** * 单据体内码 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProductionOrderPlanTimeDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProductionOrderPlanTimeDTO.java new file mode 100644 index 0000000..6dff747 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProductionOrderPlanTimeDTO.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class ProductionOrderPlanTimeDTO { + + @JsonProperty("FMONumber") + private String fMoNumber; + + @JsonProperty("FPlanStartTime") + private String fPlanStartTime; + + @JsonProperty("FPlanFinishTime") + private String fPlanFinishTime; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/jdmain/rouplan/FSubEntity.java b/ruoyi-system/src/main/java/com/ruoyi/system/jdmain/rouplan/FSubEntity.java index 6737055..0ea7196 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/jdmain/rouplan/FSubEntity.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/jdmain/rouplan/FSubEntity.java @@ -18,6 +18,9 @@ public class FSubEntity { @JsonProperty("FOperNumber") private Long FOperNumber; + + @JsonProperty("F_HBYT_ZYRY") + private String F_HBYT_ZYRY; /* 入库仓库 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java index 4434b86..a2c6258 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java @@ -3671,17 +3671,36 @@ public class JdUtil { JsonObject json = new JsonObject(); json.addProperty("FormId", "SFC_OperationPlanning"); json.addProperty("FieldKeys", - "FID,FENTITY_FEntryID,F_HBYT_SCLH,FMONumber,FProductId.FNumber,FProductName,FProSpecification,FBillNo,FOperNumber,FOperQty,FQualifiedQty,FTransOutQty,FUnqualifiedQty,FWastageQty,FTransInQty,FDepartmentId.FName,FWorkCenterId.FName,FProcessId.FName,F_HBYT_ZYRY,FOperStatus,FSeqPlanStartTime,FSeqPlanFinishTime,FOperPlanStartTime,FOperPlanFinishTime,FOptCtrlCodeId.FName,FKeyOper,FActivity1Name,FOperDescription"); + "FID,FENTITY_FEntryID,FSubEntity_FDetailID,F_HBYT_SCLH,FMONumber,FProductId.FNumber,FProductName,FProSpecification,FBillNo,FOperNumber," + + "FOperQty,FQualifiedQty,FTransOutQty,FUnqualifiedQty,FWastageQty,FTransInQty,FDepartmentId.FName,FWorkCenterId.FName," + + "FProcessId.FName,F_HBYT_ZYRY,FOperStatus,FSeqPlanStartTime,FSeqPlanFinishTime,FOperPlanStartTime,FOperPlanFinishTime," + + "FOptCtrlCodeId.FName,FKeyOper,FActivity1Name,FOperDescription,FPlanStartTime,FPlanFinishTime"); // 创建过滤条件 JsonArray filterString = new JsonArray(); JsonObject filterObject = new JsonObject(); - /* filterObject.addProperty("FieldName", "FOperStatus"); - filterObject.addProperty("Compare", "105"); - filterObject.addProperty("Value", "4"); + filterObject.addProperty("FieldName", "FPlanStartTime"); + filterObject.addProperty("Compare", "39"); + filterObject.addProperty("Value", "2025-01-01 00:00:00"); filterObject.addProperty("Left", ""); filterObject.addProperty("Right", ""); filterObject.addProperty("Logic", 0); - filterString.add(filterObject);*/ + filterString.add(filterObject); + JsonObject filterObject1 = new JsonObject(); + filterObject1.addProperty("FieldName", "FPlanFinishTime"); + filterObject1.addProperty("Compare", "39"); + filterObject1.addProperty("Value", "2026-04-12 00:00:00"); + filterObject1.addProperty("Left", ""); + filterObject1.addProperty("Right", ""); + filterObject1.addProperty("Logic", 0); + filterString.add(filterObject1); + /* JsonObject filterObject2 = new JsonObject(); + filterObject2.addProperty("FieldName", "FOperStatus"); + filterObject2.addProperty("Compare", "105"); + filterObject2.addProperty("Value", "4"); + filterObject2.addProperty("Left", ""); + filterObject2.addProperty("Right", ""); + filterObject2.addProperty("Logic", 0); + filterString.add(filterObject2);*/ json.add("FilterString", filterString); json.addProperty("OrderString", ""); json.addProperty("TopRowCount", 0); @@ -3689,25 +3708,80 @@ public class JdUtil { json.addProperty("Limit", 10000); json.addProperty("SubSystemId", ""); - String jsonData = json.toString(); - List operationPlanningList = null; - try { - // 调用接口 - String resultJson = String.valueOf(client.billQuery(jsonData)); - JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + int limit = 10000; + int startRow = 0; + List allList = new ArrayList<>(); + ObjectMapper objectMapper = new ObjectMapper(); + while (true) { + json.addProperty("StartRow", startRow); + json.addProperty("Limit", limit); + String jsonData = json.toString(); + try { + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + if (jsonArray == null || jsonArray.size() == 0) { + break; + } - // 使用 ObjectMapper 将 JsonArray 转换为 List - ObjectMapper objectMapper = new ObjectMapper(); - operationPlanningList = objectMapper.readValue(jsonArray.toString(), - new TypeReference>() { + List batchList = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() { + }); + if (batchList != null && !batchList.isEmpty()) { + allList.addAll(batchList); + } - }); - - } catch (Exception e) { - e.printStackTrace(); // 输出异常日志 + if (jsonArray.size() < limit) { + break; + } + startRow += limit; + } catch (Exception e) { + e.printStackTrace(); + break; + } } - return operationPlanningList; // 返回结果 + return allList; + } + + public static ProductionOrderPlanTimeDTO getProductionOrderPlanTime(String moNumber) { + K3CloudApi client = new K3CloudApi(); + + JsonObject json = new JsonObject(); + json.addProperty("FormId", "SFC_OperationPlanning"); + json.addProperty("FieldKeys", "FMONumber,FPlanStartTime,FPlanFinishTime"); + + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMONumber"); + filterObject.addProperty("Compare", "="); + filterObject.addProperty("Value", moNumber); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 1); + json.addProperty("SubSystemId", ""); + + try { + String resultJson = String.valueOf(client.billQuery(json.toString())); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + if (jsonArray == null ) { + return null; + } + + ObjectMapper objectMapper = new ObjectMapper(); + List list = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() { + }); + return list == null || list.isEmpty() ? null : list.get(0); + } catch (Exception e) { + return null; + } } /** @@ -3740,8 +3814,8 @@ public class JdUtil { resultDTO.setProductName(firstItem.getFProductName()); resultDTO.setBillNo(firstItem.getFBillNo()); resultDTO.setProSpecification(firstItem.getFProSpecification()); - resultDTO.setPlanStartTime(firstItem.getFOperPlanStartTime()); - resultDTO.setPlanFinishTime(firstItem.getFOperPlanFinishTime()); + resultDTO.setPlanStartTime(firstItem.getFPlanStartTime()); + resultDTO.setPlanFinishTime(firstItem.getFPlanFinishTime()); resultDTO.setFid(firstItem.getFid()); List processList = new ArrayList<>(); @@ -3762,10 +3836,13 @@ public class JdUtil { detail.setOperator(item.getFHbytZyry()); detail.setSeqPlanStartTime(item.getFSeqPlanStartTime()); detail.setSeqPlanFinishTime(item.getFSeqPlanFinishTime()); + detail.setOperPlanStartTime(item.getFOperPlanStartTime()); + detail.setOperPlanFinishTime(item.getFOperPlanFinishTime()); detail.setOptCtrlCode(item.getFOptCtrlCodeIdFName()); detail.setKeyOper(item.getFKeyOper()); detail.setActivity1Name(item.getFActivity1Name()); detail.setOperDescription(item.getFOperDescription()); + detail.setK3DetailId(item.getFSubEntityFDetailId()); detail.setEntityEntryId(item.getFEntityFEntryId()); // 状态映射:K3里4通常表示已完工 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/runner/updatePcessPlanConver.java b/ruoyi-system/src/main/java/com/ruoyi/system/runner/updatePcessPlanConver.java index c755761..0128765 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/runner/updatePcessPlanConver.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/runner/updatePcessPlanConver.java @@ -158,4 +158,37 @@ public class updatePcessPlanConver { return repoRet; } + public static RepoRet updatePcessOperator(List numDTO) { + + RepoRet repoRet = null; + for (Model model : numDTO) { + MainModel mainModel = new MainModel(); + List needUpDateFields = Arrays.asList( + "FEntity", "FSubEntity", "F_HBYT_ZYRY" + ); + mainModel.setNeedUpDateFields(needUpDateFields); + mainModel.setDeleteEntry(false); + mainModel.setModel(model); + Gson gson1 = new GsonBuilder().setPrettyPrinting().create(); + K3CloudApi client = new K3CloudApi(); + String jsonOutput = gson1.toJson(mainModel); + repoRet = null; + try { + String formId = "SFC_OperationPlanning"; + String resultJson = client.save(formId, jsonOutput); + Gson gson = new Gson(); + repoRet = gson.fromJson(resultJson, RepoRet.class); + if (repoRet.getResult().getResponseStatus().isIsSuccess()) { + System.out.printf("接口返回结果====================》: %s%n", gson.toJson(repoRet.getResult())); + } else { + fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus().getErrors().get(1))); + } + } catch (Exception e) { + fail(e.getMessage()); + return repoRet; + } + } + return repoRet; + } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISfcOperationPlanningMainService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISfcOperationPlanningMainService.java index 83ea8e4..161864a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISfcOperationPlanningMainService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISfcOperationPlanningMainService.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service; import com.ruoyi.system.domain.SfcOperationPlanningMain; import com.ruoyi.system.domain.dto.OperationPlanResultDTO; +import com.ruoyi.system.domain.dto.OperationPlanningUpdateOperatorsReq; import com.ruoyi.system.domain.vo.SfcOperationPlanningMainVo; import com.ruoyi.system.domain.bo.SfcOperationPlanningMainBo; import com.ruoyi.common.core.page.TableDataInfo; @@ -57,4 +58,6 @@ public interface ISfcOperationPlanningMainService { * 分页查询工序计划主及明细级联数据 */ TableDataInfo queryCascadePageList(SfcOperationPlanningMainBo bo, PageQuery pageQuery); + + Boolean updateOperators(OperationPlanningUpdateOperatorsReq req); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SfcOperationPlanningMainServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SfcOperationPlanningMainServiceImpl.java index 30a4b19..6378f48 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SfcOperationPlanningMainServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SfcOperationPlanningMainServiceImpl.java @@ -18,12 +18,21 @@ import com.ruoyi.system.mapper.SfcOperationPlanningDetailMapper; import com.ruoyi.system.domain.SfcOperationPlanningDetail; import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.domain.dto.OperationPlanResultDTO; +import com.ruoyi.system.domain.dto.OperationPlanningUpdateOperatorItem; +import com.ruoyi.system.domain.dto.OperationPlanningUpdateOperatorsReq; import com.ruoyi.system.domain.dto.ProcessDetailDTO; +import com.ruoyi.system.jdmain.rouplan.FEntity; +import com.ruoyi.system.jdmain.rouplan.FSubEntity; +import com.ruoyi.system.jdmain.rouplan.Model; +import com.ruoyi.system.runner.updatePcessPlanConver; +import com.kingdee.bos.webapi.entity.RepoRet; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.math.RoundingMode; import cn.hutool.core.date.DateUtil; import java.util.Date; import com.ruoyi.system.service.ISfcOperationPlanningMainService; +import com.ruoyi.common.exception.ServiceException; import java.util.List; import java.util.ArrayList; @@ -93,10 +102,17 @@ public class SfcOperationPlanningMainServiceImpl implements ISfcOperationPlannin if (processList != null && !processList.isEmpty()) { for (ProcessDetailDTO detailDTO : processList) { // 查询是否已经存在该明细记录 (根据 fid 和 entity_entry_id 和 oper_number) - SfcOperationPlanningDetail detailEntity = detailMapper.selectOne(Wrappers.lambdaQuery() - .eq(SfcOperationPlanningDetail::getFid, resultDTO.getFid()) - .eq(SfcOperationPlanningDetail::getEntityEntryId, detailDTO.getEntityEntryId()) - .eq(detailDTO.getOperNo() != null, SfcOperationPlanningDetail::getOperNumber, detailDTO.getOperNo())); + SfcOperationPlanningDetail detailEntity; + if (detailDTO.getK3DetailId() != null) { + detailEntity = detailMapper.selectOne(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningDetail::getFid, resultDTO.getFid()) + .eq(SfcOperationPlanningDetail::getK3DetailId, detailDTO.getK3DetailId())); + } else { + detailEntity = detailMapper.selectOne(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningDetail::getFid, resultDTO.getFid()) + .eq(SfcOperationPlanningDetail::getEntityEntryId, detailDTO.getEntityEntryId()) + .eq(detailDTO.getOperNo() != null, SfcOperationPlanningDetail::getOperNumber, detailDTO.getOperNo())); + } if (detailEntity == null) { detailEntity = new SfcOperationPlanningDetail(); @@ -105,6 +121,7 @@ public class SfcOperationPlanningMainServiceImpl implements ISfcOperationPlannin detailEntity.setMainId(mainId); detailEntity.setFid(resultDTO.getFid()); detailEntity.setEntityEntryId(detailDTO.getEntityEntryId()); + detailEntity.setK3DetailId(detailDTO.getK3DetailId()); if (detailDTO.getOperNo() != null) { detailEntity.setOperNumber(Long.valueOf(detailDTO.getOperNo())); } @@ -127,6 +144,12 @@ public class SfcOperationPlanningMainServiceImpl implements ISfcOperationPlannin if (StringUtils.isNotBlank(detailDTO.getSeqPlanFinishTime())) { detailEntity.setSeqPlanFinishTime(DateUtil.parse(detailDTO.getSeqPlanFinishTime())); } + if (StringUtils.isNotBlank(detailDTO.getOperPlanStartTime())) { + detailEntity.setOperPlanStartTime(DateUtil.parse(detailDTO.getOperPlanStartTime())); + } + if (StringUtils.isNotBlank(detailDTO.getOperPlanFinishTime())) { + detailEntity.setOperPlanFinishTime(DateUtil.parse(detailDTO.getOperPlanFinishTime())); + } detailEntity.setOptCtrlCode(detailDTO.getOptCtrlCode()); detailEntity.setKeyOper(detailDTO.getKeyOper()); @@ -144,6 +167,115 @@ public class SfcOperationPlanningMainServiceImpl implements ISfcOperationPlannin return true; } + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateOperators(OperationPlanningUpdateOperatorsReq req) { + SfcOperationPlanningMain main; + if (req.getOrderId() != null) { + main = baseMapper.selectById(req.getOrderId()); + } else if (req.getFid() != null) { + main = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningMain::getFid, req.getFid())); + } else if (StringUtils.isNotBlank(req.getBillNo())) { + main = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningMain::getBillNo, req.getBillNo())); + } else if (StringUtils.isNotBlank(req.getMoNumber())) { + main = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningMain::getMoNumber, req.getMoNumber())); + } else if (StringUtils.isNotBlank(req.getBatchNo())) { + main = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningMain::getHbytSclh, req.getBatchNo())); + } else { + throw new ServiceException("缺少定位参数"); + } + + if (main == null || main.getFid() == null) { + throw new ServiceException("未找到对应订单"); + } + Long fid = main.getFid(); + + Map updateMap = req.getUpdates().stream() + .collect(Collectors.toMap(OperationPlanningUpdateOperatorItem::getEntityEntryId, item -> item, (a, b) -> b, LinkedHashMap::new)); + + List entityEntryIds = new ArrayList<>(updateMap.keySet()); + List details = detailMapper.selectList(Wrappers.lambdaQuery() + .eq(SfcOperationPlanningDetail::getFid, fid) + .in(SfcOperationPlanningDetail::getEntityEntryId, entityEntryIds)); + + if (details == null || details.isEmpty()) { + throw new ServiceException("未找到可更新的工序行"); + } + + if (fid > Integer.MAX_VALUE) { + throw new ServiceException("K3 FID 超出范围"); + } + + List models = new ArrayList<>(); + for (SfcOperationPlanningDetail detail : details) { + OperationPlanningUpdateOperatorItem item = updateMap.get(detail.getEntityEntryId()); + if (item == null) { + continue; + } + if (detail.getK3DetailId() == null) { + throw new ServiceException("缺少 FDetailID,请先同步工序计划数据"); + } + + String operator = item.getOperator(); + if (operator != null) { + operator = operator.trim(); + if (operator.isEmpty()) { + operator = null; + } + } + + if (detail.getEntityEntryId() == null || detail.getEntityEntryId() > Integer.MAX_VALUE) { + throw new ServiceException("单据体内码超出范围"); + } + if (detail.getK3DetailId() > Integer.MAX_VALUE) { + throw new ServiceException("FDetailID 超出范围"); + } + + FSubEntity subEntity = new FSubEntity(); + subEntity.setFDetailID(detail.getK3DetailId().intValue()); + subEntity.setF_HBYT_ZYRY(operator); + + FEntity entity = new FEntity(); + entity.setFEntryID(detail.getEntityEntryId().intValue()); + entity.getFSubEntity().add(subEntity); + + Model model = new Model(); + model.setFID(fid.intValue()); + model.getFEntity().add(entity); + models.add(model); + } + + if (models.isEmpty()) { + throw new ServiceException("未找到可更新的工序行"); + } + + RepoRet repoRet = updatePcessPlanConver.updatePcessOperator(models); + if (repoRet == null || repoRet.getResult() == null || repoRet.getResult().getResponseStatus() == null || !repoRet.getResult().getResponseStatus().isIsSuccess()) { + throw new ServiceException("K3 更新失败"); + } + + for (SfcOperationPlanningDetail detail : details) { + OperationPlanningUpdateOperatorItem item = updateMap.get(detail.getEntityEntryId()); + if (item == null) { + continue; + } + String operator = item.getOperator(); + if (operator != null) { + operator = operator.trim(); + if (operator.isEmpty()) { + operator = null; + } + } + detail.setOperator(operator); + detailMapper.updateById(detail); + } + return true; + } + /** * 查询工序计划主 */ @@ -235,23 +367,55 @@ public class SfcOperationPlanningMainServiceImpl implements ISfcOperationPlannin detailDTO.setWastageQty(detail.getWastageQty() != null ? detail.getWastageQty().doubleValue() : null); detailDTO.setDepartment(detail.getDepartmentName()); detailDTO.setOperator(detail.getOperator()); + if (detailDTO.getPlanQty() != null && detailDTO.getInQty() != null && detailDTO.getPlanQty() > 0) { + BigDecimal progress = BigDecimal.valueOf(detailDTO.getInQty()) + .multiply(BigDecimal.valueOf(100)) + .divide(BigDecimal.valueOf(detailDTO.getPlanQty()), 2, RoundingMode.HALF_UP); + if (progress.compareTo(BigDecimal.ZERO) < 0) { + progress = BigDecimal.ZERO; + } else if (progress.compareTo(BigDecimal.valueOf(100)) > 0) { + progress = BigDecimal.valueOf(100); + } + detailDTO.setProgress(progress.doubleValue()); + } // 状态映射 String statusStr = detail.getOperStatus(); - if ("1".equals(statusStr)) detailDTO.setStatus("计划"); - else if ("2".equals(statusStr)) detailDTO.setStatus("计划下达"); - else if ("3".equals(statusStr)) detailDTO.setStatus("开工"); - else if ("4".equals(statusStr)) detailDTO.setStatus("已完工"); - else if ("5".equals(statusStr)) detailDTO.setStatus("结案"); - else if ("6".equals(statusStr)) detailDTO.setStatus("结算"); - else detailDTO.setStatus(statusStr); + if ("1".equals(statusStr)) detailDTO.setK3Status("计划"); + else if ("2".equals(statusStr)) detailDTO.setK3Status("计划下达"); + else if ("3".equals(statusStr)) detailDTO.setK3Status("开工"); + else if ("4".equals(statusStr)) detailDTO.setK3Status("已完工"); + else if ("5".equals(statusStr)) detailDTO.setK3Status("结案"); + else if ("6".equals(statusStr)) detailDTO.setK3Status("结算"); + else detailDTO.setK3Status(statusStr); + + double inQty = detailDTO.getInQty() == null ? 0D : detailDTO.getInQty(); + double okQty = detailDTO.getOkQty() == null ? 0D : detailDTO.getOkQty(); + double ngQty = detailDTO.getNgQty() == null ? 0D : detailDTO.getNgQty(); + double transOutQty = detailDTO.getTransOutQty() == null ? 0D : detailDTO.getTransOutQty(); + if ("5".equals(statusStr) || "6".equals(statusStr)) { + detailDTO.setStatus("已关闭"); + } else if (inQty == 0D) { + detailDTO.setStatus("未开工"); + } else if (transOutQty > 0D) { + detailDTO.setStatus("已转出"); + } else if (okQty + ngQty >= inQty) { + detailDTO.setStatus("工序完成"); + } else if (okQty + ngQty > 0D) { + detailDTO.setStatus("质检中"); + } else { + detailDTO.setStatus("生产中"); + } detailDTO.setSeqPlanStartTime(detail.getSeqPlanStartTime() != null ? DateUtil.formatDateTime(detail.getSeqPlanStartTime()) : null); detailDTO.setSeqPlanFinishTime(detail.getSeqPlanFinishTime() != null ? DateUtil.formatDateTime(detail.getSeqPlanFinishTime()) : null); + detailDTO.setOperPlanStartTime(detail.getOperPlanStartTime() != null ? DateUtil.formatDateTime(detail.getOperPlanStartTime()) : null); + detailDTO.setOperPlanFinishTime(detail.getOperPlanFinishTime() != null ? DateUtil.formatDateTime(detail.getOperPlanFinishTime()) : null); detailDTO.setOptCtrlCode(detail.getOptCtrlCode()); detailDTO.setKeyOper(detail.getKeyOper()); detailDTO.setActivity1Name(detail.getActivityName()); detailDTO.setOperDescription(detail.getOperDescription()); + detailDTO.setK3DetailId(detail.getK3DetailId()); detailDTO.setEntityEntryId(detail.getEntityEntryId()); processList.add(detailDTO);