diff --git a/.gitignore b/.gitignore index d522a49..6d26f06 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .settings .factorypath .project +.logs pom.properties **/target/** mvnw diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java index 1e063cc..257e1cb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java @@ -390,7 +390,8 @@ public class BomDetailsController extends BaseController { // 只在第一次遇到该物料时新增父级物料 if (!processedMaterials.contains(material.getFNumber())) { try { log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName()); - JdUtil.loadChengPinMaterialPreservation(material); + Double fbWorkTime = iProcessRouteService.getFaWorkTime(material); + JdUtil.loadChengPinMaterialPreservation(material,fbWorkTime); processedMaterials.add(material.getFNumber()); // 标记为已处理 } catch (Exception e) { log.error("新增父级物料失败: {}", e.getMessage()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java index 4827b05..7ef361d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java @@ -13,6 +13,8 @@ import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.common.utils.JdUtils; import com.ruoyi.system.domain.EleMaterials; import com.ruoyi.system.domain.dto.JdEntry; +import com.ruoyi.system.domain.dto.JdEntryVmi; +import com.ruoyi.system.domain.dto.JdVMIVo; import com.ruoyi.system.domain.dto.JinYongDTO; import com.ruoyi.system.domain.vo.ExcelVo; import com.ruoyi.system.runner.JdUtil; @@ -131,11 +133,11 @@ public class EleMaterialsController extends BaseController { @RepeatSubmit() @PostMapping("/addToK3") public R> addToK3() { - List eleMaterialsVos = iEleMaterialsService.addToJindie(); - return R.ok(eleMaterialsVos); + + return iEleMaterialsService.addToJindie(); } @Log(title = "电器物料导入", businessType = BusinessType.IMPORT) - @SaCheckPermission("system:materials:import") + @SaCheckPermission("system:materials:importData") @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ExcelVo importData(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws Exception { String originalFilename = file.getOriginalFilename(); @@ -157,9 +159,9 @@ public class EleMaterialsController extends BaseController { return jsonObject; } - @SaCheckPermission("system:materials:export") - @Log(title = "电器物料导出", businessType = BusinessType.EXPORT) - @PostMapping(value = "/importData1") + @SaCheckPermission("system:materials:exportData") + @Log(title = "电器物料数据导出", businessType = BusinessType.EXPORT) + @PostMapping(value = "/exportData") public void importData1(@RequestBody ExcelVo excelVo, HttpServletResponse response) throws Exception { //把 result 返回 @@ -272,4 +274,41 @@ public class EleMaterialsController extends BaseController { return R.ok("更新成功"); } + + @Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT) + @SaCheckPermission("system:route:updaDateGongshi") + @PostMapping(value = "/updaDateCangwei", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R updaDateCangwei(@RequestParam("file") MultipartFile file) throws Exception { + String originalFilename = file.getOriginalFilename(); + log.info("读取文件名: " + originalFilename); + ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdVMIVo.class, true); + List list = result.getList(); + + // 创建固定大小的线程池 + ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 + + for (JdVMIVo vmi : list) { + executor.submit(() -> { + List entryID = JdUtil.getEntryID2(vmi.getMaterialCode()); + for (JdEntryVmi jdEntryVmi : entryID) { + int fmaterialid = jdEntryVmi.getFMATERIALID(); + int fEntryId1 = jdEntryVmi.getFEntryId1(); + int fEntryId3 = jdEntryVmi.getFEntryId3(); + try { + JdUtil.updateVMI(fmaterialid, fEntryId1, fEntryId3,vmi.getFStockId(),vmi.getFStockPlaceId()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + // 关闭线程池 + executor.shutdown(); + while (!executor.isTerminated()) { + // 等待所有任务完成 + } + + return R.ok("更新成功"); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java index a193d85..962350b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java @@ -154,6 +154,7 @@ public class ProcessRouteController extends BaseController { parent.setMaterialName(processRouteVo.getMaterialName()); parent.setMaterial(processRouteVo.getMaterial()); parent.setDiscWeight(processRouteVo.getDiscWeight()); + parent.setBatchQuantity(processRouteVo.getBatchQuantity()); parent.setFirstBatchQuantity(processRouteVo.getFirstBatchQuantity()); // 初始化子节点列表 @@ -200,7 +201,6 @@ public class ProcessRouteController extends BaseController { child.setActivityDuration(processRouteVo.getActivityDuration()); child.setActivityUnit(processRouteVo.getActivityUnit()); child.setUnitQuantity(processRouteVo.getUnitQuantity()); - child.setBatchQuantity(processRouteVo.getBatchQuantity()); child.setPlanStartTime(processRouteVo.getPlanStartTime()); child.setPlanEndTime(processRouteVo.getPlanEndTime()); child.setXuStartTime(processRouteVo.getXuStartTime()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java index 8787139..3041ea2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java @@ -23,9 +23,12 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; + /** * 安全库存单据 * @@ -39,6 +42,8 @@ import java.util.List; public class WlStockDataController extends BaseController { private final IWlStockDataService iWlStockDataService; + private List logMessages = Collections.synchronizedList(new ArrayList<>()); + private int lastLogIndex = 0; // 记录上次返回的日志索引 /** * 查询安全库存单据列表 @@ -68,7 +73,7 @@ public class WlStockDataController extends BaseController { @SaCheckPermission("system:stockData:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Long id) { + @PathVariable Long id) { return R.ok(iWlStockDataService.queryById(id)); } @@ -109,15 +114,24 @@ public class WlStockDataController extends BaseController { /** * 生成安全库存单据 + * * @return */ @SaCheckPermission("system:stockData:generateDoc") @Log(title = "安全库存单据", businessType = BusinessType.OTHER) @PostMapping("/generateDoc") - // @XxlJob(value = "generateDoc") public R> generateDoc() { - List wlStockData = iWlStockDataService.generateDoc(); - return R.ok(wlStockData); + List result = iWlStockDataService.generateDoc(); + if (result.isEmpty()) { + return R.fail("没有生成任何数据"); + } + return R.ok(result); } + @GetMapping("/logs") +public List getLogs(@RequestParam(value = "lastIndex", defaultValue = "0") int lastIndex) { + List logs = iWlStockDataService.getLogs(lastIndex); + int nextIndex = lastIndex + logs.size(); + return logs; +} } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/WorkProcedureController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/WorkProcedureController.java index af64ca7..a5faf4e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/WorkProcedureController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/WorkProcedureController.java @@ -1,6 +1,11 @@ package com.ruoyi.system.controller; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.google.gson.JsonObject; +import com.kingdee.bos.webapi.sdk.K3CloudApi; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; @@ -11,18 +16,29 @@ import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.bo.KingdeeWorkCenterDataBo; import com.ruoyi.system.domain.bo.WorkProcedureBo; import com.ruoyi.system.domain.dto.ProductctionPlanGatteDto; import com.ruoyi.system.domain.vo.WorkProcedureVo; +import com.ruoyi.system.service.IKingdeeWorkCenterDataService; import com.ruoyi.system.service.IWorkProcedureService; import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -38,7 +54,9 @@ import java.util.Map; @RequestMapping("/system/procedure") public class WorkProcedureController extends BaseController { + private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class); private final IWorkProcedureService iWorkProcedureService; + private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService; /** * 查询工序任务列表 @@ -127,4 +145,106 @@ public class WorkProcedureController extends BaseController { @PathVariable Long[] ids) { return toAjax(iWorkProcedureService.deleteWithValidByIds(Arrays.asList(ids), true)); } + /** + * 获取金蝶相关工段数据 + */ + @SaCheckPermission("system:workCenterData:getKingdeeWorkCenterData") + @Log(title = "金蝶工段数据提前2天", businessType = BusinessType.DELETE) + @PostMapping("/getKingdeeWorkCenterData") + public R> getKingdeeWorkCenterData(@RequestParam(value="workCenter") String workCenter) { + try { + K3CloudApi client = new K3CloudApi(); + JsonObject parameter = new JsonObject(); + parameter.addProperty("FWorkCenterName", workCenter); + Object[] parameters = new Object[] { parameter.toString() }; + String execute = client.execute( + "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", + parameters); + log.info("金蝶接口返回数据: {}", execute); + + // 解析响应 + JSONObject response = JSONObject.parseObject(execute); + if (!"true".equals(response.getString("IsSuccess"))) { + String errorMsg = response.getString("Message"); + return R.fail("获取工段数据失败:" + errorMsg); + } + + // 获取明天的日期字符串 (格式: yyyy-MM-dd) + String tomorrow = DateUtil.format(DateUtil.tomorrow().toLocalDateTime().plusDays(1), "yyyy-MM-dd"); + + // 获取数据数组 + JSONArray dataArray = response.getJSONArray("data"); + if (dataArray == null || dataArray.isEmpty()) { + return R.ok(Collections.emptyList()); + } + + List tasks = new ArrayList<>(); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + for (int i = 0; i < dataArray.size(); i++) { + JSONArray queryList = dataArray.getJSONObject(i).getJSONArray("QueryList"); + for (int j = 0; j < queryList.size(); j++) { + JSONObject item = queryList.getJSONObject(j); + + // 获取计划结束时间并转换为日期格式进行比较 + String planFinishTime = item.getString("FOperPlanFinishTime2"); + if (StringUtils.hasText(planFinishTime)) { + // 提取日期部分进行比较 (去掉时间部分) + String finishDate = planFinishTime.split(" ")[0]; + // 只处理明天结束的工单 + if (tomorrow.equals(finishDate)) { + // 转换为 ProductctionPlanGatteDto 对象 + ProductctionPlanGatteDto task = new ProductctionPlanGatteDto(); + task.setId(item.getLong("Id")); // 假设有 Id 字段 + task.setText(item.getString("MoOrderNo")); + task.setToolTipsTxt(item.getString("FProcessName")); + + LocalDate startDate = item.getDate("FOperPlanStartTime2").toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + LocalDate endDate = item.getDate("FOperPlanFinishTime2").toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + task.setStart_date(startDate.toString()); + task.setEnd_date(endDate.toString()); + + long duration = ChronoUnit.DAYS.between(startDate, endDate); + task.setDuration(duration); + + task.setOpen(true); + task.setProgress(1L); + task.setStatus("yellow"); + task.setParent(null); // 父任务没有parent + + tasks.add(task); + + // 处理子任务 + JSONArray subTasksArray = item.getJSONArray("SubTasks"); + if (subTasksArray != null) { + for (int k = 0; k < subTasksArray.size(); k++) { + JSONObject subTaskItem = subTasksArray.getJSONObject(k); + ProductctionPlanGatteDto subTask = new ProductctionPlanGatteDto(); + subTask.setId(subTaskItem.getLong("SubTaskId")); + subTask.setText(subTaskItem.getString("FProcessName")); + subTask.setToolTipsTxt(subTaskItem.getString("SubTaskProcessName")); + subTask.setStart_date(subTaskItem.getString("FOperPlanStartTime2")); + subTask.setEnd_date(subTaskItem.getString("FOperPlanFinishTime2")); + subTask.setDuration(subTaskItem.getLong("1")); + subTask.setOpen(true); + subTask.setProgress(1L); + subTask.setStatus("yellow"); + subTask.setParent(task.getId()); // 设置父任务ID + + tasks.add(subTask); + } + } + } + } + } + } + + return R.ok(tasks.isEmpty() ? Collections.emptyList() : tasks); + + } catch (Exception e) { + log.error("获取金蝶工段数据失败", e); + return R.fail("获取金蝶工段数据失败:" + e.getMessage()); + } + } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WorkProcedure.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WorkProcedure.java index f830b47..189a10d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WorkProcedure.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WorkProcedure.java @@ -33,7 +33,7 @@ public class WorkProcedure extends BaseEntity { */ private Long type; /** - * 提示文本 + * 生产令号 */ private String text; /** @@ -69,5 +69,8 @@ public class WorkProcedure extends BaseEntity { * 状态 */ private String status; - + /** + * 结束时间 + */ + private Date endTime; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WorkProcedureBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WorkProcedureBo.java index 8a11575..d2d61ed 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WorkProcedureBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WorkProcedureBo.java @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import java.time.OffsetDateTime; +import java.util.Date; /** * 工序任务业务对象 work_procedure @@ -51,7 +51,7 @@ public class WorkProcedureBo extends BaseEntity { * 开始日期 */ @NotNull(message = "开始日期不能为空", groups = {AddGroup.class, EditGroup.class}) - private OffsetDateTime startDate; + private Date startDate; /** * 持续时间(天数) @@ -84,5 +84,10 @@ public class WorkProcedureBo extends BaseEntity { @NotBlank(message = "状态不能为空", groups = {AddGroup.class, EditGroup.class}) private String status; + /** + * 结束时间 + */ + @NotNull(message = "结束时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date endTime; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdEntryVmi.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdEntryVmi.java new file mode 100644 index 0000000..cae4ae4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdEntryVmi.java @@ -0,0 +1,14 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class JdEntryVmi { + @JsonProperty("FMATERIALID") + private int FMATERIALID; + @JsonProperty("SubHeadEntity1_FEntryId") + private int FEntryId1; + @JsonProperty("SubHeadEntity3_FEntryId") + private int FEntryId3; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdVMIVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdVMIVo.java new file mode 100644 index 0000000..0887a8d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdVMIVo.java @@ -0,0 +1,30 @@ +package com.ruoyi.system.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +@Data +public class JdVMIVo { + /** + * 编码 + */ + @ExcelProperty(value = "编码") + private String materialCode; + /** + * 名称 + */ + @ExcelProperty(value = "名称") + private String materialName; + + /** + * 仓库编码 + */ + @ExcelProperty(value = "仓库编码") + private String FStockId; + /** + * 仓位编码 + */ + @ExcelProperty(value = "仓位编码") + private String FStockPlaceId; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/EleMaterialsVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/EleMaterialsVo.java index 02e62cf..097f5b7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/EleMaterialsVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/EleMaterialsVo.java @@ -32,48 +32,48 @@ public class EleMaterialsVo { /** * 物料编码 */ - @ExcelProperty(value = "产品编码") + @ExcelProperty(value = "物料编码") private String materialCode; /** * 物料名称 */ - // @ExcelProperty(value = "物料名称") + @ExcelProperty(value = "物料名称") private String materialName; /** * 型号 */ - // @ExcelProperty(value = "型号") + @ExcelProperty(value = "型号") private String model; /** * 材质 */ - // @ExcelProperty(value = "类别") + @ExcelProperty(value = "类别") private String materialType; /** * 单位 */ - // @ExcelProperty(value = "单位") + @ExcelProperty(value = "单位") private String unit; /** * 品牌 */ - // @ExcelProperty(value = "品牌") + @ExcelProperty(value = "品牌") private String brand; /** * 备注 */ - // @ExcelProperty(value = "备注") + @ExcelProperty(value = "备注") private String remarks; /** * 物料值 */ - @ExcelProperty(value = "标准人员实作工时") + private String materialValue; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WorkProcedureVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WorkProcedureVo.java index dc281c6..c7d880d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WorkProcedureVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WorkProcedureVo.java @@ -84,5 +84,9 @@ public class WorkProcedureVo { @ExcelProperty(value = "状态") private String status; - + /** + * 结束时间 + */ + @ExcelProperty(value = "结束时间") + private Date endTime; } 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 8019702..61b6dae 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 @@ -906,7 +906,7 @@ public class JdUtil { } } //新增父级物料 - public static int loadChengPinMaterialPreservation(BomDetails bomDetail) { + public static int loadChengPinMaterialPreservation(BomDetails bomDetail, Double fbWorkTime ) { K3CloudApi client = new K3CloudApi(); // 创建一个空的JsonObject JsonObject json = new JsonObject(); @@ -992,12 +992,6 @@ public class JdUtil { JsonObject subHeadEntity3 = new JsonObject(); model.add("SubHeadEntity3", subHeadEntity3); - /* - * // 创建FPurchaseUnitId对象,并加入SubHeadEntity3 - * JsonObject fPurchaseUnitId = new JsonObject(); - * fPurchaseUnitId.addProperty("FNumber", "008"); - * subHeadEntity3.add("FPurchaseUnitId", fPurchaseUnitId); - */ // 创建FPurchasePriceUnitId对象,并加入SubHeadEntity3 JsonObject fPurchasePriceUnitId = new JsonObject(); @@ -1041,7 +1035,8 @@ public class JdUtil { subHeadEntity1.add("FPickStockId", fPickStockId); subHeadEntity5.addProperty("FOverControlMode", "1"); - subHeadEntity5.addProperty("FStandHourUnitId", "3600"); + subHeadEntity5.addProperty("FStdLaborProcessTime", fbWorkTime); + subHeadEntity5.addProperty("FStandHourUnitId", "60"); subHeadEntity5.addProperty("FBackFlushType", "1"); String jsonData = json.toString(); System.out.println(jsonData); @@ -1069,6 +1064,116 @@ public class JdUtil { } } + //查询物料 作用于更新到物料的 仓位 是否启用VMI + public static List getEntryID2(String materialCode) { + List jinYongDTOS = new ArrayList<>(); + K3CloudApi client = new K3CloudApi(); + JsonObject json = new JsonObject(); + json.addProperty("FormId", "BD_MATERIAL"); + json.addProperty("FieldKeys", "FMATERIALID,SubHeadEntity1_FEntryId,SubHeadEntity3_FEntryId"); + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FNumber"); + filterObject.addProperty("Compare", "="); + filterObject.addProperty("Value", materialCode); + 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", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + log.info("查询物料是否启用VMI的接口参数: {}", jsonData); + try { + String resultJson = String.valueOf(client.billQuery(jsonData)); + log.info("查询物料是否启用VMI的接口返回结果: {}", resultJson); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + + if (jsonArray != null && jsonArray.size() > 0) { + ObjectMapper objectMapper = new ObjectMapper(); + List JinYongDTOList = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() {}); + if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) { + jinYongDTOS.addAll(JinYongDTOList); + } + } else { + log.warn("未找到与bom版本号 " + materialCode + " 相关的记录"); + } + } catch (Exception e) { + log.error("调用接口时发生异常: " + e.getMessage(), e); + } + + return jinYongDTOS; + } + + + public static String updateVMI(int FMATERIALID, int fEntryId1, int fEntryId2, String cangkunum, String cangWeiNum) throws Exception { + K3CloudApi api = new K3CloudApi(false); + JsonObject json = new JsonObject(); + + // 创建 NeedUpDateFields 数组 + JsonArray needUpDateFields = new JsonArray(); + needUpDateFields.add("SubHeadEntity1"); + needUpDateFields.add("FMATERIALID"); + needUpDateFields.add("SubHeadEntity3"); + needUpDateFields.add("FStockPlaceId"); + needUpDateFields.add("FStockId"); + needUpDateFields.add("FIsVmiBusiness"); + json.add("NeedUpDateFields", needUpDateFields); + + // 添加 IsDeleteEntry 属性 + json.addProperty("IsDeleteEntry", "false"); + + // 创建 Model 对象 + JsonObject model = new JsonObject(); + model.addProperty("FMATERIALID", FMATERIALID); + + // 创建 SubHeadEntity1 对象 + JsonObject subHeadEntity1 = new JsonObject(); + subHeadEntity1.addProperty("FEntryId", fEntryId1); + + // 创建 FStockId 对象 + JsonObject fStockId = new JsonObject(); + fStockId.addProperty("FNumber", cangkunum); + subHeadEntity1.add("FStockId", fStockId); + + // 创建 FStockPlaceId 对象 + JsonObject fStockPlaceId = new JsonObject(); + JsonObject fStockPlaceIdFF100002 = new JsonObject(); + fStockPlaceIdFF100002.addProperty("FNumber", cangWeiNum); + fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002); + subHeadEntity1.add("FStockPlaceId", fStockPlaceId); + + model.add("SubHeadEntity1", subHeadEntity1); + + // 创建 SubHeadEntity3 对象 + JsonObject subHeadEntity3 = new JsonObject(); + subHeadEntity3.addProperty("FEntryId", fEntryId2); + subHeadEntity3.addProperty("FIsVmiBusiness", "true"); + model.add("SubHeadEntity3", subHeadEntity3); + + json.add("Model", model); + String data = json.toString(); + String result = api.save("BD_Material", data); + log.info("物料保存接口参数: {}", data); + Gson gson = new Gson(); + RepoRet sRet = gson.fromJson(result, RepoRet.class); + if (sRet.isSuccessfully()) { + String successMessage = String.format("物料 %s 保存成功", sRet.getResult().getResponseStatus()); + System.out.println(successMessage); + return successMessage; + } else { + String errorMessage = String.format("物料 %s 保存失败: %s", FMATERIALID, gson.toJson(sRet.getResult())); + System.out.println(errorMessage); + return errorMessage; + } + } } 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 59feb40..004891d 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 @@ -108,6 +108,7 @@ public class updatePcessPlanConver { //业务对象标识工序计划表 String formId = "SFC_OperationPlanning"; //调用接口 + System.out.println("调用接口:"+model.getFProcessId_number()+"+++++" + jsonOutput); String resultJson = client.save(formId, jsonOutput); //用于记录结果 Gson gson = new Gson(); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IEleMaterialsService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IEleMaterialsService.java index 15e2689..3a9068f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IEleMaterialsService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IEleMaterialsService.java @@ -1,5 +1,6 @@ package com.ruoyi.system.service; +import com.ruoyi.common.core.domain.R; import com.ruoyi.system.domain.EleMaterials; import com.ruoyi.system.domain.vo.EleMaterialsVo; import com.ruoyi.system.domain.bo.EleMaterialsBo; @@ -48,7 +49,7 @@ public interface IEleMaterialsService { */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); - List addToJindie(); + R> addToJindie(); boolean saveData(List list, HttpServletResponse response); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java index bf30997..d5151f5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java @@ -57,10 +57,19 @@ public interface IProcessRouteService { Boolean deleteWithValidByIds(Collection ids, Boolean isValid); Boolean updateOrInsertRoute(List bomDetailsVos); + /** + * 保存数据 + */ boolean saveData(List routeVoList, List productionOrderVos); + /** + * 查询组焊件集合 + */ List pushGroupWeldments(ProcessRoute processRoute); + /** + * 获取所有的项目令号 + */ List getDistinctProjectCodes(String query); @@ -72,8 +81,14 @@ public interface IProcessRouteService { * 查询工艺工序集合 */ List getProcessRoute(String rooteProdet); + /** + * 推送工艺路线 + */ ProcessRoutePushResultDTO pushRouteBom(String rooteProdet); + /** + * 获取所有的项目令号 + */ List getSelecPlanRouteList(String rooteProdet); @@ -81,11 +96,18 @@ public interface IProcessRouteService { * 生成这个项目的pdf */ String generatePDFs(String rooteProdet); + /** + * 更新计划时间 + */ List updateProcessPlan(String rooteProdet); + /** + * 获取所有项目 + */ List getProcessInfoList(String query); + R addRoute(List list); List getProcessMaterialList(String materialCode,String materialName, String productionOrderNo); @@ -103,6 +125,8 @@ public interface IProcessRouteService { List getProcessRouteList(String materialCode, String materialName, String productionOrderNo); //获取物料的非委外的工作时长 Double getFbWorkTime(BomDetails material); + + Double getFaWorkTime(BomDetails material); //根据令号和物料编码 查询工艺路线 List getProcessRoutesByOrder(String productionOrderNo, String materialCode); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IWlStockDataService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IWlStockDataService.java index ddffe89..d6548e4 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IWlStockDataService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IWlStockDataService.java @@ -48,4 +48,6 @@ public interface IWlStockDataService { Boolean deleteWithValidByIds(Collection ids, Boolean isValid); List generateDoc(); + + List getLogs(int lastIndex); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java index 05a8a5d..a6b17fb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java @@ -5,6 +5,7 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.kingdee.bos.webapi.entity.RepoRet; import com.kingdee.bos.webapi.sdk.K3CloudApi; +import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -190,12 +191,14 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService { * @return */ @Override - public List addToJindie() { + public R> addToJindie() { LambdaQueryWrapper wra = new LambdaQueryWrapper<>(); wra.eq(EleMaterials::getMaterialValue, "0"); List newMaterials = baseMapper.selectList(wra); List newMaterialsVos = new ArrayList<>(); - + int successCount = 0; // 成功计数 + List errorMessages = new ArrayList<>(); // 错误信息列表 + if (!newMaterials.isEmpty()) { for (EleMaterials eleMaterials : newMaterials) { // 确保 materialValue 不为 null @@ -213,23 +216,24 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService { // 其他品牌,状态为1 states = "1"; } - + int result = loadMaterialToDQ(eleMaterials, states); if (result == 1) { // 直接更新数据库 EleMaterials updateMaterial = new EleMaterials(); updateMaterial.setId(eleMaterials.getId()); updateMaterial.setMaterialValue("1"); - updateMaterial.setRemarks("已推送"); - + // 更新数据库并检查更新结果 if (baseMapper.updateById(updateMaterial) > 0) { // 更新对象状态并添加到返回列表 eleMaterials.setMaterialValue("1"); - eleMaterials.setRemarks("已推送"); newMaterialsVos.add(eleMaterials); + successCount++; // 成功计数加1 } else { - log.error("更新物料失败,物料ID: " + eleMaterials.getId()); + String errorMessage = "更新物料失败,物料ID: " + eleMaterials.getId(); + log.error(errorMessage); + errorMessages.add(errorMessage); // 添加错误信息 } } } @@ -237,10 +241,14 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService { } else { log.warn("未找到符合条件的物料"); } - - return newMaterialsVos; - } + // 构建返回结果 + if (successCount > 0) { + return R.ok("成功推送 " + successCount + " 条物料", newMaterialsVos); + } else { + return R.fail("推送失败,错误信息: " + String.join(", ", errorMessages)); + } + } /** * @param list * @param response @@ -278,22 +286,22 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService { String newCode = generateNextMaterialCode(lastCode, newMaterialsVo.getMaterialType()); newMaterialsVo.setMaterialCode(newCode); EleMaterials eleMaterials = BeanUtil.copyProperties(newMaterialsVo, EleMaterials.class); + eleMaterials.setMaterialValue("0"); + //立刻插入数据 + int insert = baseMapper.insert(eleMaterials); // 仅在有编码的情况下添加到插入列表和导出列表 eleMaterialsList.add(eleMaterials); // 添加到插入列表 allMaterialsList.add(newMaterialsVo); // 添加到导出列表 } } - // 批量插入物料数据 - log.info("开始批量插入物料数据"); - boolean flag = baseMapper.insertBatch(eleMaterialsList); // 导出数据为 Excel 文件 - log.info("开始导出数据为 Excel 文件"); + log.info("开始导出数据为 Excel 文件"); ExcelUtil.exportExcel(allMaterialsList, "电气物料BOM", EleMaterialsVo.class, response); - // exportToExcel(allMaterialsList, response, "副本电气库房库存整理V3(1)"); // 导出所有物料 - return flag; + + return true; } // 导出数据为 Excel 文件的方法 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java index 29a201d..59de80c 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java @@ -1969,34 +1969,41 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { wrapper.eq(ProcessRoute::getMaterialCode, materialCode); List processRoutes = baseMapper.selectList(wrapper); ProcessTimeInfo timeInfo = new ProcessTimeInfo(); // 创建返回对象 + if (processRoutes.isEmpty()) { System.out.println("没有找到任何工序"); return timeInfo; // 返回空信息 } + Date tenthProcessStartTime = null; Date lastProcessEndTime = null; int maxSequenceNumber = -1; // 初始化最大序号 Map sequenceEndTimeMap = new HashMap<>(); + for (ProcessRoute route : processRoutes) { Long sequenceNumber = route.getProcessNo(); - sequenceEndTimeMap.put(sequenceNumber.intValue(), route.getXuEndTime()); - if (sequenceNumber == 10) { - tenthProcessStartTime = route.getXuStartTime(); - } - // 更新最后一道工序的结束时间 - lastProcessEndTime = route.getXuEndTime(); // 更新为当前工序的结束时间 - // 更新最大序号 - if (sequenceNumber > maxSequenceNumber) { - maxSequenceNumber = Math.toIntExact(sequenceNumber); + + // 确保 sequenceNumber 和时间不为 null + if (sequenceNumber != null && route.getXuEndTime() != null) { + sequenceEndTimeMap.put(sequenceNumber.intValue(), route.getXuEndTime()); + if (sequenceNumber == 10) { + tenthProcessStartTime = route.getXuStartTime(); + } + // 更新最后一道工序的结束时间 + lastProcessEndTime = route.getXuEndTime(); // 更新为当前工序的结束时间 + // 更新最大序号 + if (sequenceNumber > maxSequenceNumber) { + maxSequenceNumber = Math.toIntExact(sequenceNumber); + } } } + // 获取最大序号对应的结束时间 lastProcessEndTime = sequenceEndTimeMap.get(maxSequenceNumber); timeInfo.setTenthProcessStartTime(tenthProcessStartTime); timeInfo.setLastProcessEndTime(lastProcessEndTime); return timeInfo; } - // 获取存在工艺 public List getSelectProcessRoute(String materialCode) { K3CloudApi client = new K3CloudApi(); @@ -2189,7 +2196,29 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { } return 0.0; } + //获取父级的物料的公式 + public Double getFaWorkTime(BomDetails material) { + if (material == null) { + log.error("传入的物料对象为 null"); + return 0.0; // 或者抛出异常 + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProcessRoute::getMaterialCode, material.getFNumber()) + .eq(ProcessRoute::getMaterialName, material.getFName()) + .eq(ProcessRoute::getRouteDescription, material.getTotalWeight()) + .ne(ProcessRoute::getWorkCenter, "委外中心"); + + // 不包含工作中心是委外中心的工艺路线 + List processRoutes = baseMapper.selectList(wrapper); + if (!CollectionUtils.isEmpty(processRoutes)) { + // 获取所有活动时长并求和,处理可能为 null 的情况 + return processRoutes.stream() + .mapToDouble(route -> Optional.ofNullable(route.getActivityDuration()).orElse(0.0)) + .sum(); + } + return 0.0; + } /** * @param productionOrderNo * @param materialCode diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java index 173879b..a10ea3b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java @@ -2,19 +2,18 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.google.gson.Gson; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.kingdee.bos.webapi.sdk.K3CloudApi; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.system.controller.ProcessRouteController; import com.ruoyi.system.domain.SafetyStock; import com.ruoyi.system.domain.WlStockData; import com.ruoyi.system.domain.bo.WlStockDataBo; @@ -23,7 +22,6 @@ import com.ruoyi.system.domain.dto.ProMoDTO; import com.ruoyi.system.domain.dto.PurchaseOrderDTO; import com.ruoyi.system.domain.vo.WlStockDataVo; import com.ruoyi.system.mapper.SafetyStockMapper; -import com.ruoyi.system.mapper.StandardPartsMapper; import com.ruoyi.system.mapper.WlStockDataMapper; import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.service.IWlStockDataService; @@ -46,9 +44,13 @@ import java.util.stream.Collectors; @RequiredArgsConstructor @Service public class WlStockDataServiceImpl implements IWlStockDataService { + + private final Queue logMessages = new ConcurrentLinkedQueue<>(); // 使用线程安全的队列存储日志 + + + private static final Logger logger = LoggerFactory.getLogger(WlStockDataServiceImpl.class); private final WlStockDataMapper baseMapper; - private final StandardPartsMapper standardPartsMapper; private final SafetyStockMapper safetyStockMapper; @@ -143,153 +145,36 @@ public class WlStockDataServiceImpl implements IWlStockDataService { return baseMapper.deleteBatchIds(ids) > 0; } + + + private void logMessages(String message) { + logMessages.add(message); // 存储日志信息 + } + + @Override + public List getLogs(int lastIndex) { + List logs = new ArrayList<>(); + int currentIndex = 0; + for (String message : logMessages) { + if (currentIndex >= lastIndex) { + logs.add(message); + } + currentIndex++; + } + return logs; + } /** * 生成安全库存单据 * * @return */ - public List generateDoc2() { - // 查询到安全库存单据已有的数据 - List existingStockData = baseMapper.selectList(); - Set existingMaterialCodes = existingStockData.stream() - .map(WlStockData::getMaterialCode) - .collect(Collectors.toSet()); - - // 获取安全库存阈值,并存储在映射中 - List safetyStocks = safetyStockMapper.selectList(); - Map safetyStockMap = new HashMap<>(); - Map currentStockMap = new HashMap<>(); - - // 定义批次大小 - int batchSize = 20; - - // 分批处理 SafetyStock - for (int start = 0; start < safetyStocks.size(); start += batchSize) { - int end = Math.min(start + batchSize, safetyStocks.size()); - List batchList = safetyStocks.subList(start, end); - - // 调用 selectKuCun1 方法处理每个批次 - JsonArray jsonArray = selectKuCun1(batchList); - if (jsonArray != null && jsonArray.size() > 0) { - for (int i = 0; i < jsonArray.size(); i++) { - JsonObject jsonObject = jsonArray.get(i).getAsJsonObject(); - String materialCode = jsonObject.has("FMaterialId.FNumber") - ? jsonObject.get("FMaterialId.FNumber").getAsString() - : ""; - double currentStock = jsonObject.has("FBaseQty") ? jsonObject.get("FBaseQty").getAsDouble() : 0.0; - logger.info("MaterialCode: {}, CurrentStock: {}", materialCode, currentStock); - currentStockMap.put(materialCode, currentStock); - } - } - } - - logger.info("得到库存集合 currentStockMap: {}", currentStockMap); - - // 创建一个列表来存储需要补货的库存数据 - List wlStockDataList = new ArrayList<>(); - - // 检查每个安全库存的当前库存是否低于安全库存阈值 - for (SafetyStock safetyStock : safetyStocks) { - String materialCode = safetyStock.getMaterialCode(); - Double currentStock = currentStockMap.get(materialCode); - - // 检查是否已经存在相同物料编码的单据 - if (existingMaterialCodes.contains(materialCode)) { - logger.info("已存在相同物料编码的单据: {}", materialCode); - continue; - } - - if (currentStock != null && currentStock < safetyStock.getMinSafetyStock()) { - WlStockData wlStockData = new WlStockData(); - wlStockData.setMaterialCode(safetyStock.getMaterialCode()); - wlStockData.setMaterialName(safetyStock.getMaterialName()); - wlStockData.setRequiredStock(safetyStock.getMaxSafetyStock()); // 使用 maxSafetyStock - wlStockData.setCurrentStock(currentStock); - wlStockData.setTriggerTime(new Date()); - wlStockData.setCreateTime(new Date()); - wlStockData.setCreateBy("BIMINXia"); - wlStockDataList.add(wlStockData); - } - } - - baseMapper.insertBatch(wlStockDataList); - return wlStockDataList; - } - - public List generateDoc1() { - // 查询到安全库存单据已有的数据 - List existingStockData = baseMapper.selectList(); - Set existingMaterialCodes = existingStockData.stream() - .map(WlStockData::getMaterialCode) - .collect(Collectors.toSet()); - - // 获取安全库存阈值,并存储在映射中 - List safetyStocks = safetyStockMapper.selectList(); - Map safetyStockMap = new HashMap<>(); - Map currentStockMap = new HashMap<>(); - - // 定义批次大小 - int batchSize = 20; - - // 分批处理 SafetyStock - for (int start = 0; start < safetyStocks.size(); start += batchSize) { - int end = Math.min(start + batchSize, safetyStocks.size()); - List batchList = safetyStocks.subList(start, end); - - // 调用 selectKuCun1 方法处理每个批次 - JsonArray jsonArray = selectKuCun1(batchList); - if (jsonArray != null && jsonArray.size() > 0) { - for (int i = 0; i < jsonArray.size(); i++) { - JsonObject jsonObject = jsonArray.get(i).getAsJsonObject(); - String materialCode = jsonObject.has("FMaterialId.FNumber") - ? jsonObject.get("FMaterialId.FNumber").getAsString() - : ""; - double currentStock = jsonObject.has("FBaseQty") ? jsonObject.get("FBaseQty").getAsDouble() : 0.0; - logger.info("MaterialCode: {}, CurrentStock: {}", materialCode, currentStock); - currentStockMap.put(materialCode, currentStock); - } - } - } - - logger.info("得到库存集合 currentStockMap: {}", currentStockMap); - - // 创建一个列表来存储需要补货的库存数据 - List wlStockDataList = new ArrayList<>(); - - // 检查每个安全库存的当前库存是否低于安全库存阈值 - for (SafetyStock safetyStock : safetyStocks) { - String materialCode = safetyStock.getMaterialCode(); - Double currentStock = currentStockMap.get(materialCode); - - // 检查是否已经存在相同物料编码的单据 - if (existingMaterialCodes.contains(materialCode)) { - logger.debug("已存在相同物料编码的单据: {}", materialCode); - continue; - } - - if (currentStock != null && currentStock < safetyStock.getMinSafetyStock()) { - WlStockData wlStockData = new WlStockData(); - wlStockData.setMaterialCode(safetyStock.getMaterialCode()); - wlStockData.setMaterialName(safetyStock.getMaterialName()); - wlStockData.setRequiredStock(safetyStock.getMaxSafetyStock()); // 使用 maxSafetyStock - wlStockData.setCurrentStock(currentStock); - wlStockData.setTriggerTime(new Date()); - wlStockDataList.add(wlStockData); - } - } - - baseMapper.insertBatch(wlStockDataList); - // 生成文档或进行后续处理 - // generateDocument(wlStockDataList); - return wlStockDataList; - } - @Override public List generateDoc() { List safetyStocks = safetyStockMapper.selectList(); if (CollectionUtils.isEmpty(safetyStocks)) { logger.warn("没有找到安全库存数据"); + logMessages("没有找到安全库存数据"); return Collections.emptyList(); } @@ -309,6 +194,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService { }) .exceptionally(e -> { logger.error("处理安全库存数据失败: {}", safetyStock.getMaterialCode(), e); + logMessages("处理安全库存数据失败: " + safetyStock.getMaterialCode()); return null; })) .collect(Collectors.toList()); @@ -321,15 +207,18 @@ public class WlStockDataServiceImpl implements IWlStockDataService { if (!wlStockDataList.isEmpty()) { boolean success = baseMapper.insertBatch(wlStockDataList); logger.info("批量插入{}条数据: {}", wlStockDataList.size(), success); + logMessages("批量插入" + wlStockDataList.size() + "条数据成功"); } return wlStockDataList; } catch (TimeoutException e) { logger.error("生成文档操作超时", e); + logMessages("生成单据操作超时"); throw new ServiceException("操作超时,请稍后重试"); } catch (Exception e) { logger.error("生成文档时发生错误", e); + logMessages("生成单据发生错误: " + e.getMessage()); throw new ServiceException("生成文档失败:" + e.getMessage()); } finally { executor.shutdown(); @@ -344,6 +233,8 @@ public class WlStockDataServiceImpl implements IWlStockDataService { } } + + private WlStockData processWithRetry(SafetyStock safetyStock) { int retryCount = 0; while (retryCount < MAX_RETRIES) { @@ -370,6 +261,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService { private WlStockData processMaterialCode(SafetyStock safetyStock) { if (safetyStock == null || StringUtils.isEmpty(safetyStock.getMaterialCode())) { logger.error("无效的安全库存数据"); + logMessages("无效的安全库存数据"); return null; } @@ -406,7 +298,9 @@ public class WlStockDataServiceImpl implements IWlStockDataService { double availableStock = fSecAVBQty + productionQty + purchaseQty - fSecQty; double minSafetyStock = safetyStock.getMinSafetyStock(); double maxSafetyStock = safetyStock.getMaxSafetyStock(); + logger.debug("物料编码:{},生产订单数量: {}, 采购订单数量: {}, 可用库存: {}",materialCode,productionQty, purchaseQty, availableStock); + logMessages("物料编码:" + materialCode + ",生产订单数量: " + productionQty + ", 采购订单数量: " + purchaseQty + ", 可用库存: " + availableStock); // 如果可用库存低于最小安全库存,创建库存数据记录 if (availableStock < minSafetyStock) { return createWlStockData(safetyStock, availableStock, fSecAVBQty, @@ -415,6 +309,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService { } catch (Exception e) { logger.error("处理物料编码时出错: {}", materialCode, e); + logMessages("处理物料编码时出错: " + materialCode); throw e; // 抛出异常以触发重试机制 } return null; @@ -445,7 +340,98 @@ public class WlStockDataServiceImpl implements IWlStockDataService { return wlStockData; } + public List getInvReserveAnalyzeRpt(String materialCode) { + List rptDTOS = new ArrayList<>(); + K3CloudApi client = new K3CloudApi(); + JsonObject jsonData = new JsonObject(); + jsonData.addProperty("FieldKeys", "FMATERIALNUMBER,FMaterialName,FDemandTypeName,FSecQty,FSecAVBQty"); + jsonData.addProperty("SchemeId", ""); + jsonData.addProperty("StartRow", 0); + jsonData.addProperty("Limit", 2000); + jsonData.addProperty("IsVerifyBaseDataField", "true"); + JsonArray filterArray = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("Left", ""); + filterObject.addProperty("FieldName", "FMATERIALNUMBER"); + filterObject.addProperty("Compare", "67"); + filterObject.addProperty("Value", materialCode); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterArray.add(filterObject); + jsonData.add("FilterString", filterArray); + + JsonObject model = new JsonObject(); + model.addProperty("FStockOrgId", "1"); + + JsonObject beginMaterialId = new JsonObject(); + beginMaterialId.addProperty("FNUMBER", materialCode); + model.add("FBeginMaterialId", beginMaterialId); + + model.addProperty("FDemandType", "PLN_FORECAST,PLN_PLANORDER,PRD_PPBOM,SAL_SaleOrder"); + model.addProperty("FNeedTransOnly", false); + + jsonData.add("Model", model); + + String jsonString = jsonData.toString(); + String formId = "PLN_InvReserveAnalyzeRpt"; + String resultJson = null; + try { + resultJson = client.getSysReportData(formId, jsonString); + } catch (Exception e) { + System.err.println("Error fetching data for materialCode: " + materialCode); + logMessages("Error fetching data for materialCode: " + materialCode); + e.printStackTrace(); + return new ArrayList<>(); + } + + if (resultJson == null) { + System.err.println("No data returned for materialCode: " + materialCode); + logMessages("No data returned for materialCode: " + materialCode); + return new ArrayList<>(); + } + + JsonObject resultObject = new Gson().fromJson(resultJson, JsonObject.class); + JsonArray rows = resultObject.getAsJsonObject("Result").getAsJsonArray("Rows"); + if (rows == null){ + System.err.println("No data returned for materialCode: " + materialCode); + logMessages("No data returned for materialCode: " + materialCode); + return new ArrayList<>(); + } + System.out.println("库存预留单===========>" + rows); + logMessages("库存预留单===========>" + rows); + + for (JsonElement rowElement : rows) { + JsonArray row = rowElement.getAsJsonArray(); + InvReserveAnalyzeRptDTO analyzeRptDTO = new InvReserveAnalyzeRptDTO(); + analyzeRptDTO.setFMATERIALNUMBER(getStringFromJsonArray(row, 0)); + analyzeRptDTO.setFMaterialName(getStringFromJsonArray(row, 1)); + analyzeRptDTO.setFDemandTypeName(getStringFromJsonArray(row, 2)); + analyzeRptDTO.setFSecQty(getDoubleFromJsonArray(row, 3)); + analyzeRptDTO.setFSecAVBQty(getDoubleFromJsonArray(row, 4)); + + rptDTOS.add(analyzeRptDTO); + } + + return rptDTOS; + } + private static String getStringFromJsonArray(JsonArray array, int index) { + return array.size() > index && !array.get(index).isJsonNull() ? array.get(index).getAsString() : ""; + } + + private static double getDoubleFromJsonArray(JsonArray array, int index) { + if (array.size() > index && !array.get(index).isJsonNull()) { + String value = array.get(index).getAsString(); + if (!value.isEmpty()) { + try { + return Double.parseDouble(value); + } catch (NumberFormatException e) { + System.err.println("NumberFormatException for value: " + value); + } + } + } + return 0.0; + } /** * 物料批量查询 */ @@ -537,4 +523,6 @@ public class WlStockDataServiceImpl implements IWlStockDataService { } return resultJsonArray; } + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WorkProcedureServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WorkProcedureServiceImpl.java index 8bd1f15..c530375 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WorkProcedureServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WorkProcedureServiceImpl.java @@ -217,62 +217,73 @@ public class WorkProcedureServiceImpl implements IWorkProcedureService { @Override public List getGongXuTasks(String text) { + // 日期格式化器,用于格式化日期 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); List tasks = new ArrayList<>(); + // 获取所有生产计划 List productionPlans = productionPlanMapper.selectList(null); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + // 遍历生产计划并创建父任务 for (ProductionPlan plan : productionPlans) { ProductctionPlanGatteDto parentTask = new ProductctionPlanGatteDto(); - parentTask.setId(plan.getId()); - parentTask.setText(plan.getProductionCode()); + parentTask.setId(plan.getId()); // 设置任务ID + parentTask.setText(plan.getProductionCode()); // 设置任务名称 LocalDate startDate = null; LocalDate endDate = null; + // 设置开始日期 if (plan.getDrawingPlanTime() != null) { startDate = LocalDate.parse(sdf.format(plan.getDrawingPlanTime()), dateFormatter); parentTask.setStart_date(startDate.toString()); } + // 设置结束日期 if (plan.getTaskCompletionTime() != null) { endDate = LocalDate.parse(sdf.format(plan.getTaskCompletionTime()), dateFormatter); parentTask.setEnd_date(endDate.toString()); } + // 计算并设置持续时间 if (startDate != null && endDate != null) { long duration = ChronoUnit.DAYS.between(startDate, endDate); parentTask.setDuration(duration); } - parentTask.setOpen(true); // 默认打开 - parentTask.setToolTipsTxt(plan.getFigureName()); - parentTask.setProgress(1L); // 需要自行处理 - parentTask.setStatus("yellow"); + + parentTask.setOpen(true); // 默认展开 + parentTask.setToolTipsTxt(plan.getFigureName()); // 设置工具提示文本 + parentTask.setProgress(1L); // 设置进度 + parentTask.setStatus("yellow"); // 设置状态 parentTask.setParent(null); // 父任务没有parent - tasks.add(parentTask); + tasks.add(parentTask); // 添加到任务列表 } - //查询子任务 + // 查询子任务 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("text", text); List workProcedureVos = baseMapper.selectVoList(queryWrapper); + + // 遍历工序任务并创建子任务 for (WorkProcedureVo procedure : workProcedureVos) { ProductctionPlanGatteDto subTask = new ProductctionPlanGatteDto(); - subTask.setId(procedure.getId()); - subTask.setText(procedure.getText()); + subTask.setId(procedure.getId()); // 设置子任务ID + subTask.setText(procedure.getText()); // 设置子任务名称 + + // 设置子任务的开始日期和持续时间 if (procedure.getStartDate() != null) { - subTask.setStart_date(sdf.format(procedure.getStartDate())); - subTask.setDuration(procedure.getDuration()); - Calendar instance = Calendar.getInstance(); + subTask.setStart_date(sdf.format(procedure.getStartDate())); + subTask.setDuration(procedure.getDuration()); + Calendar instance = Calendar.getInstance(); instance.setTime(procedure.getStartDate()); instance.add(Calendar.DAY_OF_MONTH, procedure.getDuration().intValue()); - - subTask.setEnd_date(sdf.format(instance.getTime())); - }else{ - continue; + subTask.setEnd_date(sdf.format(instance.getTime())); // 设置结束日期 + } else { + continue; // 如果没有开始日期,跳过该任务 } + // 根据工序名称设置类型 switch (procedure.getText()) { case "下 料": subTask.setType(2); @@ -301,14 +312,122 @@ public class WorkProcedureServiceImpl implements IWorkProcedureService { default: subTask.setType(1); // 默认类型 } - subTask.setToolTipsTxt(procedure.getToolTipsTxt()); - subTask.setProgress(1L); - subTask.setStatus(procedure.getStatus()); - subTask.setParent(procedure.getPlanId()); - tasks.add(subTask); + + subTask.setToolTipsTxt(procedure.getToolTipsTxt()); // 设置工具提示文本 + subTask.setProgress(1L); // 设置进度 + subTask.setStatus(procedure.getStatus()); // 设置状态 + subTask.setParent(procedure.getPlanId()); // 设置父任务ID + tasks.add(subTask); // 添加到任务列表 } + + // 返回任务列表,如果为空则返回空列表 return tasks.isEmpty() ? Collections.emptyList() : tasks; } + public List getGongXuTasks1(String text) { + // 日期格式化器,用于格式化日期 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + List tasks = new ArrayList<>(); + // 获取所有生产计划 + List productionPlans = productionPlanMapper.selectList(null); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + // 遍历生产计划并创建父任务 + for (ProductionPlan plan : productionPlans) { + ProductctionPlanGatteDto parentTask = new ProductctionPlanGatteDto(); + parentTask.setId(plan.getId()); // 设置任务ID + parentTask.setText(plan.getProductionCode()); // 设置任务名称 + + LocalDate startDate = null; + LocalDate endDate = null; + + // 设置开始日期 + if (plan.getDrawingPlanTime() != null) { + startDate = LocalDate.parse(sdf.format(plan.getDrawingPlanTime()), dateFormatter); + parentTask.setStart_date(startDate.toString()); + } + + // 设置结束日期 + if (plan.getTaskCompletionTime() != null) { + endDate = LocalDate.parse(sdf.format(plan.getTaskCompletionTime()), dateFormatter); + parentTask.setEnd_date(endDate.toString()); + } + + // 计算并设置持续时间 + if (startDate != null && endDate != null) { + long duration = ChronoUnit.DAYS.between(startDate, endDate); + parentTask.setDuration(duration); + } + + parentTask.setOpen(true); // 默认展开 + parentTask.setToolTipsTxt(plan.getFigureName()); // 设置工具提示文本 + parentTask.setProgress(1L); // 设置进度 + parentTask.setStatus("yellow"); // 设置状态 + parentTask.setParent(null); // 父任务没有parent + tasks.add(parentTask); // 添加到任务列表 + } + + // 查询子任务 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("text", text); + List workProcedureVos = baseMapper.selectVoList(queryWrapper); + + // 遍历工序任务并创建子任务 + for (WorkProcedureVo procedure : workProcedureVos) { + ProductctionPlanGatteDto subTask = new ProductctionPlanGatteDto(); + subTask.setId(procedure.getId()); // 设置子任务ID + subTask.setText(procedure.getText()); // 设置子任务名称 + + // 设置子任务的开始日期和持续时间 + if (procedure.getStartDate() != null) { + subTask.setStart_date(sdf.format(procedure.getStartDate())); + subTask.setDuration(procedure.getDuration()); + Calendar instance = Calendar.getInstance(); + instance.setTime(procedure.getStartDate()); + instance.add(Calendar.DAY_OF_MONTH, procedure.getDuration().intValue()); + subTask.setEnd_date(sdf.format(instance.getTime())); // 设置结束日期 + } else { + continue; // 如果没有开始日期,跳过该任务 + } + + // 根据工序名称设置类型 + switch (procedure.getText()) { + case "下 料": + subTask.setType(2); + break; + case "铆 焊": + subTask.setType(3); + break; + case "热 处 理": + subTask.setType(4); + break; + case "普车钻床": + subTask.setType(5); + break; + case "走心 机": + subTask.setType(6); + break; + case "龙门立加": + subTask.setType(7); + break; + case "表面处理": + subTask.setType(8); + break; + case "外购 件": + subTask.setType(9); + break; + default: + subTask.setType(1); // 默认类型 + } + + subTask.setToolTipsTxt(procedure.getToolTipsTxt()); // 设置工具提示文本 + subTask.setProgress(1L); // 设置进度 + subTask.setStatus(procedure.getStatus()); // 设置状态 + subTask.setParent(procedure.getPlanId()); // 设置父任务ID + tasks.add(subTask); // 添加到任务列表 + } + + // 返回任务列表,如果为空则返回空列表 + return tasks.isEmpty() ? Collections.emptyList() : tasks; + } } diff --git a/ruoyi-system/src/main/resources/mapper/system/WorkProcedureMapper.xml b/ruoyi-system/src/main/resources/mapper/system/WorkProcedureMapper.xml index ed4afd8..568c655 100644 --- a/ruoyi-system/src/main/resources/mapper/system/WorkProcedureMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/WorkProcedureMapper.xml @@ -17,6 +17,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +