From 441c19e87aed0d40bcc2437db044bf5894639fd8 Mon Sep 17 00:00:00 2001 From: geht <2947093423@qq.com> Date: Mon, 25 May 2026 20:29:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=AF=86=E7=82=BC=E7=89=A9?= =?UTF-8?q?=E6=96=99=E7=A7=8D=E7=B1=BB=E9=85=8D=E7=BD=AE=E5=85=B3=E8=81=94?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=A7=8D=E7=B1=BB=E6=9F=A5=E6=89=BE=E8=A1=A8=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E4=B8=8E=E8=A7=A3=E6=9E=90=E6=8E=A5=E5=8F=A3=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=80=89=E6=96=99=E5=BC=B9=E7=AA=97=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E4=B8=8E=E5=88=B7=E6=96=B0=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C=E4=B8=8E=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=A8=B3=E5=AE=9A=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeecg-module-xslmes/doc/代码修改日志 | 28 +++ .../MesXslMixerMaterialKindCfgController.java | 23 +++ .../IMesXslMixerMaterialKindCfgService.java | 17 ++ .../impl/MesXslFormulaSpecServiceImpl.java | 106 ++++------- ...MesXslMixerMaterialKindCfgServiceImpl.java | 109 ++++++++++++ .../vo/MesXslMixerMaterialKindLookupVO.java | 26 +++ jeecgboot-vue3/src/design/public.less | 6 + .../system/category/category.constants.ts | 34 +++- .../MesXslMixerMaterialKindCfg.api.ts | 6 + .../mesXslMixingSpec/MesXslMixingSpec.data.ts | 143 +++++++++++---- .../MesXslMixingMaterialCategorySetting.vue | 45 +++-- .../MesXslMixingMaterialSelectModal.vue | 164 ++++++++++++------ .../components/MesXslMixingSpecModal.vue | 19 +- 13 files changed, 556 insertions(+), 170 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslMixerMaterialKindLookupVO.java diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 index a8cdacb..a8d4ad7 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 @@ -278,3 +278,31 @@ jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialKindCfg/components/MesXslMixe -- author:cursor---date:20260525--for: 【XSLMES-20260525-A51】密炼物料种类配置菜单ID冲突修复 ----------- jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_102__mes_xsl_mixer_material_kind_cfg.sql jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_103__mes_xsl_mixer_material_kind_cfg_menu_fix.sql + +-- author:cursor---date:20260525--for: 【XSLMES-20260525-A52】混炼示方种类改读密炼物料种类配置(生成/选料弹窗) ----------- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslMixerMaterialKindLookupVO.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerMaterialKindCfgService.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerMaterialKindCfgServiceImpl.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerMaterialKindCfgController.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue + +-- author:cursor---date:20260525--for: 【XSLMES-20260525-A52】选料弹窗层级修复及关闭父弹窗时同步关闭 ----------- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue + +-- author:cursor---date:20260525--for: 【XSLMES-20260525-A52】选料弹窗左侧物料小类树会话缓存 ----------- +jeecgboot-vue3/src/views/system/category/category.constants.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue + +-- author:cursor---date:20260525--for: 【XSLMES-20260525-A52】选料弹窗小类设置按钮 Popover 层级修复 ----------- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialCategorySetting.vue + +-- author:cursor---date:20260525--for: 【XSLMES-20260525-A52】选料弹窗小类设置新增刷新分类字典 ----------- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialCategorySetting.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue + +-- author:cursor---date:20260525--for: 【XSLMES-20260525-A52】高层级弹窗内 Message 提示层级修复 ----------- +jeecgboot-vue3/src/design/public.less diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerMaterialKindCfgController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerMaterialKindCfgController.java index f1e86f9..6e4b5ab 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerMaterialKindCfgController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerMaterialKindCfgController.java @@ -19,6 +19,7 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialKindCfg; import org.jeecg.modules.xslmes.service.IMesXslMixerMaterialKindCfgService; +import org.jeecg.modules.xslmes.vo.MesXslMixerMaterialKindLookupVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @@ -72,6 +73,28 @@ public class MesXslMixerMaterialKindCfgController } //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A51】密炼物料种类配置展开与批量保存----------- + //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】密炼物料种类配置关联解析----------- + @Operation(summary = "MES密炼物料种类配置-加载种类查找表") + @GetMapping(value = "/kindLookup") + public Result kindLookup( + @RequestParam(name = "tenantId", required = false) Integer tenantId) { + return Result.OK(mesXslMixerMaterialKindCfgService.loadKindLookup(tenantId)); + } + + @Operation(summary = "MES密炼物料种类配置-解析混炼示方明细种类") + @GetMapping(value = "/resolveKind") + public Result resolveKind( + @RequestParam(name = "minorCategoryId", required = false) String minorCategoryId, + @RequestParam(name = "weighMode", required = false) String weighMode, + @RequestParam(name = "minorCategoryName", required = false) String minorCategoryName, + @RequestParam(name = "tenantId", required = false) Integer tenantId) { + MesXslMixerMaterialKindLookupVO lookup = mesXslMixerMaterialKindCfgService.loadKindLookup(tenantId); + String kind = mesXslMixerMaterialKindCfgService.resolveMixingMaterialKind( + lookup, minorCategoryId, weighMode, minorCategoryName); + return Result.OK(kind); + } + //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】密炼物料种类配置关联解析----------- + @AutoLog(value = "MES密炼物料种类配置-添加") @Operation(summary = "MES密炼物料种类配置-添加") @RequiresPermissions("xslmes:mes_xsl_mixer_material_kind_cfg:add") diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerMaterialKindCfgService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerMaterialKindCfgService.java index 83a7593..aa41b9c 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerMaterialKindCfgService.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerMaterialKindCfgService.java @@ -3,6 +3,7 @@ package org.jeecg.modules.xslmes.service; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialKindCfg; +import org.jeecg.modules.xslmes.vo.MesXslMixerMaterialKindLookupVO; /** * MES 密炼物料种类配置 @@ -23,4 +24,20 @@ public interface IMesXslMixerMaterialKindCfgService extends IService lineList) { @@ -528,7 +533,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl mixerCache = new HashMap<>(); Map categoryNameCache = new HashMap<>(); - Map categoryRubberCache = new HashMap<>(); + //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】生成混炼示方种类改读密炼物料种类配置----------- + MesXslMixerMaterialKindLookupVO kindLookup = mesXslMixerMaterialKindCfgService.loadKindLookup(null); + //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】生成混炼示方种类改读密炼物料种类配置----------- Map equipmentCache = new HashMap<>(); //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A44】F段终炼胶比重按配合示方整体PHR/体积汇总----------- BigDecimal compoundSpecificGravity = resolveCompoundSpecificGravity(formula, lines); @@ -555,7 +562,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl materials = buildMixingMaterials( - formula, lines, mixingColumn, materialStep, mixerCache, categoryNameCache, categoryRubberCache); + formula, lines, mixingColumn, materialStep, mixerCache, categoryNameCache, kindLookup); for (MesXslFormulaMixingGenerateMachineVO machine : row.getMachines()) { if (machine == null || oConvertUtils.isEmpty(machine.getMachineId())) { continue; @@ -928,7 +935,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl mixerCache, Map categoryNameCache, - Map categoryRubberCache) { + MesXslMixerMaterialKindLookupVO kindLookup) { String stepFilter = StringUtils.isNotBlank(materialStep) ? materialStep.trim().toUpperCase() : "A"; List materials = new ArrayList<>(); int sort = 0; @@ -940,9 +947,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl 0) { String motherSpecCode = appendFormulaCodeSuffix("B" + lastBSegment + rubberName, codeSuffix); BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, lastBSegment); - materials.add(createMotherRubberMaterial(motherSpecCode, rubberName, motherWeight, materials.size())); + materials.add(createMotherRubberMaterial(motherSpecCode, rubberName, motherWeight, materials.size(), kindLookup)); } - appendQStageColumnAgents(lines, stageIndex, materials, mixerCache, categoryNameCache, categoryRubberCache); + appendQStageColumnAgents(lines, stageIndex, materials, mixerCache, categoryNameCache, kindLookup); reindexMaterialSortNo(materials); return materials; //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】F段加入最后一段B炼好胶料一条再加Q配合剂----------- @@ -951,7 +958,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl materials, Map mixerCache, Map categoryNameCache, - Map categoryRubberCache) { + MesXslMixerMaterialKindLookupVO kindLookup) { for (MesXslFormulaSpecLine line : lines) { if (!isLineStep(line, "Q")) { continue; @@ -991,7 +998,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl materials, Map mixerCache, Map categoryNameCache, - Map categoryRubberCache) { + MesXslMixerMaterialKindLookupVO kindLookup) { for (MesXslFormulaSpecLine line : lines) { if (!isLineStep(line, "A")) { continue; @@ -1012,18 +1019,26 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl mixerCache, Map categoryNameCache, - Map categoryRubberCache) { + MesXslMixerMaterialKindLookupVO kindLookup) { MesXslMixingSpecMaterial material = new MesXslMixingSpecMaterial(); material.setSortNo(sortNo); material.setMixerMaterialName(line.getMixerMaterialName()); material.setMixerMaterialDesc( StringUtils.isNotBlank(line.getMaterialDesc()) ? line.getMaterialDesc() : line.getMixerMaterialName()); material.setUnitWeight(unitWeight); - fillMaterialCategory(material, line.getMixerMaterialId(), line, mixerCache, categoryNameCache, categoryRubberCache); + fillMaterialCategory(material, line.getMixerMaterialId(), line, mixerCache, categoryNameCache, kindLookup); return material; } @@ -1136,7 +1151,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl mixerCache, Map categoryNameCache, - Map categoryRubberCache) { + MesXslMixerMaterialKindLookupVO kindLookup) { if (oConvertUtils.isEmpty(mixerMaterialId)) { return; } @@ -1149,58 +1164,11 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl categoryRubberCache) { - String weighKind = resolveWeighModeMaterialKind(weighMode); - if (StringUtils.isNotBlank(weighKind)) { - return weighKind; - } - if (isCategoryRubber(minorCategoryId, categoryRubberCache)) { - return "胶料"; - } - if (StringUtils.isNotBlank(minorCategoryName)) { - return minorCategoryName; - } - return null; - } - - /** 配合示方自动/人工称量 -> 混炼示方种类 */ - private String resolveWeighModeMaterialKind(String weighMode) { - if (StringUtils.isBlank(weighMode)) { - return null; - } - String normalized = weighMode.trim(); - String lower = normalized.toLowerCase(); - if (lower.startsWith("auto") || normalized.contains("自动")) { - return "自动"; - } - if ("manual".equals(lower) || normalized.contains("人工")) { - return "人工"; - } - return null; - } - //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】生成混炼示方时称量方式优先映射种类----------- - - private boolean isCategoryRubber(String categoryId, Map cache) { - if (oConvertUtils.isEmpty(categoryId)) { - return false; - } - return Boolean.TRUE.equals(cache.computeIfAbsent(categoryId, this::loadCategoryIsRubber)); - } - - private Boolean loadCategoryIsRubber(String categoryId) { - SysCategory category = sysCategoryService.getById(categoryId); - return category != null && "1".equals(category.getIsRubber()); + mesXslMixerMaterialKindCfgService.resolveMixingMaterialKind( + kindLookup, mixer.getMinorCategoryId(), weighMode, minorName)); + //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】生成混炼示方种类改读密炼物料种类配置----------- } private String resolveCategoryName(String categoryId, Map cache) { diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerMaterialKindCfgServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerMaterialKindCfgServiceImpl.java index 306c3e4..52b195c 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerMaterialKindCfgServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerMaterialKindCfgServiceImpl.java @@ -7,7 +7,9 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.exception.JeecgBootException; @@ -25,6 +27,8 @@ import org.jeecg.modules.system.service.ISysDictService; import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialKindCfg; import org.jeecg.modules.xslmes.mapper.MesXslMixerMaterialKindCfgMapper; import org.jeecg.modules.xslmes.service.IMesXslMixerMaterialKindCfgService; +import org.jeecg.modules.xslmes.vo.MesXslMixerMaterialKindLookupVO; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -295,4 +299,109 @@ public class MesXslMixerMaterialKindCfgServiceImpl } } //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A51】密炼物料种类配置展开与批量保存----------- + + //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】密炼物料种类配置关联解析----------- + private static final String DEFAULT_RUBBER_KIND_NAME = "胶料"; + + @Override + public MesXslMixerMaterialKindLookupVO loadKindLookup(Integer tenantId) { + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.and(q -> q.eq(MesXslMixerMaterialKindCfg::getDelFlag, CommonConstant.DEL_FLAG_0).or().isNull(MesXslMixerMaterialKindCfg::getDelFlag)); + Integer resolvedTenantId = resolveTenantId(tenantId); + if (resolvedTenantId != null && MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { + qw.eq(MesXslMixerMaterialKindCfg::getTenantId, resolvedTenantId); + } + qw.orderByAsc(MesXslMixerMaterialKindCfg::getPriority).orderByAsc(MesXslMixerMaterialKindCfg::getKindKey); + List rows = list(qw); + + MesXslMixerMaterialKindLookupVO lookup = new MesXslMixerMaterialKindLookupVO(); + Map byRefId = new LinkedHashMap<>(); + Map byRefCode = new LinkedHashMap<>(); + String rubberKindName = null; + if (rows != null) { + for (MesXslMixerMaterialKindCfg row : rows) { + if (row == null || oConvertUtils.isEmpty(row.getKindName())) { + continue; + } + String kindName = row.getKindName().trim(); + if (oConvertUtils.isNotEmpty(row.getCategoryRefId()) && !byRefId.containsKey(row.getCategoryRefId().trim())) { + byRefId.put(row.getCategoryRefId().trim(), kindName); + } + if (oConvertUtils.isNotEmpty(row.getCategoryRefCode())) { + String refCode = row.getCategoryRefCode().trim(); + if (!byRefCode.containsKey(refCode)) { + byRefCode.put(refCode, kindName); + } + String lowerCode = refCode.toLowerCase(); + if (!lowerCode.equals(refCode) && !byRefCode.containsKey(lowerCode)) { + byRefCode.put(lowerCode, kindName); + } + } + if (rubberKindName == null && DEFAULT_RUBBER_KIND_NAME.equals(kindName)) { + rubberKindName = kindName; + } + } + } + lookup.setByRefId(byRefId); + lookup.setByRefCode(byRefCode); + lookup.setRubberKindName(oConvertUtils.isNotEmpty(rubberKindName) ? rubberKindName : DEFAULT_RUBBER_KIND_NAME); + return lookup; + } + + @Override + public String resolveMixingMaterialKind( + MesXslMixerMaterialKindLookupVO lookup, + String minorCategoryId, + String weighMode, + String minorCategoryName) { + if (lookup == null) { + lookup = loadKindLookup(null); + } + if (oConvertUtils.isNotEmpty(weighMode)) { + String fromWeighMode = matchKindFromLookup(lookup, weighMode.trim()); + if (oConvertUtils.isNotEmpty(fromWeighMode)) { + return fromWeighMode; + } + } + if (oConvertUtils.isNotEmpty(minorCategoryId)) { + String fromMinor = matchKindFromLookup(lookup, minorCategoryId.trim()); + if (oConvertUtils.isNotEmpty(fromMinor)) { + return fromMinor; + } + } + if (oConvertUtils.isNotEmpty(minorCategoryName)) { + return minorCategoryName.trim(); + } + return null; + } + + private String matchKindFromLookup(MesXslMixerMaterialKindLookupVO lookup, String key) { + if (lookup == null || oConvertUtils.isEmpty(key)) { + return null; + } + Map byRefId = lookup.getByRefId(); + if (byRefId != null && byRefId.containsKey(key)) { + return byRefId.get(key); + } + Map byRefCode = lookup.getByRefCode(); + if (byRefCode == null || byRefCode.isEmpty()) { + return null; + } + if (byRefCode.containsKey(key)) { + return byRefCode.get(key); + } + String lower = key.toLowerCase(); + if (byRefCode.containsKey(lower)) { + return byRefCode.get(lower); + } + if (StringUtils.isNotBlank(key)) { + for (Map.Entry entry : byRefCode.entrySet()) { + if (entry.getKey() != null && key.contains(entry.getKey())) { + return entry.getValue(); + } + } + } + return null; + } + //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】密炼物料种类配置关联解析----------- } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslMixerMaterialKindLookupVO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslMixerMaterialKindLookupVO.java new file mode 100644 index 0000000..cf2d3f3 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslMixerMaterialKindLookupVO.java @@ -0,0 +1,26 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; +import lombok.Data; + +/** + * 密炼物料种类配置查找表(按对应分类/字典项关联) + */ +@Data +@Schema(description = "密炼物料种类配置查找表") +public class MesXslMixerMaterialKindLookupVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "对应分类/字典项ID -> 种类名称") + private Map byRefId = new LinkedHashMap<>(); + + @Schema(description = "对应分类/字典项编码 -> 种类名称") + private Map byRefCode = new LinkedHashMap<>(); + + @Schema(description = "胶料种类名称(母炼胶行兜底)") + private String rubberKindName; +} diff --git a/jeecgboot-vue3/src/design/public.less b/jeecgboot-vue3/src/design/public.less index eda1bbf..be1938d 100644 --- a/jeecgboot-vue3/src/design/public.less +++ b/jeecgboot-vue3/src/design/public.less @@ -56,6 +56,12 @@ } } +// 高层级业务弹窗(如混炼示方选料 z-index 1500)打开时,顶部提示需置于弹窗之上 +.ant-message, +.ant-notification { + z-index: 2200 !important; +} + // ======================================= // ============ [sjl] 按钮组样式 ========== // ======================================= diff --git a/jeecgboot-vue3/src/views/system/category/category.constants.ts b/jeecgboot-vue3/src/views/system/category/category.constants.ts index 40aca17..1a1b980 100644 --- a/jeecgboot-vue3/src/views/system/category/category.constants.ts +++ b/jeecgboot-vue3/src/views/system/category/category.constants.ts @@ -130,7 +130,39 @@ function normalizeTreeSelectNodes(nodes: unknown): Recordable[] { } /** 加载 MES 物料分类树:根下物料大类 + 各物料小类(供密炼物料/混炼示方选料复用) */ -export async function loadMesMaterialCategoryTreeData(): Promise { +let mesMaterialCategoryTreeCache: MesMaterialCategoryTreeLoadResult | null = null; +let mesMaterialCategoryTreeLoading: Promise | null = null; + +export function hasMesMaterialCategoryTreeCache() { + return !!(mesMaterialCategoryTreeCache?.minors?.length || mesMaterialCategoryTreeCache?.majors?.length); +} + +export function clearMesMaterialCategoryTreeCache() { + mesMaterialCategoryTreeCache = null; + mesMaterialCategoryTreeLoading = null; +} + +export async function loadMesMaterialCategoryTreeData(forceReload = false): Promise { + if (!forceReload && mesMaterialCategoryTreeCache) { + return mesMaterialCategoryTreeCache; + } + if (!forceReload && mesMaterialCategoryTreeLoading) { + return mesMaterialCategoryTreeLoading; + } + mesMaterialCategoryTreeLoading = fetchMesMaterialCategoryTreeData() + .then((result) => { + if (result.minors.length || result.majors.length) { + mesMaterialCategoryTreeCache = result; + } + return result; + }) + .finally(() => { + mesMaterialCategoryTreeLoading = null; + }); + return mesMaterialCategoryTreeLoading; +} + +async function fetchMesMaterialCategoryTreeData(): Promise { // 优先 loadTreeRoot(与密炼物料列表页一致,已验证可用) try { const treeRes = await loadTreeData({ async: false, pcode: MATERIAL_ROOT_CODE }); diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api.ts index 26e37af..d07357c 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api.ts @@ -11,12 +11,18 @@ enum Api { importExcel = '/xslmes/mesXslMixerMaterialKindCfg/importExcel', exportXls = '/xslmes/mesXslMixerMaterialKindCfg/exportXls', queryById = '/xslmes/mesXslMixerMaterialKindCfg/queryById', + kindLookup = '/xslmes/mesXslMixerMaterialKindCfg/kindLookup', + resolveKind = '/xslmes/mesXslMixerMaterialKindCfg/resolveKind', } export const list = (params) => defHttp.get({ url: Api.list, params }); export const queryById = (params) => defHttp.get({ url: Api.queryById, params }); +export const loadKindLookup = (params?) => defHttp.get({ url: Api.kindLookup, params }); + +export const resolveKind = (params) => defHttp.get({ url: Api.resolveKind, params }); + export const expandLines = (params) => defHttp.get({ url: Api.expandLines, params }); export const addBatch = (params) => defHttp.post({ url: Api.addBatch, params }, { successMessageMode: 'none' }); diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts index 2187215..933a177 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts @@ -967,52 +967,135 @@ export function sanitizeMixingMaterialPickerHiddenCategoryIds(allMinorIds: strin } //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗小类树为空时重置隐藏配置----------- -/** 解析混炼示方明细种类:小类勾选胶料则显示「胶料」,否则显示小类名 */ -export function resolveMixingMaterialKindFromCategory(isRubber?: unknown, minorName?: string) { - if (isRubber === '1' || isRubber === 1 || isRubber === true) { - return '胶料'; +//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】混炼示方种类改读密炼物料种类配置----------- +export interface MixerMaterialKindLookup { + byRefId: Record; + byRefCode: Record; + rubberKindName?: string; +} + +export const EMPTY_MIXER_MATERIAL_KIND_LOOKUP: MixerMaterialKindLookup = { + byRefId: {}, + byRefCode: {}, + rubberKindName: '胶料', +}; + +let mixingMaterialKindLookupCache: MixerMaterialKindLookup | null = null; +let mixingMaterialKindLookupPromise: Promise | null = null; + +/** 加载密炼物料种类配置查找表(带内存缓存) */ +export async function loadMixingMaterialKindLookup(forceReload = false): Promise { + if (!forceReload && mixingMaterialKindLookupCache) { + return mixingMaterialKindLookupCache; } + if (!forceReload && mixingMaterialKindLookupPromise) { + return mixingMaterialKindLookupPromise; + } + mixingMaterialKindLookupPromise = (async () => { + try { + const { loadKindLookup } = await import('../mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api'); + const raw = await loadKindLookup(); + const lookup: MixerMaterialKindLookup = { + byRefId: raw?.byRefId || {}, + byRefCode: raw?.byRefCode || {}, + rubberKindName: raw?.rubberKindName || '胶料', + }; + mixingMaterialKindLookupCache = lookup; + return lookup; + } catch { + return EMPTY_MIXER_MATERIAL_KIND_LOOKUP; + } finally { + mixingMaterialKindLookupPromise = null; + } + })(); + return mixingMaterialKindLookupPromise; +} + +/** 清除种类配置缓存(配置变更后可调用) */ +export function clearMixingMaterialKindLookupCache() { + mixingMaterialKindLookupCache = null; + mixingMaterialKindLookupPromise = null; +} + +function matchKindFromLookup(lookup: MixerMaterialKindLookup | null | undefined, key?: string) { + if (!lookup || key == null || String(key).trim() === '') { + return ''; + } + const normalized = String(key).trim(); + if (lookup.byRefId?.[normalized]) { + return lookup.byRefId[normalized]; + } + if (lookup.byRefCode?.[normalized]) { + return lookup.byRefCode[normalized]; + } + const lower = normalized.toLowerCase(); + if (lookup.byRefCode?.[lower]) { + return lookup.byRefCode[lower]; + } + for (const [code, kindName] of Object.entries(lookup.byRefCode || {})) { + if (code && normalized.includes(code)) { + return kindName; + } + } + return ''; +} + +/** 解析混炼示方明细种类:称量方式优先,其次物料小类 ID,最后小类名称兜底 */ +export function resolveMixingMaterialKindFromLookup( + lookup: MixerMaterialKindLookup | null | undefined, + weighMode?: string, + minorCategoryId?: string, + minorCategoryName?: string, +) { + const fromWeighMode = matchKindFromLookup(lookup, weighMode); + if (fromWeighMode) { + return fromWeighMode; + } + const fromMinorId = matchKindFromLookup(lookup, minorCategoryId); + if (fromMinorId) { + return fromMinorId; + } + if (minorCategoryName != null && String(minorCategoryName).trim() !== '') { + return String(minorCategoryName).trim(); + } + return ''; +} + +/** @deprecated 保留兼容,请改用 resolveMixingMaterialKindFromLookup */ +export function resolveMixingMaterialKindFromCategory(_isRubber?: unknown, minorName?: string) { return minorName != null && String(minorName).trim() !== '' ? String(minorName).trim() : ''; } +/** @deprecated 保留兼容,请改用 resolveMixingMaterialKindFromLookup */ +export function resolveMixingMaterialKindFromWeighMode(_weighMode?: string) { + return ''; +} + +/** 选料确认时种类:读密炼物料种类配置表 */ +export function resolveMixingMaterialKindForPicker( + lookup: MixerMaterialKindLookup | null | undefined, + weighMode: string | undefined, + minorCategoryId?: string, + minorCategoryName?: string, +) { + return resolveMixingMaterialKindFromLookup(lookup, weighMode, minorCategoryId, minorCategoryName); +} +//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】混炼示方种类改读密炼物料种类配置----------- + //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗自动/人工称量列与种类映射----------- /** 与配合示方「自动/人工」列相同字典 */ export const MIXING_MATERIAL_PICKER_WEIGH_MODE_DICT = 'xslmes_formula_spec_weigh_mode'; -/** 选料弹窗表格列(隐藏 ERP 编号,新增仅本次有效的自动/人工称量) */ +/** 选料弹窗表格列(隐藏 ERP 编号,新增种类列与自动/人工称量) */ export const mixingMaterialPickerTableColumns: BasicColumn[] = [ { title: '物料编码', align: 'center', width: 120, dataIndex: 'materialCode' }, { title: '物料名称', align: 'center', width: 160, dataIndex: 'materialName' }, { title: '自动/人工称量', align: 'center', width: 132, dataIndex: 'pickerWeighMode' }, + { title: '种类', align: 'center', width: 100, dataIndex: 'pickerMaterialKind' }, { title: '物料大类', align: 'center', width: 120, dataIndex: 'majorCategoryId_dictText' }, { title: '物料小类', align: 'center', width: 120, dataIndex: 'minorCategoryId_dictText' }, { title: '物料描述', align: 'center', width: 180, ellipsis: true, dataIndex: 'materialDesc' }, ]; - -/** 配合示方称量方式 -> 混炼示方种类(与后端 resolveWeighModeMaterialKind 一致) */ -export function resolveMixingMaterialKindFromWeighMode(weighMode?: string) { - if (weighMode == null || String(weighMode).trim() === '') { - return ''; - } - const normalized = String(weighMode).trim(); - const lower = normalized.toLowerCase(); - if (lower.startsWith('auto') || normalized.includes('自动')) { - return '自动'; - } - if (lower === 'manual' || normalized.includes('人工')) { - return '人工'; - } - return ''; -} - -/** 选料确认时种类:称量方式优先,否则按小类胶料/小类名 */ -export function resolveMixingMaterialKindForPicker(weighMode: string | undefined, isRubber?: unknown, minorName?: string) { - const fromWeighMode = resolveMixingMaterialKindFromWeighMode(weighMode); - if (fromWeighMode) { - return fromWeighMode; - } - return resolveMixingMaterialKindFromCategory(isRubber, minorName); -} //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗自动/人工称量列与种类映射----------- /** 选择密炼物料后回填混炼示方橡胶及配合剂明细行 */ diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialCategorySetting.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialCategorySetting.vue index e4d6850..8b53a11 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialCategorySetting.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialCategorySetting.vue @@ -3,6 +3,7 @@ v-model:open="popoverOpen" trigger="click" placement="bottomRight" + :getPopupContainer="getPopoverContainer" :overlayClassName="`${prefixCls}__popover`" @open-change="handleOpenChange" > @@ -14,7 +15,7 @@ - - - - - + + + @@ -71,13 +73,21 @@ type: Boolean, default: false, }, + refreshing: { + type: Boolean, + default: false, + }, }); - const emit = defineEmits(['update:hiddenCategoryIds', 'change']); + const emit = defineEmits(['update:hiddenCategoryIds', 'change', 'refresh']); const popoverOpen = ref(false); const draftVisibleIds = ref([]); + function getPopoverContainer() { + return document.body; + } + const allCategoryIds = computed(() => (props.categories || []).map((item) => item.id)); //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗小类设置按大类分组展示----------- @@ -156,6 +166,12 @@ draftVisibleIds.value = [...allCategoryIds.value]; } + //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】小类设置刷新分类字典----------- + function handleRefresh() { + emit('refresh'); + } + //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】小类设置刷新分类字典----------- + function handleSave() { const visibleSet = new Set(draftVisibleIds.value.map(String)); const hidden = allCategoryIds.value.filter((id) => !visibleSet.has(String(id))); @@ -175,6 +191,8 @@ diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue index 9c28399..01c7d20 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue @@ -2,8 +2,9 @@ @@ -21,7 +22,9 @@ v-model:hiddenCategoryIds="hiddenCategoryIds" :categories="allMinorCategories" :loading="treeLoading" + :refreshing="categoryRefreshing" @change="handleCategoryVisibilityChange" + @refresh="handleRefreshCategoryTree" />
@@ -55,6 +58,9 @@ />
+ @@ -64,19 +70,20 @@