From c85657d1995fe66969cc660634e47b928a6c53e7 Mon Sep 17 00:00:00 2001 From: geht <2947093423@qq.com> Date: Fri, 22 May 2026 19:43:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B7=B7=E7=82=BC=E7=A4=BA?= =?UTF-8?q?=E6=96=B9=E7=94=9F=E6=88=90=E9=A2=84=E8=A7=88=E4=B8=8E=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=9B=E5=BB=BA=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=9B=B8=E5=85=B3=E5=AD=97=E6=AE=B5=E5=8F=8A=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BA=A4=E4=BA=92=EF=BC=8C=E4=BF=AE=E5=A4=8D=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E7=B3=BB=E7=BB=9F=E7=A8=B3=E5=AE=9A=E6=80=A7=E5=92=8C?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeecg-module-xslmes/doc/代码修改日志 | 57 ++ .../MesXslFormulaSpecController.java | 28 + .../xslmes/entity/MesXslMixingSpec.java | 4 +- .../service/IMesXslFormulaSpecService.java | 16 + .../impl/MesXslFormulaSpecServiceImpl.java | 503 ++++++++++++++++++ .../MesXslFormulaMixingGenerateMachineVO.java | 16 + ...XslFormulaMixingGeneratePreviewItemVO.java | 25 + .../MesXslFormulaMixingGeneratePreviewVO.java | 23 + .../MesXslFormulaMixingGenerateRequestVO.java | 17 + .../vo/MesXslFormulaMixingGenerateRowVO.java | 26 + .../jeecg-system-biz/docs/代码修改日志 | 8 + .../modules/system/entity/SysCategory.java | 3 + .../service/impl/SysCategoryServiceImpl.java | 32 ++ ..._mes_xsl_mixing_spec_stage_count_total.sql | 3 + ...l_mixing_spec_stage_count_revert_total.sql | 4 + .../V3.9.2_99__sys_category_is_rubber.sql | 20 + .../MesMixerMaterialSysCategoryModal.vue | 44 +- .../system/category/category.constants.ts | 22 + .../views/system/category/category.data.ts | 10 + .../category/components/CategoryModal.vue | 31 ++ .../MesXslEquipmentLedgerMultiSelectModal.vue | 76 +++ .../MesXslFormulaSpec.api.ts | 8 + .../MesXslFormulaSpecList.vue | 26 + .../MesXslFormulaGenerateMixingModal.vue | 193 +++++++ .../components/MesXslFormulaSpecModal.vue | 27 + .../MesXslMixerActionSelectModal.vue | 91 ++++ .../MesXslMixerConditionSelectModal.vue | 91 ++++ .../mesXslMixingSpec/MesXslMixingSpec.data.ts | 66 ++- .../components/MesXslMixingSpecModal.vue | 268 ++++++++-- .../components/MesXslMixingStepSelectCell.vue | 109 ++++ 30 files changed, 1786 insertions(+), 61 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateMachineVO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewItemVO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewVO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRequestVO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRowVO.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_100__mes_xsl_mixing_spec_stage_count_total.sql create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_101__mes_xsl_mixing_spec_stage_count_revert_total.sql create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_99__sys_category_is_rubber.sql create mode 100644 jeecgboot-vue3/src/views/system/category/category.constants.ts create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerMultiSelectModal.vue create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslMixerAction/components/MesXslMixerActionSelectModal.vue create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/components/MesXslMixerConditionSelectModal.vue create mode 100644 jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingStepSelectCell.vue diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 index 04a7f2a..f980ca7 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 @@ -132,3 +132,60 @@ jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.api.ts jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpecList.vue jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A33】新增混炼示方主表/明细字段交互优化 --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixerAction/components/MesXslMixerActionSelectModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/components/MesXslMixerConditionSelectModal.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A34】混炼示方动作/组合改为下拉选择 --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A35】混炼示方动作/组合列常显下拉倒三角 --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingStepSelectCell.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】F段明细加入最后一段B炼好胶(如三段用B2)+Q列配合剂 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】B2/Bn明细改为上一段胶料一条(B{n-1}+胶料名)+本段列配合剂 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】修复B2与B1相同:按列增量拼接并支持列2+非Q配合剂 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRowVO.java +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】生成混炼示方B段改为Bn=B(n-1)+第n列有值配合剂增量拼接 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】生成混炼示方明细种类按分类字典is_rubber显示胶料或小类名 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】生成混炼示方编号原样追加胶料代号中胶料名称后的后缀 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】生成混炼示方明细按STEP过滤:B段仅A物料、F段仅Q物料 --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A38】配合示方生成混炼示方(预览段×机台批量创建) --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerate*.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslFormulaSpecService.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslFormulaSpecController.java +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpecList.vue +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerMultiSelectModal.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A36】混炼示方动作/组合下拉列表被表格裁切修复 --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingStepSelectCell.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue + +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A37】未选机台点击动作/组合提示请先选择机台 --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingStepSelectCell.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslFormulaSpecController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslFormulaSpecController.java index 0ad744a..7c752dc 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslFormulaSpecController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslFormulaSpecController.java @@ -25,6 +25,8 @@ import org.jeecg.modules.xslmes.entity.MesXslFormulaSpec; import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecLine; import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecService; import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecSettingService; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGeneratePreviewVO; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGenerateRequestVO; import org.jeecg.modules.xslmes.vo.MesXslFormulaRubberContentSettingVO; import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecPage; import org.springframework.beans.BeanUtils; @@ -173,6 +175,32 @@ public class MesXslFormulaSpecController extends JeecgController buildMixingGeneratePreview( + @RequestParam(name = "formulaSpecId", required = true) String formulaSpecId) { + try { + return Result.OK(mesXslFormulaSpecService.buildMixingGeneratePreview(formulaSpecId)); + } catch (IllegalArgumentException ex) { + return Result.error(ex.getMessage()); + } + } + + @AutoLog(value = "MES配合示方-生成混炼示方") + @Operation(summary = "MES配合示方-生成混炼示方") + @RequiresPermissions("xslmes:mes_xsl_mixing_spec:add") + @PostMapping(value = "/generateMixingSpec") + public Result> generateMixingSpec(@RequestBody MesXslFormulaMixingGenerateRequestVO request) { + try { + int count = mesXslFormulaSpecService.generateMixingSpecFromFormula(request); + return Result.OK("成功生成 " + count + " 条混炼示方", Map.of("count", count)); + } catch (IllegalArgumentException ex) { + return Result.error(ex.getMessage()); + } + } + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方----------- + @RequiresPermissions("xslmes:mes_xsl_formula_spec:exportXls") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, MesXslFormulaSpec model) { diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMixingSpec.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMixingSpec.java index ea6c7e6..25c9d2a 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMixingSpec.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMixingSpec.java @@ -75,8 +75,8 @@ public class MesXslMixingSpec implements Serializable { @Schema(description = "适用工厂") private String applyFactory; - @Schema(description = "段数") - private Integer stageCount; + @Schema(description = "段数(当前/总,如2/3)") + private String stageCount; @Schema(description = "纯混炼时间(秒)") private Integer pureMixSec; diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslFormulaSpecService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslFormulaSpecService.java index 8bab67c..9cbbdc0 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslFormulaSpecService.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslFormulaSpecService.java @@ -7,6 +7,8 @@ import java.util.List; import org.jeecg.modules.xslmes.entity.MesXslFormulaSpec; import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecLine; import org.jeecg.modules.xslmes.entity.MesXslMixerPsCompile; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGeneratePreviewVO; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGenerateRequestVO; public interface IMesXslFormulaSpecService extends IService { @@ -36,4 +38,18 @@ public interface IMesXslFormulaSpecService extends IService { */ void syncFromMixerPsWorkflow(MesXslMixerPsCompile ps, String mixerPsTargetStatus); //update-end---author:cursor ---date:20260522 for:【配合示方】密炼PS审批联动同步状态与审批人----------- + + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方预览与批量创建----------- + /** + * 根据配合示方混合段数构建生成混炼示方预览行(示方编号 + 段信息) + */ + MesXslFormulaMixingGeneratePreviewVO buildMixingGeneratePreview(String formulaSpecId); + + /** + * 按预览行×机台批量生成混炼示方(含橡胶及配合剂明细) + * + * @return 成功生成的混炼示方条数 + */ + int generateMixingSpecFromFormula(MesXslFormulaMixingGenerateRequestVO request); + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方预览与批量创建----------- } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java index dcdeaf2..883b7f0 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java @@ -7,6 +7,7 @@ import jakarta.annotation.Resource; import java.io.Serializable; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; @@ -14,6 +15,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; @@ -22,13 +25,23 @@ import org.jeecg.modules.mes.material.entity.MesMixerMaterial; import org.jeecg.modules.mes.material.service.IMesMaterialService; import org.jeecg.modules.mes.material.service.IMesMixerMaterialService; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.system.entity.SysCategory; +import org.jeecg.modules.system.service.ISysCategoryService; import org.jeecg.modules.xslmes.entity.MesXslFormulaSpec; import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecLine; import org.jeecg.modules.xslmes.entity.MesXslMixerPsCompile; +import org.jeecg.modules.xslmes.entity.MesXslMixingSpec; +import org.jeecg.modules.xslmes.entity.MesXslMixingSpecMaterial; import org.jeecg.modules.xslmes.mapper.MesXslFormulaSpecLineMapper; import org.jeecg.modules.xslmes.mapper.MesXslFormulaSpecMapper; import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecService; import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecSettingService; +import org.jeecg.modules.xslmes.service.IMesXslMixingSpecService; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGenerateMachineVO; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGeneratePreviewItemVO; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGeneratePreviewVO; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGenerateRequestVO; +import org.jeecg.modules.xslmes.vo.MesXslFormulaMixingGenerateRowVO; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.service.ISysUserService; import org.springframework.stereotype.Service; @@ -57,6 +70,12 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl lineList) { @@ -434,4 +453,488 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl items = new ArrayList<>(); + int aIndex = 0; + for (int i = 1; i <= stageCount; i++) { + boolean isQSegment = hasQ && i == stageCount; + MesXslFormulaMixingGeneratePreviewItemVO item = new MesXslFormulaMixingGeneratePreviewItemVO(); + item.setRowKey(i); + item.setStageIndex(i); + if (isQSegment) { + item.setStepType("Q"); + item.setSpecCode(appendFormulaCodeSuffix("F" + rubberName, formulaCodeSuffix)); + item.setASegmentIndex(null); + } else { + aIndex++; + item.setStepType("A"); + item.setASegmentIndex(aIndex); + item.setSpecCode(appendFormulaCodeSuffix("B" + aIndex + rubberName, formulaCodeSuffix)); + } + items.add(item); + } + MesXslFormulaMixingGeneratePreviewVO preview = new MesXslFormulaMixingGeneratePreviewVO(); + preview.setFormulaSpecId(formulaSpecId); + preview.setRubberName(rubberName); + preview.setMixingStages(stageCount); + preview.setItems(items); + return preview; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int generateMixingSpecFromFormula(MesXslFormulaMixingGenerateRequestVO request) { + if (request == null || oConvertUtils.isEmpty(request.getFormulaSpecId())) { + throw new IllegalArgumentException("配合示方ID不能为空"); + } + if (CollectionUtils.isEmpty(request.getRows())) { + throw new IllegalArgumentException("请至少配置一行示方与机台"); + } + MesXslFormulaSpec formula = getByIdWithLines(request.getFormulaSpecId()); + if (formula == null) { + throw new IllegalArgumentException("未找到配合示方数据"); + } + List lines = formula.getLineList(); + if (CollectionUtils.isEmpty(lines)) { + throw new IllegalArgumentException("配合示方明细为空,无法生成混炼示方"); + } + Map mixerCache = new HashMap<>(); + Map categoryNameCache = new HashMap<>(); + Map categoryRubberCache = new HashMap<>(); + int created = 0; + int totalStages = normalizeMixingStages(formula.getMixingStages()); + Date today = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()); + for (MesXslFormulaMixingGenerateRowVO row : request.getRows()) { + if (row == null || oConvertUtils.isEmpty(row.getSpecCode()) || row.getStageIndex() == null) { + continue; + } + if (CollectionUtils.isEmpty(row.getMachines())) { + throw new IllegalArgumentException("示方「" + row.getSpecCode() + "」请至少选择一个机台"); + } + String materialStep = resolveMixingMaterialStep(row); + int mixingColumn = resolveMixingColumn(row, formula); + List materials = buildMixingMaterials( + formula, lines, mixingColumn, materialStep, mixerCache, categoryNameCache, categoryRubberCache); + for (MesXslFormulaMixingGenerateMachineVO machine : row.getMachines()) { + if (machine == null || oConvertUtils.isEmpty(machine.getMachineId())) { + continue; + } + MesXslMixingSpec mixing = new MesXslMixingSpec(); + mixing.setSpecName(row.getSpecCode()); + mixing.setPurpose(formula.getPurpose()); + mixing.setIssueNumber(formula.getIssueNumber()); + mixing.setMachineId(machine.getMachineId()); + mixing.setMachineName(machine.getMachineName()); + mixing.setMakeDate(today); + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A40】生成时写入段数当前/总如2/3----------- + if (row.getStageIndex() != null && totalStages > 0) { + mixing.setStageCount(row.getStageIndex() + "/" + totalStages); + } else if (row.getStageIndex() != null) { + mixing.setStageCount(String.valueOf(row.getStageIndex())); + } + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A40】生成时写入段数当前/总如2/3----------- + if ("Q".equalsIgnoreCase(row.getStepType())) { + mixing.setFinalRubberSg(formula.getQRubberSg()); + } else { + mixing.setMotherRubberSg(formula.getARubberSg()); + } + mesXslMixingSpecService.saveMain(mixing, materials, null, null, null); + created++; + } + } + if (created <= 0) { + throw new IllegalArgumentException("未生成任何混炼示方,请检查机台配置"); + } + return created; + } + + private int normalizeMixingStages(Integer mixingStages) { + if (mixingStages == null || mixingStages <= 0) { + return 0; + } + return Math.min(mixingStages, 7); + } + + private String resolveRubberName(MesXslFormulaSpec main) { + if (StringUtils.isNotBlank(main.getBasicFormula())) { + return main.getBasicFormula().trim(); + } + if (StringUtils.isNotBlank(main.getRubberMaterialId())) { + MesMaterial rubber = mesMaterialService.getById(main.getRubberMaterialId()); + if (rubber != null && StringUtils.isNotBlank(rubber.getMaterialName())) { + return rubber.getMaterialName().trim(); + } + } + return ""; + } + + /** + * 配合示方胶料代号/示方编号中,胶料名称之后的后缀原样截取(如 SA01、SB01 等,不做固定拼接)。 + */ + private String resolveFormulaCodeSuffix(MesXslFormulaSpec main) { + if (main == null) { + return ""; + } + String code = StringUtils.isNotBlank(main.getRubberCode()) ? main.getRubberCode().trim() : ""; + if (StringUtils.isBlank(code) && StringUtils.isNotBlank(main.getSpecCode())) { + code = main.getSpecCode().trim(); + } + if (StringUtils.isBlank(code)) { + return ""; + } + String rubberName = resolveRubberName(main); + if (StringUtils.isBlank(rubberName)) { + return ""; + } + int nameIndex = code.indexOf(rubberName); + if (nameIndex >= 0 && nameIndex + rubberName.length() < code.length()) { + return code.substring(nameIndex + rubberName.length()); + } + String dNamePrefix = "D" + rubberName; + if (code.startsWith(dNamePrefix) && code.length() > dNamePrefix.length()) { + return code.substring(dNamePrefix.length()); + } + return ""; + } + + private String appendFormulaCodeSuffix(String baseSpecCode, String formulaCodeSuffix) { + if (StringUtils.isBlank(baseSpecCode)) { + return baseSpecCode; + } + if (StringUtils.isBlank(formulaCodeSuffix)) { + return baseSpecCode; + } + return baseSpecCode + formulaCodeSuffix; + } + + private boolean hasStepQ(List lines) { + if (CollectionUtils.isEmpty(lines)) { + return false; + } + for (MesXslFormulaSpecLine line : lines) { + if (line != null && "Q".equalsIgnoreCase(line.getStep())) { + return true; + } + } + return false; + } + + /** 解析 B/F 段对应的配合示方混合段列号 */ + private int resolveMixingColumn(MesXslFormulaMixingGenerateRowVO row, MesXslFormulaSpec formula) { + if ("Q".equalsIgnoreCase(resolveMixingMaterialStep(row))) { + Integer stages = formula != null ? formula.getMixingStages() : null; + if (stages != null && stages > 0) { + return Math.min(stages, 7); + } + } + if (row != null && row.getASegmentIndex() != null && row.getASegmentIndex() > 0) { + return Math.min(row.getASegmentIndex(), 7); + } + if (row != null && row.getStageIndex() != null && row.getStageIndex() > 0) { + return Math.min(row.getStageIndex(), 7); + } + String specCode = row != null ? row.getSpecCode() : null; + if (StringUtils.isNotBlank(specCode)) { + Matcher matcher = Pattern.compile("(?i)B(\\d+)").matcher(specCode.trim()); + if (matcher.find()) { + return Math.min(Integer.parseInt(matcher.group(1)), 7); + } + } + return 1; + } + + /** + * B1=第一段配合剂(列1 STEP=A);Bn(n>1)=上一段胶料示方一条(B{n-1}+胶料名)+本段列n配合剂。 + * F 段=最后一段B炼好胶一条(如三段时B2+胶料名)+本列 STEP=Q 配合剂。 + */ + private String resolveMixingMaterialStep(MesXslFormulaMixingGenerateRowVO row) { + if (row != null && StringUtils.isNotBlank(row.getStepType())) { + return row.getStepType().trim().toUpperCase(); + } + String specCode = row != null ? row.getSpecCode() : null; + if (StringUtils.isNotBlank(specCode) && specCode.trim().toUpperCase().startsWith("F")) { + return "Q"; + } + return "A"; + } + + private List buildMixingMaterials( + MesXslFormulaSpec formula, + List lines, + int stageIndex, + String materialStep, + Map mixerCache, + Map categoryNameCache, + Map categoryRubberCache) { + String stepFilter = StringUtils.isNotBlank(materialStep) ? materialStep.trim().toUpperCase() : "A"; + List materials = new ArrayList<>(); + int sort = 0; + if ("Q".equals(stepFilter)) { + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】F段加入最后一段B炼好胶料一条再加Q配合剂----------- + String rubberName = resolveRubberName(formula); + String codeSuffix = resolveFormulaCodeSuffix(formula); + int lastBSegment = resolveLastBSegmentIndex(formula, lines); + if (lastBSegment > 0) { + String motherSpecCode = appendFormulaCodeSuffix("B" + lastBSegment + rubberName, codeSuffix); + BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, lastBSegment); + materials.add(createMotherRubberMaterial(motherSpecCode, rubberName, motherWeight, materials.size())); + } + appendQStageColumnAgents(lines, stageIndex, materials, mixerCache, categoryNameCache, categoryRubberCache); + reindexMaterialSortNo(materials); + return materials; + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】F段加入最后一段B炼好胶料一条再加Q配合剂----------- + } + int bColumn = Math.max(stageIndex, 1); + String rubberName = resolveRubberName(formula); + String codeSuffix = resolveFormulaCodeSuffix(formula); + if (bColumn <= 1) { + appendBStageColumnAgents(lines, 1, materials, mixerCache, categoryNameCache, categoryRubberCache); + reindexMaterialSortNo(materials); + return materials; + } + // B2/B3…:上一段炼好胶料一条(如 B1+胶料名) + 本段列配合剂 + int prevB = bColumn - 1; + String motherSpecCode = appendFormulaCodeSuffix("B" + prevB + rubberName, codeSuffix); + BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, prevB); + materials.add(createMotherRubberMaterial(motherSpecCode, rubberName, motherWeight, materials.size())); + appendBStageColumnAgents(lines, bColumn, materials, mixerCache, categoryNameCache, categoryRubberCache); + reindexMaterialSortNo(materials); + return materials; + } + + /** 含 Q 时最后一段 B 的段号(如混合段3段则最后 B 为 B2) */ + private int resolveLastBSegmentIndex(MesXslFormulaSpec formula, List lines) { + int stageCount = normalizeMixingStages(formula != null ? formula.getMixingStages() : null); + if (stageCount <= 0 || !hasStepQ(lines)) { + return 0; + } + return stageCount > 1 ? stageCount - 1 : 0; + } + + /** F 段本列:STEP=Q 且该列有数值的配合剂 */ + private void appendQStageColumnAgents( + List lines, + int column, + List materials, + Map mixerCache, + Map categoryNameCache, + Map categoryRubberCache) { + for (MesXslFormulaSpecLine line : lines) { + if (!isLineStep(line, "Q")) { + continue; + } + BigDecimal unitWeight = readStageValue(line, column); + if (!hasStageNumericValue(unitWeight)) { + continue; + } + materials.add( + toMixingMaterial(line, unitWeight, materials.size(), mixerCache, categoryNameCache, categoryRubberCache)); + } + } + + /** 本段列:STEP=A 且该列有数值的配合剂 */ + private void appendBStageColumnAgents( + List lines, + int column, + List materials, + Map mixerCache, + Map categoryNameCache, + Map categoryRubberCache) { + for (MesXslFormulaSpecLine line : lines) { + if (!isLineStep(line, "A")) { + continue; + } + BigDecimal unitWeight = resolveBColumnUnitWeight(line, column); + if (!hasStageNumericValue(unitWeight)) { + continue; + } + materials.add( + toMixingMaterial(line, unitWeight, materials.size(), mixerCache, categoryNameCache, categoryRubberCache)); + } + } + + /** 上一段密炼产出胶料(一条):示方编号 B{n-1}+胶料名,种类=胶料 */ + private MesXslMixingSpecMaterial createMotherRubberMaterial( + String motherSpecCode, String rubberName, BigDecimal unitWeight, int sortNo) { + MesXslMixingSpecMaterial material = new MesXslMixingSpecMaterial(); + material.setSortNo(sortNo); + material.setMixerMaterialName(motherSpecCode); + material.setMixerMaterialDesc(StringUtils.isNotBlank(rubberName) ? rubberName : motherSpecCode); + material.setMaterialKind("胶料"); + material.setUnitWeight(unitWeight); + return material; + } + + /** 混合段累计合计:优先主表 stageNTotal,否则按明细该列求和 */ + private BigDecimal resolveStageCumulativeTotal(MesXslFormulaSpec formula, List lines, int column) { + BigDecimal fromMain = readStageTotalFromMain(formula, column); + if (hasStageNumericValue(fromMain)) { + return fromMain; + } + BigDecimal sum = BigDecimal.ZERO; + boolean hasAny = false; + for (MesXslFormulaSpecLine line : lines) { + if (line == null) { + continue; + } + BigDecimal w = readStageValue(line, column); + if (!hasStageNumericValue(w)) { + continue; + } + sum = sum.add(w); + hasAny = true; + } + return hasAny ? sum : null; + } + + private BigDecimal readStageTotalFromMain(MesXslFormulaSpec formula, int column) { + if (formula == null || column < 1 || column > 7) { + return null; + } + return switch (column) { + case 1 -> formula.getStage1Total(); + case 2 -> formula.getStage2Total(); + case 3 -> formula.getStage3Total(); + case 4 -> formula.getStage4Total(); + case 5 -> formula.getStage5Total(); + case 6 -> formula.getStage6Total(); + case 7 -> formula.getStage7Total(); + default -> null; + }; + } + + /** B 段单重:优先取当前列;第1列 STEP=A 可回退 PHR */ + private BigDecimal resolveBColumnUnitWeight(MesXslFormulaSpecLine line, int column) { + BigDecimal weight = readStageValue(line, column); + if (hasStageNumericValue(weight)) { + return weight; + } + if (column == 1 && isLineStep(line, "A") && line.getPhr() != null) { + return line.getPhr(); + } + return null; + } + + private void reindexMaterialSortNo(List materials) { + for (int i = 0; i < materials.size(); i++) { + materials.get(i).setSortNo(i); + } + } + + private boolean isLineStep(MesXslFormulaSpecLine line, String step) { + if (line == null || StringUtils.isBlank(step)) { + return false; + } + String lineStep = StringUtils.isNotBlank(line.getStep()) ? line.getStep().trim().toUpperCase() : ""; + return step.equalsIgnoreCase(lineStep); + } + + /** 混合段列是否有有效数值(非空且非 0) */ + private boolean hasStageNumericValue(BigDecimal value) { + return value != null && value.compareTo(BigDecimal.ZERO) != 0; + } + + private MesXslMixingSpecMaterial toMixingMaterial( + MesXslFormulaSpecLine line, + BigDecimal unitWeight, + int sortNo, + Map mixerCache, + Map categoryNameCache, + Map categoryRubberCache) { + 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(), mixerCache, categoryNameCache, categoryRubberCache); + return material; + } + + private BigDecimal readStageValue(MesXslFormulaSpecLine line, int stageIndex) { + if (line == null || stageIndex < 1 || stageIndex > 7) { + return null; + } + return switch (stageIndex) { + case 1 -> line.getStage1(); + case 2 -> line.getStage2(); + case 3 -> line.getStage3(); + case 4 -> line.getStage4(); + case 5 -> line.getStage5(); + case 6 -> line.getStage6(); + case 7 -> line.getStage7(); + default -> null; + }; + } + + private void fillMaterialCategory( + MesXslMixingSpecMaterial material, + String mixerMaterialId, + Map mixerCache, + Map categoryNameCache, + Map categoryRubberCache) { + if (oConvertUtils.isEmpty(mixerMaterialId)) { + return; + } + MesMixerMaterial mixer = mixerCache.computeIfAbsent(mixerMaterialId, id -> mesMixerMaterialService.getById(id)); + if (mixer == null) { + return; + } + String majorName = resolveCategoryName(mixer.getMajorCategoryId(), categoryNameCache); + String minorName = resolveCategoryName(mixer.getMinorCategoryId(), categoryNameCache); + material.setMaterialMajor(majorName); + material.setMaterialMinor(minorName); + material.setMaterialKind(resolveMixingMaterialKind(mixer.getMinorCategoryId(), minorName, categoryRubberCache)); + } + + /** + * 种类:物料小类在分类字典勾选「胶料」则显示「胶料」,否则显示小类分类名称。 + */ + private String resolveMixingMaterialKind( + String minorCategoryId, String minorCategoryName, Map categoryRubberCache) { + if (isCategoryRubber(minorCategoryId, categoryRubberCache)) { + return "胶料"; + } + if (StringUtils.isNotBlank(minorCategoryName)) { + return minorCategoryName; + } + return null; + } + + 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()); + } + + private String resolveCategoryName(String categoryId, Map cache) { + if (oConvertUtils.isEmpty(categoryId)) { + return null; + } + return cache.computeIfAbsent(categoryId, id -> { + SysCategory category = sysCategoryService.getById(id); + return category != null ? category.getName() : null; + }); + } + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方预览与批量创建----------- } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateMachineVO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateMachineVO.java new file mode 100644 index 0000000..4ec29c2 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateMachineVO.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** 生成混炼示方:机台 */ +@Data +@Schema(description = "生成混炼示方机台") +public class MesXslFormulaMixingGenerateMachineVO { + + @Schema(description = "设备台账ID") + private String machineId; + + @Schema(description = "机台名称") + private String machineName; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewItemVO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewItemVO.java new file mode 100644 index 0000000..7c7677c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewItemVO.java @@ -0,0 +1,25 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** 生成混炼示方:预览行 */ +@Data +@Schema(description = "生成混炼示方预览行") +public class MesXslFormulaMixingGeneratePreviewItemVO { + + @Schema(description = "行键(段序号)") + private Integer rowKey; + + @Schema(description = "示方编号(规格)") + private String specCode; + + @Schema(description = "混合段序号 1-7") + private Integer stageIndex; + + @Schema(description = "段类型:A 或 Q") + private String stepType; + + @Schema(description = "A段序号(仅A段有值)") + private Integer aSegmentIndex; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewVO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewVO.java new file mode 100644 index 0000000..ffbadbc --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGeneratePreviewVO.java @@ -0,0 +1,23 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Data; + +/** 生成混炼示方:预览结果 */ +@Data +@Schema(description = "生成混炼示方预览") +public class MesXslFormulaMixingGeneratePreviewVO { + + @Schema(description = "配合示方ID") + private String formulaSpecId; + + @Schema(description = "胶料名称") + private String rubberName; + + @Schema(description = "混合段数") + private Integer mixingStages; + + @Schema(description = "预览行") + private List items; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRequestVO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRequestVO.java new file mode 100644 index 0000000..479d0e0 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRequestVO.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Data; + +/** 生成混炼示方:确认请求 */ +@Data +@Schema(description = "生成混炼示方确认请求") +public class MesXslFormulaMixingGenerateRequestVO { + + @Schema(description = "配合示方ID") + private String formulaSpecId; + + @Schema(description = "确认行") + private List rows; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRowVO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRowVO.java new file mode 100644 index 0000000..858f462 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaMixingGenerateRowVO.java @@ -0,0 +1,26 @@ +package org.jeecg.modules.xslmes.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Data; + +/** 生成混炼示方:确认行(含机台) */ +@Data +@Schema(description = "生成混炼示方确认行") +public class MesXslFormulaMixingGenerateRowVO { + + @Schema(description = "示方编号(规格)") + private String specCode; + + @Schema(description = "混合段序号 1-7") + private Integer stageIndex; + + @Schema(description = "A段序号(B1/B2…,仅A段有值)") + private Integer aSegmentIndex; + + @Schema(description = "段类型:A 或 Q") + private String stepType; + + @Schema(description = "机台列表") + private List machines; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 b/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 index f6f1358..cd16fb7 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 @@ -418,3 +418,11 @@ jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecor jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/MesXslEquipInspectRecordList.vue jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordModal.vue jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectRecord/components/MesXslEquipInspectRecordHandleModal.vue +-- author:cursor---date:20260522--for: 【XSLMES-20260522-A31】分类字典原辅材料子类增加胶料标记字段 --- +jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_99__sys_category_is_rubber.sql +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysCategory.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java +jeecgboot-vue3/src/views/system/category/category.constants.ts +jeecgboot-vue3/src/views/system/category/category.data.ts +jeecgboot-vue3/src/views/system/category/components/CategoryModal.vue +jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSysCategoryModal.vue diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysCategory.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysCategory.java index e19273b..ee2f609 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysCategory.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysCategory.java @@ -49,6 +49,9 @@ public class SysCategory implements Serializable,Comparable{ /**是否有子节点*/ @Excel(name = "是否有子节点(1:有)", width = 15) private java.lang.String hasChild; + /**是否胶料(仅原辅材料子类有效) 1是/0否*/ + @Excel(name = "是否胶料", width = 15) + private java.lang.String isRubber; /**租户ID*/ private java.lang.Integer tenantId; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java index 5410273..869b23c 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java @@ -29,6 +29,9 @@ import java.util.stream.Collectors; @Service public class SysCategoryServiceImpl extends ServiceImpl implements ISysCategoryService { + /** 原辅材料分类编码(其子类可标记为胶料) */ + private static final String MATERIAL_RAW_AUX_CODE = "XSLMES_MATERIAL_RAW_AUX"; + @Override public void addSysCategory(SysCategory sysCategory) { String categoryPid = ISysCategoryService.ROOT_PID_VALUE; @@ -64,6 +67,9 @@ public class SysCategoryServiceImpl extends ServiceImpl queryListByCode(String pcode) throws JeecgBootException{ String pid = ROOT_PID_VALUE; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_100__mes_xsl_mixing_spec_stage_count_total.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_100__mes_xsl_mixing_spec_stage_count_total.sql new file mode 100644 index 0000000..bae3528 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_100__mes_xsl_mixing_spec_stage_count_total.sql @@ -0,0 +1,3 @@ +-- 段数存「当前段/总段数」文本,如 2/3(不新增字段) +ALTER TABLE `mes_xsl_mixing_spec` + MODIFY COLUMN `stage_count` varchar(20) DEFAULT NULL COMMENT '段数(当前/总)'; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_101__mes_xsl_mixing_spec_stage_count_revert_total.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_101__mes_xsl_mixing_spec_stage_count_revert_total.sql new file mode 100644 index 0000000..a85d7fc --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_101__mes_xsl_mixing_spec_stage_count_revert_total.sql @@ -0,0 +1,4 @@ +-- 回退误加的 stage_count_total,并确保 stage_count 为 varchar +ALTER TABLE `mes_xsl_mixing_spec` DROP COLUMN IF EXISTS `stage_count_total`; +ALTER TABLE `mes_xsl_mixing_spec` + MODIFY COLUMN `stage_count` varchar(20) DEFAULT NULL COMMENT '段数(当前/总)'; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_99__sys_category_is_rubber.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_99__sys_category_is_rubber.sql new file mode 100644 index 0000000..dd2daf0 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_99__sys_category_is_rubber.sql @@ -0,0 +1,20 @@ +-- 分类字典:原辅材料子类增加「胶料」标记字段(幂等) +SET NAMES utf8mb4; + +SET @db = DATABASE(); + +SET @sql = IF( + (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'sys_category' AND COLUMN_NAME = 'is_rubber') = 0, + 'ALTER TABLE `sys_category` ADD COLUMN `is_rubber` varchar(1) DEFAULT ''0'' COMMENT ''是否胶料 1是/0否'' AFTER `has_child`', + 'SELECT 1' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +-- 天然胶、合成胶、再生胶默认标记为胶料 +UPDATE `sys_category` +SET `is_rubber` = '1', `update_by` = 'admin', `update_time` = NOW() +WHERE `code` IN ( + 'XSLMES_MATERIAL_RAW_AUX_TRJ', + 'XSLMES_MATERIAL_RAW_AUX_HCJ', + 'XSLMES_MATERIAL_RAW_AUX_ZSJ' +); diff --git a/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSysCategoryModal.vue b/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSysCategoryModal.vue index fe6a3f2..9750f98 100644 --- a/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSysCategoryModal.vue +++ b/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSysCategoryModal.vue @@ -10,6 +10,13 @@ import { BasicModal, useModalInner } from '/@/components/Modal'; import { BasicForm, useForm } from '/@/components/Form'; import { defHttp } from '/@/utils/http/axios'; import { loadTreeData } from '/@/views/system/category/category.api'; +import { + MATERIAL_RAW_AUX_CODE, + materialRawAuxCategoryId, + isMaterialRawAuxSubCategory, + toIsRubberFlag, + fromIsRubberFlag, +} from '/@/views/system/category/category.constants'; import { useMessage } from '/@/hooks/web/useMessage'; import type { FormSchema } from '/@/components/Form'; import type { Recordable } from '/@/types/global'; @@ -34,6 +41,15 @@ const schemas: FormSchema[] = [ required: true, componentProps: { maxlength: 50, placeholder: '请输入分类名称' }, }, + { + label: ' ', + field: 'isRubber', + component: 'Checkbox', + defaultValue: false, + renderComponentContent: '胶料', + colProps: { span: 24 }, + ifShow: ({ values }) => isMaterialRawAuxSubCategory(values.pid), + }, ]; const [registerForm, { resetFields, setFieldsValue, validate, updateSchema, scrollToField }] = useForm({ @@ -64,10 +80,30 @@ async function buildPidTree(): Promise { ]; } +async function ensureMaterialRawAuxCategoryId() { + if (materialRawAuxCategoryId.value) { + return; + } + const res = await defHttp.get( + { url: '/sys/category/loadOne', params: { field: 'code', val: MATERIAL_RAW_AUX_CODE } }, + { isTransformResponse: false }, + ); + if (res?.success && res?.result?.id) { + materialRawAuxCategoryId.value = res.result.id; + } +} + +function normalizeSubmitValues(values: Recordable) { + const payload = { ...values }; + payload.isRubber = isMaterialRawAuxSubCategory(payload.pid) ? toIsRubberFlag(payload.isRubber) : '0'; + return payload; +} + const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { await resetFields(); setModalProps({ confirmLoading: false }); isUpdate.value = !!data?.isUpdate; + await ensureMaterialRawAuxCategoryId(); const tree = await buildPidTree(); if (!tree.length) { createMessage.warning('未加载到物料分类树,请确认分类字典根编码 XSLMES_MATERIAL 已存在'); @@ -89,7 +125,7 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data if (unref(isUpdate) && data?.record?.id) { const cat = await defHttp.get({ url: '/sys/category/queryById', params: { id: data.record.id } }); - await setFieldsValue({ id: cat.id, pid: cat.pid, name: cat.name }); + await setFieldsValue({ id: cat.id, pid: cat.pid, name: cat.name, isRubber: fromIsRubberFlag(cat.isRubber) }); } else { const pid = data?.parentId != null && data.parentId !== '' ? String(data.parentId) : ''; await setFieldsValue({ pid: pid || undefined, name: '' }); @@ -100,13 +136,13 @@ const title = computed(() => (unref(isUpdate) ? '编辑物料分类' : '新增 async function handleSubmit() { try { - const values = await validate(); + const values = normalizeSubmitValues(await validate()); setModalProps({ confirmLoading: true }); if (unref(isUpdate)) { const full = await defHttp.get({ url: '/sys/category/queryById', params: { id: values.id } }); - await editMaterialSysCategory({ ...full, pid: values.pid, name: values.name }); + await editMaterialSysCategory({ ...full, pid: values.pid, name: values.name, isRubber: values.isRubber }); } else { - await saveMaterialSysCategory({ pid: values.pid, name: values.name }); + await saveMaterialSysCategory({ pid: values.pid, name: values.name, isRubber: values.isRubber }); } closeModal(); emit('success'); diff --git a/jeecgboot-vue3/src/views/system/category/category.constants.ts b/jeecgboot-vue3/src/views/system/category/category.constants.ts new file mode 100644 index 0000000..011798f --- /dev/null +++ b/jeecgboot-vue3/src/views/system/category/category.constants.ts @@ -0,0 +1,22 @@ +import { ref } from 'vue'; + +/** MES 物料分类 - 原辅材料编码 */ +export const MATERIAL_RAW_AUX_CODE = 'XSLMES_MATERIAL_RAW_AUX'; + +/** 原辅材料分类节点 ID(运行时加载) */ +export const materialRawAuxCategoryId = ref(''); + +/** 是否为原辅材料的直接子类 */ +export function isMaterialRawAuxSubCategory(pid?: string) { + return !!materialRawAuxCategoryId.value && pid === materialRawAuxCategoryId.value; +} + +/** 表单 Checkbox 布尔值 -> 数据库存储值 */ +export function toIsRubberFlag(value: unknown) { + return value === true || value === '1' ? '1' : '0'; +} + +/** 数据库存储值 -> 表单 Checkbox 布尔值 */ +export function fromIsRubberFlag(value: unknown) { + return value === '1' || value === 1 || value === true; +} diff --git a/jeecgboot-vue3/src/views/system/category/category.data.ts b/jeecgboot-vue3/src/views/system/category/category.data.ts index 334560e..8adedf2 100644 --- a/jeecgboot-vue3/src/views/system/category/category.data.ts +++ b/jeecgboot-vue3/src/views/system/category/category.data.ts @@ -1,5 +1,6 @@ import { BasicColumn } from '/@/components/Table'; import { FormSchema } from '/@/components/Table'; +import { isMaterialRawAuxSubCategory } from './category.constants'; export const columns: BasicColumn[] = [ { @@ -73,4 +74,13 @@ export const formSchema: FormSchema[] = [ placeholder: '留空将按规则自动生成(如 A01.A02)', }, }, + { + label: ' ', + field: 'isRubber', + component: 'Checkbox', + defaultValue: false, + renderComponentContent: '胶料', + colProps: { span: 24 }, + show: ({ values }) => isMaterialRawAuxSubCategory(values.pid), + }, ]; diff --git a/jeecgboot-vue3/src/views/system/category/components/CategoryModal.vue b/jeecgboot-vue3/src/views/system/category/components/CategoryModal.vue index ee9671e..a59b3e2 100644 --- a/jeecgboot-vue3/src/views/system/category/components/CategoryModal.vue +++ b/jeecgboot-vue3/src/views/system/category/components/CategoryModal.vue @@ -9,12 +9,40 @@ import { BasicForm, useForm } from '/src/components/Form'; import { formSchema } from '../category.data'; import { loadTreeData, saveOrUpdateDict } from '../category.api'; + import { defHttp } from '/@/utils/http/axios'; + import { + MATERIAL_RAW_AUX_CODE, + materialRawAuxCategoryId, + isMaterialRawAuxSubCategory, + toIsRubberFlag, + fromIsRubberFlag, + } from '../category.constants'; + import type { Recordable } from '/@/types/global'; // 获取emit const emit = defineEmits(['register', 'success']); const isUpdate = ref(true); const expandedRowKeys = ref([]); const treeData = ref([]); const isSubAdd = ref(false); + + async function ensureMaterialRawAuxCategoryId() { + if (materialRawAuxCategoryId.value) { + return; + } + const res = await defHttp.get( + { url: '/sys/category/loadOne', params: { field: 'code', val: MATERIAL_RAW_AUX_CODE } }, + { isTransformResponse: false }, + ); + if (res?.success && res?.result?.id) { + materialRawAuxCategoryId.value = res.result.id; + } + } + + function normalizeSubmitValues(values: Recordable) { + const payload = { ...values }; + payload.isRubber = isMaterialRawAuxSubCategory(payload.pid) ? toIsRubberFlag(payload.isRubber) : '0'; + return payload; + } //表单配置 const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({ schemas: formSchema, @@ -35,12 +63,14 @@ expandedRowKeys.value = []; setModalProps({ confirmLoading: false, minHeight: 80 }); isUpdate.value = !!data?.isUpdate; + await ensureMaterialRawAuxCategoryId(); // 代码逻辑说明: 分类字典data.record为空报错------------ isSubAdd.value = !data?.isUpdate && data.record && data.record.id; if (data?.record) { //表单赋值 await setFieldsValue({ ...data.record, + isRubber: fromIsRubberFlag(data.record.isRubber), }); } //父级节点树信息 @@ -76,6 +106,7 @@ async function handleSubmit() { try { let values = await validate(); + values = normalizeSubmitValues(values); setModalProps({ confirmLoading: true }); //提交表单 await saveOrUpdateDict(values, isUpdate.value); diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerMultiSelectModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerMultiSelectModal.vue new file mode 100644 index 0000000..fe34ebc --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerMultiSelectModal.vue @@ -0,0 +1,76 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts index cd57ce4..0c034b7 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts @@ -14,6 +14,8 @@ enum Api { generateRubberCode = '/xslmes/mesXslFormulaSpec/generateRubberCode', getRubberContentSetting = '/xslmes/mesXslFormulaSpec/getRubberContentSetting', saveRubberContentSetting = '/xslmes/mesXslFormulaSpec/saveRubberContentSetting', + buildMixingGeneratePreview = '/xslmes/mesXslFormulaSpec/buildMixingGeneratePreview', + generateMixingSpec = '/xslmes/mesXslFormulaSpec/generateMixingSpec', } export const getExportUrl = Api.exportXls; @@ -41,3 +43,9 @@ export const batchDelete = (params, handleSuccess) => { }; export const saveOrUpdate = (params, isUpdate) => defHttp.post({ url: isUpdate ? Api.edit : Api.save, params }); + +//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方----------- +export const buildMixingGeneratePreview = (params) => + defHttp.get({ url: Api.buildMixingGeneratePreview, params }, { successMessageMode: 'none' }); +export const generateMixingSpec = (params) => defHttp.post({ url: Api.generateMixingSpec, params }); +//update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方----------- diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpecList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpecList.vue index 1e000e9..a69c7a8 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpecList.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpecList.vue @@ -36,27 +36,40 @@ + + 生成混炼示方 + + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue index 3cdf834..fe89e22 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue @@ -8,6 +8,17 @@ @register="registerModal" @ok="handleSubmit" > + @@ -439,6 +451,7 @@ } from '../MesXslFormulaSpec.data'; import { saveOrUpdate, queryById, generateRubberCode as generateRubberCodeApi, getRubberContentSetting } from '../MesXslFormulaSpec.api'; import MesXslFormulaRubberContentSettingModal from './MesXslFormulaRubberContentSettingModal.vue'; + import MesXslFormulaGenerateMixingModal from './MesXslFormulaGenerateMixingModal.vue'; import MesXslFormulaLineColumnSetting from './MesXslFormulaLineColumnSetting.vue'; import { queryById as queryMixerById } from '/@/views/mes/material/MesMixerMaterial.api'; import { buildUUID } from '/@/utils/uuid'; @@ -518,6 +531,7 @@ const [registerIssueNumberModal, { openModal: openIssueNumberModalInner }] = useModal(); const [registerIssueDeptModal, { openModal: openIssueDeptModalInner }] = useModal(); const [registerRubberContentSettingModal, { openModal: openRubberContentSettingModal }] = useModal(); + const [registerGenerateMixingModal, { openModal: openGenerateMixingModal }] = useModal(); const issueDeptPickerValue = ref(''); const rubberMaterialPickerId = ref(''); const mixerPsCompilePickerId = ref(''); @@ -1172,6 +1186,19 @@ return !unref(isUpdate) ? '新增配合示方' : '编辑配合示方'; }); + const showGenerateMixingBtn = computed( + () => !showFooterFlag.value && unref(isUpdate) && !!loadedMainRecord.value?.id, + ); + + function handleGenerateMixing() { + const id = loadedMainRecord.value?.id; + if (!id) { + createMessage.warning('请先保存配合示方'); + return; + } + openGenerateMixingModal(true, { formulaSpecId: id }); + } + async function handleLineValueChange(event) { const { row, column } = event || {}; if (!row || !column) { diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixerAction/components/MesXslMixerActionSelectModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixerAction/components/MesXslMixerActionSelectModal.vue new file mode 100644 index 0000000..53439bf --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixerAction/components/MesXslMixerActionSelectModal.vue @@ -0,0 +1,91 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/components/MesXslMixerConditionSelectModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/components/MesXslMixerConditionSelectModal.vue new file mode 100644 index 0000000..7865c68 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/components/MesXslMixerConditionSelectModal.vue @@ -0,0 +1,91 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts index e9e089e..415d138 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts @@ -35,7 +35,7 @@ export const columns: BasicColumn[] = [ { title: '机台', align: 'center', dataIndex: 'machineName', width: 120 }, { title: '制作日期', align: 'center', dataIndex: 'makeDate', width: 120 }, { title: '发行编号', align: 'center', dataIndex: 'issueNumber', width: 150 }, - { title: '段数', align: 'center', dataIndex: 'stageCount', width: 80 }, + { title: '段数', align: 'center', dataIndex: 'stageCount', width: 88 }, { title: '纯混炼时间(秒)', align: 'center', dataIndex: 'pureMixSec', width: 130 }, { title: '变更日期', align: 'center', dataIndex: 'changeDate', width: 120 }, { title: '修改时间', align: 'center', dataIndex: 'updateTime', width: 165 }, @@ -49,18 +49,21 @@ export const searchFormSchema: FormSchema[] = [ export const mainSchema: FormSchema[] = [ { label: '', field: 'id', component: 'Input', show: false }, + { label: '', field: 'machineId', component: 'Input', show: false }, { label: '规格', field: 'specName', component: 'Input', required: true, colProps: { span: 8 } }, - { label: '用途', field: 'purpose', component: 'AutoComplete', required: true, colProps: { span: 8 } }, + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】混炼示方基本信息字段优化----------- + { label: '用途', field: 'purpose', component: 'Input', required: true, colProps: { span: 8 } }, { label: '机台', field: 'machineName', component: 'Input', colProps: { span: 8 } }, { label: '制作日期', field: 'makeDate', component: 'DatePicker', colProps: { span: 8 }, componentProps: { valueFormat: 'YYYY-MM-DD' } }, - { label: '发行编号', field: 'issueNumber', component: 'AutoComplete', required: true, colProps: { span: 8 } }, + { label: '发行编号', field: 'issueNumber', component: 'Input', required: true, colProps: { span: 8 } }, + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】混炼示方基本信息字段优化----------- { label: '换算系数', field: 'convertFactor', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, { label: '填充体积', field: 'fillVolume', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, { label: '回收炭黑(秒)', field: 'recycleCarbonSec', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } }, { label: '母胶比重', field: 'motherRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, { label: '终炼胶比重', field: 'finalRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, { label: '适用工厂', field: 'applyFactory', component: 'Input', colProps: { span: 8 } }, - { label: '段数', field: 'stageCount', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } }, + { label: '段数', field: 'stageCount', component: 'Input', colProps: { span: 8 }, componentProps: { placeholder: '如 2/3' } }, { label: '纯混炼时间(秒)', field: 'pureMixSec', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } }, { label: '回收炭黑(KG)', field: 'recycleCarbonKg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, { label: '自动小料打印设定', field: 'autoSmallPrintSetting', component: 'Input', colProps: { span: 8 } }, @@ -198,13 +201,32 @@ export function calcMixingMaterialTableWidth(columns: JVxeColumn[], widthMap: Re export const MIXING_STEP_MIN_COLUMN_WIDTH = 48; export const stepColumns: JVxeColumn[] = [ - { title: '动作', key: 'actionName', type: JVxeTypes.input, width: 120, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH }, + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角----------- + { + title: '动作', + key: 'actionName', + type: JVxeTypes.slot, + slotName: 'actionNameSlot', + width: 120, + minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, + }, + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角----------- { title: '时间(")', key: 'actionSec', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, { title: '保护时间', key: 'protectSec', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, { title: '温度(℃)', key: 'tempC', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, { title: '功率(Kw)', key: 'powerKw', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, { title: '能量(Kwh)', key: 'energyKwh', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, - { title: '组合', key: 'comboMode', type: JVxeTypes.input, width: 72, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角----------- + { + title: '组合', + key: 'comboMode', + type: JVxeTypes.slot, + slotName: 'comboModeSlot', + width: 72, + minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, + align: 'center', + }, + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角----------- { title: '转速(rpm)', key: 'speedRpm', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, { title: '压力(Mpa)', key: 'pressureMpa', type: JVxeTypes.inputNumber, width: 80, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, { title: '栓(%)', key: 'boltPercent', type: JVxeTypes.inputNumber, width: 72, minWidth: MIXING_STEP_MIN_COLUMN_WIDTH, align: 'center' }, @@ -281,7 +303,9 @@ export const MIXING_TCU_COLUMN_WIDTH_CACHE_KEY = 'mes_xsl_mixing_spec_tcu_column export const MIXING_TCU_MIN_COLUMN_WIDTH = 48; export const tcuColumns: JVxeColumn[] = [ - { title: '区分', key: 'sectionType', type: JVxeTypes.select, dictCode: 'xslmes_mixing_tcu_section', width: 96, minWidth: MIXING_TCU_MIN_COLUMN_WIDTH, align: 'center' }, + //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】TCU区分固定上/下密炼机----------- + { title: '区分', key: 'sectionType', type: JVxeTypes.select, dictCode: 'xslmes_mixing_tcu_section', disabled: true, width: 96, minWidth: MIXING_TCU_MIN_COLUMN_WIDTH, align: 'center' }, + //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】TCU区分固定上/下密炼机----------- { title: '前转子温度', key: 'frontRotorTemp', type: JVxeTypes.inputNumber, width: 76, minWidth: MIXING_TCU_MIN_COLUMN_WIDTH, align: 'center' }, { title: '后转子温度', key: 'rearRotorTemp', type: JVxeTypes.inputNumber, width: 76, minWidth: MIXING_TCU_MIN_COLUMN_WIDTH, align: 'center' }, { title: '前混炼室温度', key: 'frontChamberTemp', type: JVxeTypes.inputNumber, width: 76, minWidth: MIXING_TCU_MIN_COLUMN_WIDTH, align: 'center' }, @@ -580,8 +604,36 @@ export function createEmptyDownStepRows(count = DEFAULT_MIXING_DOWN_STEP_ROW_COU return createEmptyMixingRows(count); } +//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】TCU默认两行及上密炼机药品称默认值----------- +/** 上密炼机 TCU 行默认药品称量位置(药品称) */ +export const MIXING_TCU_UP_MIXER_DRUG_WEIGH_POS = 'drug_scale'; + +/** 构建 TCU 温度条件默认两行(上密炼机/下密炼机) */ +export function buildDefaultMixingTcuRows(rows: Recordable[] = []): Recordable[] { + const up = + rows.find((r) => r.sectionType === 'up_mixer') || + ({ sectionType: 'up_mixer', drugWeighPos: MIXING_TCU_UP_MIXER_DRUG_WEIGH_POS } as Recordable); + if (up.sectionType === 'up_mixer' && !up.drugWeighPos) { + up.drugWeighPos = MIXING_TCU_UP_MIXER_DRUG_WEIGH_POS; + } + const down = rows.find((r) => r.sectionType === 'down_mixer') || ({ sectionType: 'down_mixer', drugWeighPos: undefined } as Recordable); + return [up, down]; +} +//update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】TCU默认两行及上密炼机药品称默认值----------- + /** 确保明细行具备唯一 id(JVxeTable 依赖 rowKey=id) */ export function normalizeMixingDetailRows(rows: Recordable[] = []): Recordable[] { return (rows || []).map((row) => ({ ...row, id: row?.id || buildUUID() })); } + +//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A39】编辑页明细补齐默认空行与新增一致----------- +/** 编辑/详情加载时补齐明细默认空行(不少于 defaultCount,已有数据行保留) */ +export function ensureMixingDetailRows(rows: Recordable[] = [], defaultCount: number): Recordable[] { + const normalized = normalizeMixingDetailRows(rows); + if (normalized.length >= defaultCount) { + return normalized; + } + return [...normalized, ...createEmptyMixingRows(defaultCount - normalized.length)]; +} +//update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A39】编辑页明细补齐默认空行与新增一致----------- //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A22】明细表默认空行数----------- diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue index 4e41b05..d1c244c 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue @@ -28,22 +28,28 @@ 发行编号 - - + @@ -63,16 +69,13 @@ 用途 - 母胶比重 @@ -81,7 +84,13 @@ 段数 - + 纯混炼时间(秒) @@ -253,7 +262,28 @@ :disabled="!showFooter" @resizable-change="handleStepColumnResize" @column-resizable-change="handleStepColumnResize" - /> + > + + + @@ -282,7 +312,28 @@ :disabled="!showFooter" @resizable-change="handleStepColumnResize" @column-resizable-change="handleStepColumnResize" - /> + > + + + @@ -317,13 +368,17 @@ + + + + +