新增混炼示方生成预览与批量创建功能,优化相关字段及用户交互,修复界面显示问题,增强系统稳定性和用户体验。
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<MesXslFormulaSp
|
||||
}
|
||||
//update-end---author:cursor ---date:20260521 for:【配合示方】含胶率物料小类可配置-----------
|
||||
|
||||
//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方-----------
|
||||
@Operation(summary = "MES配合示方-生成混炼示方预览")
|
||||
@GetMapping(value = "/buildMixingGeneratePreview")
|
||||
public Result<MesXslFormulaMixingGeneratePreviewVO> 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<Map<String, Object>> 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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<MesXslFormulaSpec> {
|
||||
|
||||
@@ -36,4 +38,18 @@ public interface IMesXslFormulaSpecService extends IService<MesXslFormulaSpec> {
|
||||
*/
|
||||
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】配合示方生成混炼示方预览与批量创建-----------
|
||||
}
|
||||
|
||||
@@ -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<MesXslFormulaSpecM
|
||||
@Resource
|
||||
private ISysUserService sysUserService;
|
||||
|
||||
@Resource
|
||||
private IMesXslMixingSpecService mesXslMixingSpecService;
|
||||
|
||||
@Resource
|
||||
private ISysCategoryService sysCategoryService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveMain(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList) {
|
||||
@@ -434,4 +453,488 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
|
||||
this.update(wrapper);
|
||||
}
|
||||
//update-end---author:cursor ---date:20260522 for:【配合示方】密炼PS审批联动同步状态与审批人-----------
|
||||
|
||||
//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方预览与批量创建-----------
|
||||
@Override
|
||||
public MesXslFormulaMixingGeneratePreviewVO buildMixingGeneratePreview(String formulaSpecId) {
|
||||
MesXslFormulaSpec main = getByIdWithLines(formulaSpecId);
|
||||
if (main == null) {
|
||||
throw new IllegalArgumentException("未找到配合示方数据");
|
||||
}
|
||||
int stageCount = normalizeMixingStages(main.getMixingStages());
|
||||
if (stageCount <= 0) {
|
||||
throw new IllegalArgumentException("请先维护混合段数");
|
||||
}
|
||||
String rubberName = resolveRubberName(main);
|
||||
String formulaCodeSuffix = resolveFormulaCodeSuffix(main);
|
||||
boolean hasQ = hasStepQ(main.getLineList());
|
||||
List<MesXslFormulaMixingGeneratePreviewItemVO> 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<MesXslFormulaSpecLine> lines = formula.getLineList();
|
||||
if (CollectionUtils.isEmpty(lines)) {
|
||||
throw new IllegalArgumentException("配合示方明细为空,无法生成混炼示方");
|
||||
}
|
||||
Map<String, MesMixerMaterial> mixerCache = new HashMap<>();
|
||||
Map<String, String> categoryNameCache = new HashMap<>();
|
||||
Map<String, Boolean> 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<MesXslMixingSpecMaterial> 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<MesXslFormulaSpecLine> 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<MesXslMixingSpecMaterial> buildMixingMaterials(
|
||||
MesXslFormulaSpec formula,
|
||||
List<MesXslFormulaSpecLine> lines,
|
||||
int stageIndex,
|
||||
String materialStep,
|
||||
Map<String, MesMixerMaterial> mixerCache,
|
||||
Map<String, String> categoryNameCache,
|
||||
Map<String, Boolean> categoryRubberCache) {
|
||||
String stepFilter = StringUtils.isNotBlank(materialStep) ? materialStep.trim().toUpperCase() : "A";
|
||||
List<MesXslMixingSpecMaterial> 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<MesXslFormulaSpecLine> 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<MesXslFormulaSpecLine> lines,
|
||||
int column,
|
||||
List<MesXslMixingSpecMaterial> materials,
|
||||
Map<String, MesMixerMaterial> mixerCache,
|
||||
Map<String, String> categoryNameCache,
|
||||
Map<String, Boolean> 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<MesXslFormulaSpecLine> lines,
|
||||
int column,
|
||||
List<MesXslMixingSpecMaterial> materials,
|
||||
Map<String, MesMixerMaterial> mixerCache,
|
||||
Map<String, String> categoryNameCache,
|
||||
Map<String, Boolean> 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<MesXslFormulaSpecLine> 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<MesXslMixingSpecMaterial> 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<String, MesMixerMaterial> mixerCache,
|
||||
Map<String, String> categoryNameCache,
|
||||
Map<String, Boolean> 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<String, MesMixerMaterial> mixerCache,
|
||||
Map<String, String> categoryNameCache,
|
||||
Map<String, Boolean> 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<String, Boolean> categoryRubberCache) {
|
||||
if (isCategoryRubber(minorCategoryId, categoryRubberCache)) {
|
||||
return "胶料";
|
||||
}
|
||||
if (StringUtils.isNotBlank(minorCategoryName)) {
|
||||
return minorCategoryName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isCategoryRubber(String categoryId, Map<String, Boolean> 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<String, String> 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】配合示方生成混炼示方预览与批量创建-----------
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<MesXslFormulaMixingGeneratePreviewItemVO> items;
|
||||
}
|
||||
@@ -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<MesXslFormulaMixingGenerateRowVO> rows;
|
||||
}
|
||||
@@ -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<MesXslFormulaMixingGenerateMachineVO> machines;
|
||||
}
|
||||
Reference in New Issue
Block a user