diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/UpdatePriorityDTO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/UpdatePriorityDTO.java index 32a962df..6b77b937 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/UpdatePriorityDTO.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/UpdatePriorityDTO.java @@ -18,4 +18,7 @@ public class UpdatePriorityDTO { @Schema(description = "需求交期") private Date demandDate; + @Schema(description = "优先级;1.正常,2.项目要求日期急件,3.合同急件,4.绩效零件,5.调度标注急件") + private Integer priority; + } diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/WorkOrderDTO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/WorkOrderDTO.java index eeee9982..a1924db5 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/WorkOrderDTO.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/dto/WorkOrderDTO.java @@ -10,7 +10,7 @@ import lombok.Data; @Data public class WorkOrderDTO { - @Schema(description = "订单类型:1-热表,2-烧结,3-玻璃饼,4-壳体,5-插针,6-石墨模") + @Schema(description = "订单类型:12001-热表,12002-烧结,12003-玻璃饼,12004-壳体,12005-插针,12006-石墨模") private String yieldType; @Schema(description = "运行状态:1.正常,2.已下达,3.加工中,4.检验中,13.审理中,14.返工中,15.已完工,21已关闭") diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkOrder.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkOrder.java index 50bca402..75e4d871 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkOrder.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkOrder.java @@ -8,9 +8,9 @@ import org.springblade.core.mp.base.BaseEntity; import java.io.Serial; import java.math.BigDecimal; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * 车间订单表 实体类 @@ -67,6 +67,9 @@ public class WorkOrder extends BaseEntity { * 已关闭 */ public static Integer RUN_STATUS_VOIDED = 21; + + public static final Set RUNNING_ORDER_STATUS = Set.of(RUN_STATUS_ISSUED, RUN_STATUS_RECEIVE); + /** * 正常 */ diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkPlan.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkPlan.java index fec9add8..5a5d3b93 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkPlan.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkPlan.java @@ -162,27 +162,27 @@ public class WorkPlan extends BaseEntity { /** * */ - @Schema(description = "") + @Schema(description = "绑定状态") private Short bindStatus; /** * */ - @Schema(description = "") + @Schema(description = "报工数量") private Double workQty; /** * */ - @Schema(description = "") + @Schema(description = "接收人") private Long receiveMan; /** * */ - @Schema(description = "") + @Schema(description = "加工工时") private BigDecimal hours; /** * */ - @Schema(description = "") + @Schema(description = "工艺能力") private Long caId; /** * 打印标记类型:1、生产过程 @@ -192,7 +192,7 @@ public class WorkPlan extends BaseEntity { /** * */ - @Schema(description = "") + @Schema(description = "附属班组") private Long subsidiaryTeam; /** * 检验颜色标识 @@ -220,14 +220,14 @@ public class WorkPlan extends BaseEntity { @Schema(description = "工艺文件编号/版本号") private String papers; /** - * + * 引用文件/版本号 */ - @Schema(description = "") + @Schema(description = "引用文件/版本号") private String referenceFile; /** - * 引用文件/版本号 + * 外协订单 */ - @Schema(description = "引用文件/版本号") + @Schema(description = "外协订单") private String wxNo; /** diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/enums/WorkOrderEnum.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/enums/WorkOrderEnum.java new file mode 100644 index 00000000..84c82818 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/enums/WorkOrderEnum.java @@ -0,0 +1,65 @@ +package org.springblade.desk.produce.pojo.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springblade.core.tool.utils.ObjectUtil; +import org.springblade.core.tool.utils.StringPool; + +import java.util.Arrays; + +/** + * 车间订单枚举 + * + * @author litao + * @date 2026-2-4 + */ +@Getter +@AllArgsConstructor +public enum WorkOrderEnum { + EMPTY(StringPool.EMPTY, -1), + + /** + * 状态枚举 + */ + RUN_STATUS_NORMAL("未下达", 1), + RUN_STATUS_ISSUED("已下达", 2), + RUN_STATUS_RECEIVE("加工中", 3), + RUN_STATUS_CHECK("检验中", 4), + RUN_STATUS_CRAFT_CHANGE("工艺变更", 5), + RUN_STATUS_HEAR("审理中", 13), + RUN_STATUS_COMPLETED("已完工", 15), + RUN_STATUS_HANDOVER("已交接", 17), + RUN_STATUS_REWORK("返工", 19), + RUN_STATUS_SCRAP("报废", 20), + RUN_STATUS_VOIDED("已关闭", 21); + final String name; + final int category; + + /** + * 匹配枚举值 + * + * @param name 名称 + * @return BladeUserEnum + */ + public static WorkOrderEnum of(String name) { + return Arrays.stream(WorkOrderEnum.values()) + .filter(userEnum -> userEnum.getName().equalsIgnoreCase(name != null ? name : "web")) + .findFirst() + // 在没有找到匹配项时返回默认值 + .orElse(WorkOrderEnum.EMPTY); + } + + /** + * 根据值获取名称 + * + * @param category + * @return + */ + public static String getName(int category) { + WorkOrderEnum item = Arrays.stream(WorkOrderEnum.values()) + .filter(enumItem -> enumItem.getCategory() == category) + .findFirst() + .orElse(null); + return ObjectUtil.isEmpty(item) ? StringPool.EMPTY : item.getName(); + } +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/vo/CacheWorkOrderVO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/vo/CacheWorkOrderVO.java new file mode 100644 index 00000000..d856a9c2 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/vo/CacheWorkOrderVO.java @@ -0,0 +1,101 @@ +package org.springblade.desk.produce.pojo.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 订单缓存 视图实体类 + * + * @author litao + * @since 2026-2-3 + */ +@Data +public class CacheWorkOrderVO { + + @Schema(description = "车间订单ID") + private Long woId; + + @Schema(description = "生产订单ID") + private Long yoId; + + @Schema(description = "主加工单位:班组") + private String mainTsName; + + @Schema(description = "主加工单位:外协") + private String mainOcName; + + @Schema(description = "班组id") + private String makeTeam; + + @Schema(description = "外协id") + private String ppsOcId; + + @Schema(description = "班组") + private String tsName; + + @Schema(description = "外协") + private String ocName; + + @Schema(description = "工序") + private String ppsName; + + @Schema(description = "生产订单号") + private String yoCode; + + @Schema(description = "计划单号") + private String ypCode; + + @Schema(description = "零件号") + private String partCode; + + @Schema(description = "生产标识") + private String productIdent; + + @Schema(description = "产品名称") + private String partName; + + @Schema(description = "镀种信息") + private String plate; + + @Schema(description = "产品型号") + private String productType; + + @Schema(description = "需求部门") + private String useDept; + + @Schema(description = "面积(dm²)") + private String totalArea; + + @Schema(description = "单批次面积") + private String area; + + @Schema(description = "调度员") + private String dispatcherName; + + @Schema(description = "未入库数量") + private Integer notInQty; + + @Schema(description = "下序id") + private Integer ppsIdNext; + + @Schema(description = "下序名称") + private Integer ppsNameNext; + + @Schema(description = "下一班组id") + private Integer makeTeamNext; + + @Schema(description = "下一班组") + private Integer makeTeamNextName; + + @Schema(description = "接收人员id") + private Integer receiveUser; + + @Schema(description = "接收人员") + private Integer receiveUserNamr; + + @Schema(description = "工序集合") + private List processList; + +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/vo/CacheWorkPlanVO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/vo/CacheWorkPlanVO.java new file mode 100644 index 00000000..040da7ba --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/vo/CacheWorkPlanVO.java @@ -0,0 +1,103 @@ +package org.springblade.desk.produce.pojo.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 工序缓存 视图实体类 + * + * @author litao + * @since 2026-2-3 + */ +@Data +public class CacheWorkPlanVO { + + @Schema(description = "车间订单") + private Long woId; + + @Schema(description = "工序") + private Long ppsId; + + @Schema(description = "工序号") + private String orders; + + @Schema(description = "工序描述") + private String makeMemo; + + @Schema(description = "工时定额") + private BigDecimal hourQuota; + + @Schema(description = "计划开始") + private LocalDateTime startTime; + + @Schema(description = "计划结束") + private LocalDateTime endTime; + + @Schema(description = "加工班组") + private Long makeTeam; + + @Schema(description = "是否外协") + private String oem; + + @Schema(description = "外协商") + private Long ocId; + + @Schema(description = "上一道") + private Long frontWpId; + + @Schema(description = "下一道") + private Long nextWpId; + + @Schema(description = "试验数量") + private Double testQty; + + @Schema(description = "合格数量") + private Double qualifiedQty; + + @Schema(description = "报废数量") + private Double scrapQty; + + @Schema(description = "不合格数量") + private Integer unqualifiedQty; + + @Schema(description = "实际开始") + private Date factStartTime; + + @Schema(description = "实际结束") + private Date factEndTime; + + @Schema(description = "报工数量") + private Double workQty; + + @Schema(description = "接收人") + private Long receiveMan; + + @Schema(description = "加工工时") + private BigDecimal hours; + + @Schema(description = "工艺能力") + private Long caId; + + @Schema(description = "附属班组") + private Long subsidiaryTeam; + + @Schema(description = "消耗数量") + private Double lossQty; + + @Schema(description = "金额") + private BigDecimal wpMoney; + + @Schema(description = "工艺文件编号/版本号") + private String papers; + + @Schema(description = "引用文件/版本号") + private String referenceFile; + + @Schema(description = "作业中心") + private Long workCenterId; + +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/DeskApplication.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/DeskApplication.java index ae79ff8e..750523cd 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/DeskApplication.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/DeskApplication.java @@ -1,34 +1,10 @@ -/** - * BladeX Commercial License Agreement - * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. - *

- * Use of this software is governed by the Commercial License Agreement - * obtained after purchasing a license from BladeX. - *

- * 1. This software is for development use only under a valid license - * from BladeX. - *

- * 2. Redistribution of this software's source code to any third party - * without a commercial license is strictly prohibited. - *

- * 3. Licensees may copyright their own code but cannot use segments - * from this software for such purposes. Copyright of this software - * remains with BladeX. - *

- * Using this software signifies agreement to this License, and the software - * must not be used for illegal purposes. - *

- * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is - * not liable for any claims arising from secondary or illegal development. - *

- * Author: Chill Zhuang (bladejava@qq.com) - */ package org.springblade.desk; import org.springblade.core.cloud.client.BladeCloudApplication; import org.springblade.core.launch.BladeApplication; import org.springblade.core.launch.constant.AppConstant; -import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; /** * Desk启动器 @@ -36,6 +12,8 @@ import org.springframework.scheduling.annotation.EnableScheduling; * @author Chill */ @BladeCloudApplication +@EnableCaching +@EnableAsync public class DeskApplication { public static void main(String[] args) { diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/IPrReworkProcessService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/IPrReworkProcessService.java index 0f92fe0d..ceda52ed 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/IPrReworkProcessService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/IPrReworkProcessService.java @@ -25,12 +25,15 @@ */ package org.springblade.desk.dashboard.service; +import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.Wrapper; import org.springblade.desk.dashboard.pojo.entity.PrReworkProcessEntity; import org.springblade.desk.dashboard.pojo.vo.PrReworkProcessVO; import org.springblade.desk.dashboard.excel.PrReworkProcessExcel; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseService; +import org.springblade.erpdata.pojo.dto.ReworkProcessDTO; + import java.util.List; /** @@ -66,4 +69,6 @@ public interface IPrReworkProcessService extends BaseService selectPrReworkProcess(String reworkOrder, String partCode, String batchNo); + + JSONArray treeProcess(ReworkProcessDTO prReworkProcess); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/impl/PrReworkProcessServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/impl/PrReworkProcessServiceImpl.java index a98bcac9..07cedd07 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/impl/PrReworkProcessServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/impl/PrReworkProcessServiceImpl.java @@ -25,12 +25,13 @@ */ package org.springblade.desk.dashboard.service.impl; -import org.checkerframework.checker.units.qual.A; +import com.alibaba.fastjson.JSONArray; import org.springblade.desk.dashboard.pojo.entity.PrReworkProcessEntity; import org.springblade.desk.dashboard.pojo.vo.PrReworkProcessVO; import org.springblade.desk.dashboard.excel.PrReworkProcessExcel; import org.springblade.desk.dashboard.mapper.PrReworkProcessMapper; import org.springblade.desk.dashboard.service.IPrReworkProcessService; +import org.springblade.erpdata.pojo.dto.ReworkProcessDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; @@ -70,4 +71,9 @@ public class PrReworkProcessServiceImpl extends BaseServiceImpl workOrderByCardNo(String cardNo) { return R.data(deductionPreserveService.workOrderByCardNo(cardNo)); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/RbProduceManageController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/RbProduceManageController.java index 85895337..087a5260 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/RbProduceManageController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/RbProduceManageController.java @@ -13,9 +13,11 @@ import org.springblade.core.tool.api.R; import org.springblade.desk.produce.pojo.dto.*; import org.springblade.desk.produce.pojo.entity.WorkOrder; import org.springblade.desk.produce.pojo.vo.BatchPrepareVO; +import org.springblade.desk.produce.pojo.vo.CacheWorkOrderVO; import org.springblade.desk.produce.pojo.vo.WorkOrderVO; import org.springblade.desk.produce.pojo.vo.WorkPlanRunVO; import org.springblade.desk.produce.service.IWorkOrderService; +import org.springblade.desk.produce.service.impl.OrderCacheService; import org.springblade.desk.produce.wrapper.WorkOrderWrapper; import org.springframework.web.bind.annotation.*; @@ -33,6 +35,8 @@ public class RbProduceManageController extends BladeController { private final IWorkOrderService workOrderService; + private final OrderCacheService orderCacheService; + @GetMapping("/page") @ApiOperationSupport(order = 1) @Operation(summary = "车间订单列表分页", description = "传入WorkOrderVO") @@ -92,10 +96,17 @@ public class RbProduceManageController extends BladeController { @Operation(summary = "更改车间订单优先级", description = "传入WorkOrder") public R updatePriority(@RequestBody UpdatePriorityDTO updatePriorityDTO) { WorkOrder wo = workOrderService.getById(updatePriorityDTO.getWoId()); - wo.setPriority(WorkOrder.PRIORITY_SCH_IMP); +// wo.setPriority(WorkOrder.PRIORITY_SCH_IMP); + wo.setPriority(updatePriorityDTO.getPriority()); wo.setDemandDate(updatePriorityDTO.getDemandDate()); return R.data(workOrderService.updateById(wo)); } + @GetMapping(value = "/getWorkOrderCache/{woId}") + @ApiOperationSupport(order = 9) + @Operation(summary = "缓存获取订单相关数据", description = "传入车间订单ID") + public R getWorkOrderCache(@PathVariable Long woId) { + return R.data(orderCacheService.getOrderFromCache(woId)); + } } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/ReworkProcessController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/ReworkProcessController.java new file mode 100644 index 00000000..a340ebc0 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/ReworkProcessController.java @@ -0,0 +1,49 @@ +package org.springblade.desk.produce.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import org.springblade.core.boot.ctrl.BladeController; +import org.springblade.core.mp.support.Condition; +import org.springblade.core.mp.support.Query; +import org.springblade.core.tool.api.R; +import org.springblade.desk.dashboard.service.IPrReworkProcessService; +import org.springblade.erpdata.feign.IErpDataProduceClient; +import org.springblade.erpdata.pojo.dto.ReworkProcessDTO; +import org.springblade.erpdata.pojo.vo.ReworkProcessVO; +import org.springframework.web.bind.annotation.*; + +/** + * 返工订单 + * + * @author litao + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/ReworkProcess") +@Tag(name = "返工订单", description = "接口") +public class ReworkProcessController extends BladeController { + + private final IErpDataProduceClient erpDataProduceClient; + + private final IPrReworkProcessService reworkProcessService; + + @GetMapping("/loadReworkOrder") + @ApiOperationSupport(order = 1) + @Operation(summary = "erp查询返工订单", description = "传入ReworkProcessDTO") + public R> page(ReworkProcessDTO prReworkProcess, Query query) { + prReworkProcess.setQuery(query); + return erpDataProduceClient.loadReworkOrder(prReworkProcess); + } + +// @GetMapping("/treeProcess") +// @ApiOperationSupport(order = 2) +// @Operation(summary = "查询返工工序树", description = "") +// public R taskComplete(@RequestBody ReworkProcessDTO prReworkProcess) { +// return R.data(reworkProcessService.treeProcess(prReworkProcess)); +// } + +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/SjProduceManageController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/SjProduceManageController.java index 41780dc2..56170858 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/SjProduceManageController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/controller/SjProduceManageController.java @@ -43,21 +43,21 @@ public class SjProduceManageController extends BladeController { @ApiOperationSupport(order = 1) @Operation(summary = "烧结配套齐套流转列表", description = "传入WorkOrderVO") public R> page(YieldOrderDTO yieldOrder, Query query) { - Integer moldFlag = yieldOrder.getMoldFlag(); - Integer kitFlag = yieldOrder.getKitFlag(); - if (moldFlag == null || kitFlag == null) { - throw new ServiceException("缺少必要参数:moldFlag、kitFlag"); - } +// Integer moldFlag = yieldOrder.getMoldFlag(); +// Integer kitFlag = yieldOrder.getKitFlag(); +// if (moldFlag == null || kitFlag == null) { +// throw new ServiceException("缺少必要参数:moldFlag、kitFlag"); +// } LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(YieldOrder::getStatus, 10000); queryWrapper.and(wrapper -> wrapper.eq(YieldOrder::getYieldType, 12002).or().like(YieldOrder::getMemo, "铆卡钉")); - if (moldFlag == 0) { - queryWrapper.and(wrapper -> wrapper.isNull(YieldOrder::getSjMoldPreparation).or().ne(YieldOrder::getSjMoldPreparation, YieldOrder.SJ_MOLD_PREPARATION_2)); - } else if (moldFlag == 1 && kitFlag == 0) { - queryWrapper.and(wrapper -> wrapper.isNull(YieldOrder::getSjKitPreparation).ne(YieldOrder::getSjKitPreparation, YieldOrder.SJ_KIT_PREPARATION_2)); - } else if (moldFlag == 1 && kitFlag == 1) { - queryWrapper.eq(YieldOrder::getSjKitPreparation, YieldOrder.SJ_KIT_PREPARATION_2); - } +// if (moldFlag == 0) { +// queryWrapper.and(wrapper -> wrapper.isNull(YieldOrder::getSjMoldPreparation).or().ne(YieldOrder::getSjMoldPreparation, YieldOrder.SJ_MOLD_PREPARATION_2)); +// } else if (moldFlag == 1 && kitFlag == 0) { +// queryWrapper.and(wrapper -> wrapper.isNull(YieldOrder::getSjKitPreparation).ne(YieldOrder::getSjKitPreparation, YieldOrder.SJ_KIT_PREPARATION_2)); +// } else if (moldFlag == 1 && kitFlag == 1) { +// queryWrapper.eq(YieldOrder::getSjKitPreparation, YieldOrder.SJ_KIT_PREPARATION_2); +// } queryWrapper.like(StringUtils.isNotBlank(yieldOrder.getYpCode()), YieldOrder::getYpCode, yieldOrder.getYpCode()); queryWrapper.like(StringUtils.isNotBlank(yieldOrder.getCardNo()), YieldOrder::getCardNo, yieldOrder.getCardNo()); queryWrapper.like(StringUtils.isNotBlank(yieldOrder.getPartCode()), YieldOrder::getPartCode, yieldOrder.getPartCode()); diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/listener/CacheInitListener.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/listener/CacheInitListener.java new file mode 100644 index 00000000..790e40c4 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/listener/CacheInitListener.java @@ -0,0 +1,28 @@ +package org.springblade.desk.produce.listener; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.desk.produce.service.impl.OrderCacheService; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +/** + * @author litao + */ +@Component +@RequiredArgsConstructor +@Slf4j +public class CacheInitListener { + + private final OrderCacheService orderCacheService; + + @Async + @EventListener(ApplicationReadyEvent.class) + public void initCacheAfterReady() { + log.info("===== SpringBoot3 ApplicationReadyEvent 触发:开始初始化缓存 ====="); + orderCacheService.initRunningOrderCache(); + log.info("===== SpringBoot3 ApplicationReadyEvent 触发:缓存初始化完成 ====="); + } +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/WorkOrderMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/WorkOrderMapper.xml index 1a866a27..a17597fe 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/WorkOrderMapper.xml +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/WorkOrderMapper.xml @@ -37,7 +37,7 @@ mwo.OC_ID ocId, mwp.MAKE_TEAM makeTeam, mwp.OC_ID ppsOcId, - mwp.PPS_ID ppsId, + bpe.NAME ppsName, mwo.SEND_DOWN_TIME sendDownTime, mwo.WO_CODE woCode, myo.YO_CODE yoCode, @@ -75,6 +75,7 @@ LEFT JOIN MES_YIELD_ORDER myo ON mwo.YO_ID = myo.ID LEFT JOIN MES_WORK_PLAN mwp ON mwo.WP_ID = mwp.ID LEFT JOIN MES_WORK_PLAN nmwp ON mwp.NEXT_WP_ID = nmwp.ID + LEFT JOIN BS_PROCESS_SET bpe ON mwp.PPS_ID = bpe.ID mwo.is_deleted = 0 diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IWorkOrderService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IWorkOrderService.java index aa3d3d9c..1a69099a 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IWorkOrderService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IWorkOrderService.java @@ -9,10 +9,7 @@ import org.springblade.desk.produce.pojo.dto.WorkOrderDTO; import org.springblade.desk.produce.pojo.entity.WorkOrder; import org.springblade.desk.produce.pojo.entity.WorkOrderRun; import org.springblade.desk.produce.pojo.entity.WorkPlanRun; -import org.springblade.desk.produce.pojo.vo.BatchPrepareVO; -import org.springblade.desk.produce.pojo.vo.QueryByReadStatusVO; -import org.springblade.desk.produce.pojo.vo.WorkOrderVO; -import org.springblade.desk.produce.pojo.vo.WorkPlanRunVO; +import org.springblade.desk.produce.pojo.vo.*; import java.util.List; @@ -55,4 +52,8 @@ public interface IWorkOrderService extends BaseService { boolean setReadStatus(String woIds); WorkOrder getWorkOrderByCardNo(String cardNo); + + List selectAllRunningOrder(); + + List selectProcessByOrderIds(List orderIds); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderCacheService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderCacheService.java new file mode 100644 index 00000000..931270dd --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderCacheService.java @@ -0,0 +1,173 @@ +package org.springblade.desk.produce.service.impl; + +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.desk.produce.pojo.entity.WorkOrder; +import org.springblade.desk.produce.pojo.vo.CacheWorkOrderVO; +import org.springblade.desk.produce.pojo.vo.CacheWorkPlanVO; +import org.springblade.desk.produce.service.IWorkOrderService; +import org.springframework.beans.BeanUtils; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; + +/** + * 订单本地缓存核心服务:封装缓存初始化、查询、更新、删除,统一管理缓存操作 + * @author litao + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class OrderCacheService { + + private final IWorkOrderService workOrderService; + + // 注入Spring缓存管理器(核心新增:用于手动操作缓存) + private final CacheManager cacheManager; + + // 细粒度并发锁:key=订单ID,value=对应锁对象 → 仅对同一订单加锁,不影响其他订单(高性能) + private final Map orderLockMap = new ConcurrentHashMap<>(); + + // 声明订单缓存实例(初始化后赋值,避免多次获取) + private Cache runningOrderCache; + + // 初始化缓存实例(项目启动后执行,仅一次) + @PostConstruct + public void initCacheInstance() { + // 获取配置文件中定义的runningOrderCache缓存实例 + this.runningOrderCache = cacheManager.getCache("runningOrderCache"); + } + + // ====================== 核心缓存注解:贴合Caffeine配置 ====================== + // 缓存名称:runningOrderCache(与application.yml一致) + // 缓存Key:#orderId(订单ID,精准映射) + + /** + * 从缓存查询订单(优先走缓存,无则查库并加载到缓存) + * @Cacheable:缓存不存在时执行方法体,存在则直接返回缓存 + */ + @Cacheable(cacheNames = "runningOrderCache", key = "#orderId", unless = "#result == null") + public CacheWorkOrderVO getOrderFromCache(Long orderId) { + // 缓存不存在时,查库加载最新数据并返回(自动存入缓存) + return loadOrderFromDB(orderId); + } + + /** + * 更新缓存:订单/工序修改后,同步更新缓存(数据库已先更新) + * @CachePut:无论缓存是否存在,都会执行方法体并将结果更新到缓存 → 保证缓存与数据库一致 + */ + @CachePut(cacheNames = "runningOrderCache", key = "#orderId", unless = "#result == null") + public CacheWorkOrderVO updateOrderCache(Long orderId) { + // 先加锁,防止多线程同时更新同一订单缓存 + ReentrantLock lock = getOrderLock(orderId); + lock.lock(); + try { + // 查库获取最新数据,更新到缓存 + return loadOrderFromDB(orderId); + } finally { + // 必须释放锁,避免死锁 + lock.unlock(); + } + } + + /** + * 删除缓存:订单变为非运行中状态(完成/取消)时,从缓存移除 + * @CacheEvict:删除指定Key的缓存 + */ + @CacheEvict(cacheNames = "runningOrderCache", key = "#orderId") + public void removeOrderCache(Long orderId) { + // 方法体可留空,注解自动完成删除 + log.info("订单[{}]已变为非运行中状态,从本地缓存移除", orderId); + } + + /** + * 批量删除缓存(可选:如批量更新订单状态时使用) + */ + @CacheEvict(cacheNames = "runningOrderCache", allEntries = false) + public void removeBatchOrderCache(Long[] orderIds) { + // 注解中#orderIds为数组,自动遍历删除对应Key的缓存 + } + + // ====================== 启动初始化缓存:加载所有运行中订单+工序 ====================== + public void initRunningOrderCache() { + log.info("开始初始化运行中订单本地缓存..."); + // 1. 查库:获取所有运行中订单 + List runningOrderList = workOrderService.selectAllRunningOrder(); + if (CollectionUtils.isEmpty(runningOrderList)) { + log.error("无运行中订单,缓存初始化完成"); + return; + } + // 2. 提取订单ID列表,批量查询所有关联工序(避免N+1) + List orderIds = runningOrderList.stream().map(WorkOrder::getId).collect(Collectors.toList()); + List allProcessList = workOrderService.selectProcessByOrderIds(orderIds); + // 工序按订单ID分组:key=订单ID,value=对应工序列表 + Map> processGroupMap = allProcessList.stream().collect(Collectors.groupingBy(CacheWorkPlanVO::getWoId)); + + // 3. 组装缓存VO,批量加载到本地缓存 + for (WorkOrder order : runningOrderList) { + Long orderId = order.getId(); + // 加锁初始化单个订单缓存,避免与启动后的业务更新并发 + ReentrantLock lock = getOrderLock(orderId); + lock.lock(); + try { + CacheWorkOrderVO cacheVO = assembleOrderCacheVO(order, processGroupMap.getOrDefault(orderId, new ArrayList<>())); + // 调用updateOrderCache,利用@CachePut将数据存入缓存 +// updateOrderCache(orderId); + // 手动存入缓存:直接用缓存实例put,无二次查库(核心优化) + runningOrderCache.put(orderId, cacheVO); + } finally { + lock.unlock(); + } + } + log.info("运行中订单本地缓存初始化完成,共加载[{}]个订单", runningOrderList.size()); + } + + // ====================== 私有工具方法:抽离通用逻辑 ====================== + /** + * 根据订单ID查库,加载订单+关联工序的最新数据 + */ + private CacheWorkOrderVO loadOrderFromDB(Long orderId) { + // 1. 查订单主信息 + WorkOrder order = workOrderService.getById(orderId); + if (order == null) { + return null; + } + // 非运行中订单,直接返回null(不会存入缓存) + Integer orderStatus = order.getRunStatus(); + if (orderStatus == null || !WorkOrder.RUNNING_ORDER_STATUS.contains(orderStatus)) { + return null; + } + // 2. 查关联工序 + List processList = workOrderService.selectProcessByOrderIds(Collections.singletonList(orderId)); + // 3. 组装VO + return assembleOrderCacheVO(order, processList); + } + + /** + * 组装订单缓存VO + */ + private CacheWorkOrderVO assembleOrderCacheVO(WorkOrder order, List processList) { + CacheWorkOrderVO cacheVO = new CacheWorkOrderVO(); + BeanUtils.copyProperties(order, cacheVO); + cacheVO.setProcessList(processList); + return cacheVO; + } + + /** + * 获取订单对应的锁对象(ConcurrentHashMap保证线程安全) + */ + private ReentrantLock getOrderLock(Long orderId) { + // 不存在则创建新锁,存在则返回已有锁 + return orderLockMap.computeIfAbsent(orderId, k -> new ReentrantLock()); + } +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderDeclareServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderDeclareServiceImpl.java index 76deef9b..80a9dfb7 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderDeclareServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/OrderDeclareServiceImpl.java @@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; -import org.springblade.core.tool.api.R; import org.springblade.desk.produce.mapper.OrderDeclareMapper; import org.springblade.desk.produce.pojo.dto.SaveDeclareDto; import org.springblade.desk.produce.pojo.entity.*; diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/WorkOrderServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/WorkOrderServiceImpl.java index 2d969ae3..8acdf272 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/WorkOrderServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/WorkOrderServiceImpl.java @@ -460,6 +460,23 @@ public class WorkOrderServiceImpl extends BaseServiceImpl selectAllRunningOrder() { + return this.list(Wrappers.lambdaQuery(WorkOrder.class).eq(WorkOrder::getRunStatus, WorkOrder.RUN_STATUS_RECEIVE)); + } + + @Override + public List selectProcessByOrderIds(List orderIds) { + List workPlanList = new ArrayList<>(); + List workPlans = workPlanService.list(Wrappers.lambdaQuery(WorkPlan.class).in(WorkPlan::getWoId, orderIds)); + for (WorkPlan workPlan : workPlans) { + CacheWorkPlanVO cacheWorkPlanVO = new CacheWorkPlanVO(); + BeanUtils.copyProperties(workPlan, cacheWorkPlanVO); + workPlanList.add(cacheWorkPlanVO); + } + return workPlanList; + } + private boolean checkWp(WorkPlan wp, Integer runType) { //不分派工序不能操作 BsProcessSetEntity processSet = bsProcessSetService.getById(wp.getPpsId()); diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/wrapper/WorkOrderWrapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/wrapper/WorkOrderWrapper.java index 559cc8f7..cca7191b 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/wrapper/WorkOrderWrapper.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/wrapper/WorkOrderWrapper.java @@ -5,6 +5,8 @@ import org.springblade.core.mp.support.BaseEntityWrapper; import org.springblade.core.tool.utils.BeanUtil; import org.springblade.desk.produce.pojo.entity.WorkOrder; import org.springblade.desk.produce.pojo.vo.WorkOrderVO; +import org.springblade.system.cache.UserCache; +import org.springblade.system.pojo.entity.User; import java.util.List; import java.util.Objects; @@ -32,6 +34,10 @@ public class WorkOrderWrapper extends BaseEntityWrapper public IPage listWorkOrderVO(IPage pages) { List workOrderVos = pages.getRecords(); + for (WorkOrderVO workOrderVo : workOrderVos) { + User user = UserCache.getUser(workOrderVo.getDispatcher()); + workOrderVo.setDispatcherName(user.getRealName()); + } pages.setRecords(workOrderVos); return pages; } diff --git a/blade-service/blade-desk/src/main/resources/application-dev.yml b/blade-service/blade-desk/src/main/resources/application-dev.yml index 1fa698f7..f15508f6 100644 --- a/blade-service/blade-desk/src/main/resources/application-dev.yml +++ b/blade-service/blade-desk/src/main/resources/application-dev.yml @@ -8,6 +8,14 @@ spring: url: ${blade.datasource.dev.url} username: ${blade.datasource.dev.username} password: ${blade.datasource.dev.password} + # Caffeine缓存核心配置(SpringBoot3) + cache: + type: caffeine + caffeine: + # 单个缓存自定义配置(优先级最高,贴合订单缓存) + cache-names: runningOrderCache + specs: + runningOrderCache: expireAfterWrite=1h,refreshAfterWrite=30m,maximumSize=5000,initialCapacity=100 business: oldMes: