新增配方日志查询功能,记录配方和混炼示方的创建、更新与删除操作,增强数据追溯能力。

This commit is contained in:
geht
2026-05-26 17:50:55 +08:00
parent c70f7b2b90
commit 9e36435a72
19 changed files with 9926 additions and 0 deletions

View File

@@ -414,3 +414,26 @@ jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/ser
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerPsCompileServiceImpl.java
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts
jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpecList.vue
-- author:cursor---date:20260526--for: 【配方日志查询】配合示方/混炼示方修改日志记录与查询接口 -----------
jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_107__mes_xsl_formula_spec_edit_log.sql
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslFormulaSpecEditLog.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaSpecEditChangeItemVO.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/vo/MesXslFormulaSpecEditLogDetailVO.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslFormulaSpecEditLogMapper.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/common/MesXslFormulaSpecEditLogDiffUtil.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslFormulaSpecEditLogService.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecEditLogServiceImpl.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslFormulaSpecEditLogController.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/service/impl/MesXslMixingSpecServiceImpl.java
-- author:cursor---date:20260526--for: 【配方日志查询】前端列表页与修改对比弹窗 -----------
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpecEditLog/MesXslFormulaSpecEditLog.api.ts
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpecEditLog/MesXslFormulaSpecEditLog.data.ts
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpecEditLog/MesXslFormulaSpecEditLogList.vue
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpecEditLog/components/MesXslFormulaSpecEditLogCompareModal.vue
-- author:cursor---date:20260526--for: 【配方日志查询】明细对比展示逐行逐字段变更内容 -----------
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/common/MesXslFormulaSpecEditLogDiffUtil.java
jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpecEditLog/MesXslFormulaSpecEditLog.data.ts

View File

@@ -0,0 +1,546 @@
package org.jeecg.modules.xslmes.common;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpec;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecLine;
import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecEditChangeItemVO;
import org.jeecg.modules.xslmes.vo.MesXslMixingSpecPage;
/**
* 配方示方修改日志:快照序列化与差异对比
*/
public final class MesXslFormulaSpecEditLogDiffUtil {
public static final String SECTION_MAIN = "main";
public static final String SECTION_LINE = "line";
public static final String SECTION_MATERIAL = "material";
public static final String SECTION_STEP = "step";
public static final String SECTION_DOWN_STEP = "downStep";
public static final String SECTION_TCU = "tcu";
private static final Set<String> IGNORE_FIELDS = Set.of(
"id",
"createBy",
"createTime",
"updateBy",
"updateTime",
"delFlag",
"tenantId",
"sysOrgCode",
"createBy_dictText",
"lineList",
"materialList",
"stepList",
"downStepList",
"tcuList");
private static final Map<String, String> FORMULA_MAIN_LABELS = buildFormulaMainLabels();
private static final Map<String, String> MIXING_MAIN_LABELS = buildMixingMainLabels();
private static final Map<String, String> SECTION_LABELS = Map.of(
SECTION_MAIN, "主表",
SECTION_LINE, "配合明细",
SECTION_MATERIAL, "橡胶及配合剂",
SECTION_STEP, "混合步骤",
SECTION_DOWN_STEP, "下密炼机条件",
SECTION_TCU, "TCU温度条件");
private static final Map<String, Map<String, String>> SECTION_FIELD_LABELS = buildSectionFieldLabels();
private static final Map<String, String[]> SECTION_SUMMARY_FIELDS = buildSectionSummaryFields();
private MesXslFormulaSpecEditLogDiffUtil() {}
public static String buildFormulaSnapshotJson(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList) {
Map<String, Object> snapshot = new LinkedHashMap<>(2);
snapshot.put(SECTION_MAIN, toJsonObject(main));
snapshot.put(SECTION_LINE, lineList == null ? List.of() : lineList);
return toJson(snapshot);
}
public static String buildMixingSnapshotJson(MesXslMixingSpecPage page) {
if (page == null) {
return null;
}
Map<String, Object> snapshot = new LinkedHashMap<>(5);
snapshot.put(SECTION_MAIN, toJsonObject(page));
snapshot.put(SECTION_MATERIAL, page.getMaterialList() == null ? List.of() : page.getMaterialList());
snapshot.put(SECTION_STEP, page.getStepList() == null ? List.of() : page.getStepList());
snapshot.put(SECTION_DOWN_STEP, page.getDownStepList() == null ? List.of() : page.getDownStepList());
snapshot.put(SECTION_TCU, page.getTcuList() == null ? List.of() : page.getTcuList());
return toJson(snapshot);
}
public static List<MesXslFormulaSpecEditChangeItemVO> compare(
String specType, String beforeSnapshot, String afterSnapshot) {
List<MesXslFormulaSpecEditChangeItemVO> items = new ArrayList<>();
JSONObject before = parseObject(beforeSnapshot);
JSONObject after = parseObject(afterSnapshot);
Map<String, String> mainLabels = SPEC_TYPE_MIXING.equals(specType) ? MIXING_MAIN_LABELS : FORMULA_MAIN_LABELS;
compareMainSection(items, before == null ? null : before.getJSONObject(SECTION_MAIN),
after == null ? null : after.getJSONObject(SECTION_MAIN), mainLabels);
if (SPEC_TYPE_FORMULA.equals(specType)) {
compareChildListSection(items, SECTION_LINE, before, after);
} else {
compareChildListSection(items, SECTION_MATERIAL, before, after);
compareChildListSection(items, SECTION_STEP, before, after);
compareChildListSection(items, SECTION_DOWN_STEP, before, after);
compareChildListSection(items, SECTION_TCU, before, after);
}
return items;
}
public static String buildSummary(String actionType, List<MesXslFormulaSpecEditChangeItemVO> items) {
if ("create".equals(actionType)) {
return "新增示方";
}
if ("delete".equals(actionType)) {
return "删除示方";
}
if (items == null || items.isEmpty()) {
return "内容无变化";
}
Set<String> labels = new LinkedHashSet<>();
for (MesXslFormulaSpecEditChangeItemVO item : items) {
if (SECTION_MAIN.equals(item.getSection()) && StringUtils.isNotBlank(item.getFieldLabel())) {
labels.add(item.getFieldLabel());
} else if (StringUtils.isNotBlank(item.getSectionLabel())) {
labels.add(item.getSectionLabel());
}
}
if (labels.isEmpty()) {
return "内容有变更";
}
String joined = String.join("", labels);
if (joined.length() > 180) {
joined = joined.substring(0, 177) + "...";
}
return "修改:" + joined;
}
private static void compareMainSection(
List<MesXslFormulaSpecEditChangeItemVO> items,
JSONObject before,
JSONObject after,
Map<String, String> labels) {
Set<String> keys = new LinkedHashSet<>();
if (before != null) {
keys.addAll(before.keySet());
}
if (after != null) {
keys.addAll(after.keySet());
}
for (String key : keys) {
if (IGNORE_FIELDS.contains(key)) {
continue;
}
String beforeVal = formatValue(before == null ? null : before.get(key));
String afterVal = formatValue(after == null ? null : after.get(key));
if (Objects.equals(beforeVal, afterVal)) {
continue;
}
MesXslFormulaSpecEditChangeItemVO item = new MesXslFormulaSpecEditChangeItemVO();
item.setSection(SECTION_MAIN);
item.setSectionLabel(SECTION_LABELS.get(SECTION_MAIN));
item.setFieldKey(key);
item.setFieldLabel(labels.getOrDefault(key, key));
item.setBeforeValue(beforeVal);
item.setAfterValue(afterVal);
items.add(item);
}
}
private static void compareChildListSection(
List<MesXslFormulaSpecEditChangeItemVO> items, String section, JSONObject before, JSONObject after) {
List<JSONObject> beforeList = toJsonObjectList(before == null ? null : before.get(section));
List<JSONObject> afterList = toJsonObjectList(after == null ? null : after.get(section));
if (Objects.equals(normalizeListJson(beforeList), normalizeListJson(afterList))) {
return;
}
Map<String, String> fieldLabels = SECTION_FIELD_LABELS.getOrDefault(section, Map.of());
String[] summaryFields = SECTION_SUMMARY_FIELDS.getOrDefault(section, new String[0]);
Map<String, JSONObject> beforeMap = indexRows(beforeList);
Map<String, JSONObject> afterMap = indexRows(afterList);
Set<String> rowKeys = new LinkedHashSet<>();
rowKeys.addAll(beforeMap.keySet());
rowKeys.addAll(afterMap.keySet());
for (String rowKey : rowKeys) {
JSONObject beforeRow = beforeMap.get(rowKey);
JSONObject afterRow = afterMap.get(rowKey);
String rowLabel = formatRowLabel(rowKey);
if (beforeRow == null && afterRow != null) {
addChangeItem(items, section, rowKey + "_add", rowLabel + "(新增)", "",
formatRowSummary(afterRow, fieldLabels, summaryFields));
continue;
}
if (beforeRow != null && afterRow == null) {
addChangeItem(items, section, rowKey + "_del", rowLabel + "(删除)",
formatRowSummary(beforeRow, fieldLabels, summaryFields), "");
continue;
}
compareRowFields(items, section, rowKey, rowLabel, beforeRow, afterRow, fieldLabels);
}
}
private static void compareRowFields(
List<MesXslFormulaSpecEditChangeItemVO> items,
String section,
String rowKey,
String rowLabel,
JSONObject beforeRow,
JSONObject afterRow,
Map<String, String> fieldLabels) {
Set<String> keys = new LinkedHashSet<>();
keys.addAll(beforeRow.keySet());
keys.addAll(afterRow.keySet());
for (String key : keys) {
if (IGNORE_FIELDS.contains(key) || isRowMetaField(key)) {
continue;
}
String beforeVal = formatValue(beforeRow.get(key));
String afterVal = formatValue(afterRow.get(key));
if (Objects.equals(beforeVal, afterVal)) {
continue;
}
addChangeItem(
items,
section,
rowKey + "_" + key,
rowLabel + "·" + fieldLabels.getOrDefault(key, key),
beforeVal,
afterVal);
}
}
private static void addChangeItem(
List<MesXslFormulaSpecEditChangeItemVO> items,
String section,
String fieldKey,
String fieldLabel,
String beforeValue,
String afterValue) {
MesXslFormulaSpecEditChangeItemVO item = new MesXslFormulaSpecEditChangeItemVO();
item.setSection(section);
item.setSectionLabel(SECTION_LABELS.getOrDefault(section, section));
item.setFieldKey(fieldKey);
item.setFieldLabel(fieldLabel);
item.setBeforeValue(beforeValue);
item.setAfterValue(afterValue);
items.add(item);
}
/** 按 sortNo 优先、否则按列表序号建立行索引 */
private static Map<String, JSONObject> indexRows(List<JSONObject> rows) {
Map<String, JSONObject> map = new LinkedHashMap<>();
if (rows == null) {
return map;
}
int index = 0;
for (JSONObject row : rows) {
index++;
if (row == null) {
continue;
}
Integer sortNo = row.getInteger("sortNo");
String key = sortNo != null ? "sort_" + sortNo : "idx_" + index;
map.put(key, row);
}
return map;
}
private static String formatRowLabel(String rowKey) {
if (rowKey.startsWith("sort_")) {
return "" + rowKey.substring(5) + "";
}
if (rowKey.startsWith("idx_")) {
return "" + rowKey.substring(4) + "";
}
return rowKey;
}
private static String formatRowSummary(JSONObject row, Map<String, String> fieldLabels, String[] summaryFields) {
if (row == null || row.isEmpty()) {
return "";
}
List<String> parts = new ArrayList<>();
for (String key : summaryFields) {
String val = formatValue(row.get(key));
if (StringUtils.isBlank(val)) {
continue;
}
parts.add(fieldLabels.getOrDefault(key, key) + "=" + val);
}
if (parts.isEmpty()) {
for (String key : fieldLabels.keySet()) {
String val = formatValue(row.get(key));
if (StringUtils.isBlank(val)) {
continue;
}
parts.add(fieldLabels.get(key) + "=" + val);
if (parts.size() >= 4) {
break;
}
}
}
return String.join("", parts);
}
private static boolean isRowMetaField(String key) {
return "formulaSpecId".equals(key) || "mixingSpecId".equals(key);
}
private static List<JSONObject> toJsonObjectList(Object listObj) {
if (listObj == null) {
return List.of();
}
JSONArray array = listObj instanceof JSONArray jsonArray ? jsonArray : JSON.parseArray(toJson(listObj));
if (array == null || array.isEmpty()) {
return List.of();
}
List<JSONObject> rows = new ArrayList<>(array.size());
for (int i = 0; i < array.size(); i++) {
Object element = array.get(i);
if (element instanceof JSONObject jsonObject) {
rows.add(jsonObject);
} else if (element != null) {
rows.add(JSON.parseObject(toJson(element)));
}
}
return rows;
}
private static Map<String, Map<String, String>> buildSectionFieldLabels() {
Map<String, Map<String, String>> map = new LinkedHashMap<>();
map.put(SECTION_LINE, buildFormulaLineLabels());
map.put(SECTION_MATERIAL, buildMixingMaterialLabels());
map.put(SECTION_STEP, buildMixingStepLabels());
map.put(SECTION_DOWN_STEP, buildMixingStepLabels());
map.put(SECTION_TCU, buildMixingTcuLabels());
return map;
}
private static Map<String, String[]> buildSectionSummaryFields() {
Map<String, String[]> map = new LinkedHashMap<>();
map.put(SECTION_LINE, new String[] {"mixerMaterialName", "mixerMaterialCode", "phr", "step"});
map.put(SECTION_MATERIAL, new String[] {"mixerMaterialName", "unitWeight", "accumWeight", "seqNo"});
map.put(SECTION_STEP, new String[] {"actionName", "actionSec", "tempC", "speedRpm"});
map.put(SECTION_DOWN_STEP, new String[] {"actionName", "actionSec", "tempC", "speedRpm"});
map.put(SECTION_TCU, new String[] {"sectionType", "frontRotorTemp", "rearRotorTemp", "drugWeighPos"});
return map;
}
private static Map<String, String> buildFormulaLineLabels() {
Map<String, String> map = new LinkedHashMap<>();
map.put("sortNo", "序号");
map.put("phr", "PHR");
map.put("mixerMaterialCode", "物料编码");
map.put("mixerMaterialName", "物料名称");
map.put("materialDesc", "物料描述");
map.put("step", "STEP");
map.put("weighMode", "称量方式");
map.put("weightPercent", "重量%");
map.put("volume", "体积");
map.put("remark", "备注");
for (int i = 1; i <= 7; i++) {
map.put("stage" + i, "混合段" + i);
}
return map;
}
private static Map<String, String> buildMixingMaterialLabels() {
Map<String, String> map = new LinkedHashMap<>();
map.put("sortNo", "序号");
map.put("materialMajor", "物料大类");
map.put("materialMinor", "物料小类");
map.put("materialKind", "种类");
map.put("mixerMaterialName", "物料名称");
map.put("mixerMaterialDesc", "物料描述");
map.put("unitWeight", "单重");
map.put("accumWeight", "累计");
map.put("seqNo", "顺序");
return map;
}
private static Map<String, String> buildMixingStepLabels() {
Map<String, String> map = new LinkedHashMap<>();
map.put("sortNo", "序号");
map.put("actionName", "动作");
map.put("actionSec", "时间(秒)");
map.put("protectSec", "保护时间");
map.put("tempC", "温度(℃)");
map.put("powerKw", "功率(Kw)");
map.put("energyKwh", "能量(Kwh)");
map.put("comboMode", "组合");
map.put("speedRpm", "转速(rpm)");
map.put("pressureMpa", "压力(Mpa)");
map.put("boltPercent", "栓(%)");
return map;
}
private static Map<String, String> buildMixingTcuLabels() {
Map<String, String> map = new LinkedHashMap<>();
map.put("sortNo", "序号");
map.put("sectionType", "区分");
map.put("frontRotorTemp", "前转子温度");
map.put("rearRotorTemp", "后转子温度");
map.put("frontChamberTemp", "前混炼室温度");
map.put("rearChamberTemp", "后混炼室温度");
map.put("topPlugTemp", "上下顶栓温度");
map.put("drugWeighPos", "药品称量位置");
return map;
}
private static JSONObject parseObject(String json) {
if (StringUtils.isBlank(json)) {
return null;
}
return JSON.parseObject(json);
}
private static JSONObject toJsonObject(Object obj) {
if (obj == null) {
return new JSONObject();
}
JSONObject jsonObject = JSON.parseObject(toJson(obj));
for (String ignore : IGNORE_FIELDS) {
jsonObject.remove(ignore);
}
return jsonObject;
}
private static String toJson(Object obj) {
return JSON.toJSONStringWithDateFormat(
obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue);
}
private static String normalizeListJson(Object listObj) {
if (listObj == null) {
return "[]";
}
if (listObj instanceof List<?> list) {
return normalizeListJson(list);
}
return toJson(listObj);
}
private static String normalizeListJson(List<JSONObject> rows) {
if (rows == null || rows.isEmpty()) {
return "[]";
}
List<JSONObject> normalized = new ArrayList<>(rows.size());
for (JSONObject row : rows) {
if (row == null) {
continue;
}
JSONObject copy = new JSONObject(row);
for (String ignore : IGNORE_FIELDS) {
copy.remove(ignore);
}
copy.remove("formulaSpecId");
copy.remove("mixingSpecId");
normalized.add(copy);
}
return toJson(normalized);
}
private static String formatValue(Object value) {
if (value == null) {
return "";
}
if (value instanceof BigDecimal decimal) {
return decimal.stripTrailingZeros().toPlainString();
}
if (value instanceof Date date) {
return toJson(date).replace("\"", "");
}
return String.valueOf(value);
}
private static Map<String, String> buildFormulaMainLabels() {
Map<String, String> map = new LinkedHashMap<>();
map.put("category", "分类");
map.put("specCode", "示方编号");
map.put("rubberCode", "胶料代号");
map.put("rubberMaterialId", "胶料ID");
map.put("basicFormula", "基本配合");
map.put("issueDate", "发行日期");
map.put("purpose", "用途");
map.put("issueNumber", "发行编号");
map.put("mixingStages", "混合段数");
map.put("mixingMachine", "混合机器");
map.put("issueDeptId", "发行部门ID");
map.put("issueDeptName", "发行部门");
map.put("status", "状态");
map.put("aRubberTotalPhr", "A胶合计PHR");
map.put("totalPhr", "总PHR");
map.put("naturalRubber", "天然橡胶");
map.put("syntheticRubber", "合成橡胶");
map.put("totalAmount", "总量");
map.put("weightUnitPrice", "重量单价");
map.put("volumeUnitPrice", "体积单价");
map.put("qRubberSg", "Q胶比重");
map.put("aRubberSg", "A胶比重");
map.put("proofreadBy", "校对人");
map.put("proofreadTime", "校对时间");
map.put("auditBy", "审核人");
map.put("auditTime", "审核时间");
map.put("approveBy", "批准人");
map.put("approveTime", "批准时间");
for (int i = 1; i <= 7; i++) {
map.put("stage" + i + "Total", "混合段" + i + "合计");
}
return map;
}
private static Map<String, String> buildMixingMainLabels() {
Map<String, String> map = new LinkedHashMap<>();
map.put("specName", "规格");
map.put("purpose", "用途");
map.put("machineId", "机台ID");
map.put("machineName", "机台");
map.put("makeDate", "制作日期");
map.put("issueNumber", "发行编号");
map.put("convertFactor", "换算系数");
map.put("fillVolume", "填充体积");
map.put("recycleCarbonSec", "回收炭黑(秒)");
map.put("motherRubberSg", "母胶比重");
map.put("finalRubberSg", "终炼胶比重");
map.put("applyFactory", "适用工厂");
map.put("stageCount", "段数");
map.put("pureMixSec", "纯混炼时间(秒)");
map.put("recycleCarbonKg", "回收炭黑(kg)");
map.put("autoSmallPrintSetting", "自动小票打印设置");
map.put("setTrainCount", "设定车次");
map.put("sideWallWaterTemp", "侧壁水温");
map.put("overtimeDischargeSec", "超时排胶(秒)");
map.put("overtempDischargeSec", "超温排胶(秒)");
map.put("overtempDischargeTemp", "超温排胶温度");
map.put("doorWaterTemp", "门水温");
map.put("rotorWaterTemp", "转子水温");
map.put("maxFeedTemp", "最高投料温度");
map.put("draftBy", "编制人");
map.put("draftTime", "编制时间");
map.put("proofreadBy", "校对人");
map.put("proofreadTime", "校对时间");
map.put("auditBy", "审核人");
map.put("auditTime", "审核时间");
map.put("approveBy", "批准人");
map.put("approveTime", "批准时间");
map.put("changeDate", "变更日期");
return map;
}
public static final String SPEC_TYPE_FORMULA = "formula";
public static final String SPEC_TYPE_MIXING = "mixing";
}

View File

@@ -0,0 +1,63 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecEditLog;
import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecEditLogService;
import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecEditLogDetailVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
/**
* 配方示方修改日志(只读查询)
*/
@Tag(name = "配方日志查询")
@RestController
@RequestMapping("/xslmes/mesXslFormulaSpecEditLog")
@Slf4j
public class MesXslFormulaSpecEditLogController
extends JeecgController<MesXslFormulaSpecEditLog, IMesXslFormulaSpecEditLogService> {
@Operation(summary = "配方日志查询-分页列表")
@RequiresPermissions("xslmes:mes_xsl_formula_spec_edit_log:list")
@GetMapping(value = "/list")
public Result<IPage<MesXslFormulaSpecEditLog>> queryPageList(
MesXslFormulaSpecEditLog entity,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslFormulaSpecEditLog> qw = QueryGenerator.initQueryWrapper(entity, req.getParameterMap());
qw.orderByDesc("modify_time");
Page<MesXslFormulaSpecEditLog> page = new Page<>(pageNo, pageSize);
return Result.OK(service.page(page, qw));
}
@Operation(summary = "配方日志查询-详情(含对比项)")
@RequiresPermissions("xslmes:mes_xsl_formula_spec_edit_log:list")
@GetMapping(value = "/queryById")
public Result<MesXslFormulaSpecEditLogDetailVO> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslFormulaSpecEditLogDetailVO detail = service.getDetail(id);
if (detail == null) {
return Result.error("未找到对应数据");
}
return Result.OK(detail);
}
@RequiresPermissions("xslmes:mes_xsl_formula_spec_edit_log:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslFormulaSpecEditLog entity) {
return super.exportXls(request, entity, MesXslFormulaSpecEditLog.class, "配方日志查询");
}
}

View File

@@ -0,0 +1,79 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 配方示方修改日志(配合示方/混炼示方)
*/
@Data
@TableName("mes_xsl_formula_spec_edit_log")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "配方示方修改日志")
public class MesXslFormulaSpecEditLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@Excel(name = "示方分类", width = 12, dicCode = "xslmes_formula_spec_edit_log_type")
@Dict(dicCode = "xslmes_formula_spec_edit_log_type")
@Schema(description = "示方分类 formula=配合示方 mixing=混炼示方")
private String specType;
@Schema(description = "示方主表ID")
private String specId;
@Excel(name = "示方标识", width = 22)
@Schema(description = "示方标识(胶料代号/规格名)")
private String specTitle;
@Excel(name = "发行编号", width = 16)
@Schema(description = "发行编号")
private String issueNumber;
@Excel(name = "操作类型", width = 10, dicCode = "xslmes_formula_spec_edit_log_action")
@Dict(dicCode = "xslmes_formula_spec_edit_log_action")
@Schema(description = "操作类型 create=新增 update=修改 delete=删除")
private String actionType;
@Excel(name = "修改内容", width = 50)
@Schema(description = "修改内容摘要")
private String changeSummary;
@Schema(description = "变更前快照JSON")
private String beforeSnapshot;
@Schema(description = "变更后快照JSON")
private String afterSnapshot;
@Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "修改时间")
private Date modifyTime;
@Schema(description = "修改人账号")
private String modifyBy;
@Excel(name = "修改人", width = 14)
@Schema(description = "修改人姓名")
private String modifyByName;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,9 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecEditLog;
/**
* 配方示方修改日志
*/
public interface MesXslFormulaSpecEditLogMapper extends BaseMapper<MesXslFormulaSpecEditLog> {}

View File

@@ -0,0 +1,43 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpec;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecEditLog;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecLine;
import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecEditChangeItemVO;
import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecEditLogDetailVO;
import org.jeecg.modules.xslmes.vo.MesXslMixingSpecPage;
/**
* 配方示方修改日志
*/
public interface IMesXslFormulaSpecEditLogService extends IService<MesXslFormulaSpecEditLog> {
String SPEC_TYPE_FORMULA = "formula";
String SPEC_TYPE_MIXING = "mixing";
String ACTION_CREATE = "create";
String ACTION_UPDATE = "update";
String ACTION_DELETE = "delete";
void recordFormulaCreate(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList);
void recordFormulaUpdate(
MesXslFormulaSpec beforeMain,
List<MesXslFormulaSpecLine> beforeLines,
MesXslFormulaSpec afterMain,
List<MesXslFormulaSpecLine> afterLines);
void recordFormulaDelete(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList);
void recordMixingCreate(MesXslMixingSpecPage after);
void recordMixingUpdate(MesXslMixingSpecPage before, MesXslMixingSpecPage after);
void recordMixingDelete(MesXslMixingSpecPage before);
MesXslFormulaSpecEditLogDetailVO getDetail(String id);
List<MesXslFormulaSpecEditChangeItemVO> buildChangeItems(
String specType, String beforeSnapshot, String afterSnapshot);
}

View File

@@ -0,0 +1,256 @@
package org.jeecg.modules.xslmes.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Date;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.xslmes.common.MesXslFormulaSpecEditLogDiffUtil;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpec;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecEditLog;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecLine;
import org.jeecg.modules.xslmes.mapper.MesXslFormulaSpecEditLogMapper;
import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecEditLogService;
import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecEditChangeItemVO;
import org.jeecg.modules.xslmes.vo.MesXslFormulaSpecEditLogDetailVO;
import org.jeecg.modules.xslmes.vo.MesXslMixingSpecPage;
import org.springframework.stereotype.Service;
/**
* 配方示方修改日志
*/
@Service
@Slf4j
public class MesXslFormulaSpecEditLogServiceImpl
extends ServiceImpl<MesXslFormulaSpecEditLogMapper, MesXslFormulaSpecEditLog>
implements IMesXslFormulaSpecEditLogService {
@Override
public void recordFormulaCreate(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList) {
if (main == null || StringUtils.isBlank(main.getId())) {
return;
}
String afterSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildFormulaSnapshotJson(main, lineList);
List<MesXslFormulaSpecEditChangeItemVO> items =
buildChangeItems(SPEC_TYPE_FORMULA, null, afterSnapshot);
saveLog(SPEC_TYPE_FORMULA, main.getId(), resolveFormulaTitle(main), main.getIssueNumber(),
ACTION_CREATE, null, afterSnapshot, items, main.getTenantId());
}
@Override
public void recordFormulaUpdate(
MesXslFormulaSpec beforeMain,
List<MesXslFormulaSpecLine> beforeLines,
MesXslFormulaSpec afterMain,
List<MesXslFormulaSpecLine> afterLines) {
if (afterMain == null || StringUtils.isBlank(afterMain.getId())) {
return;
}
String beforeSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildFormulaSnapshotJson(beforeMain, beforeLines);
String afterSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildFormulaSnapshotJson(afterMain, afterLines);
List<MesXslFormulaSpecEditChangeItemVO> items =
buildChangeItems(SPEC_TYPE_FORMULA, beforeSnapshot, afterSnapshot);
if (items.isEmpty()) {
return;
}
saveLog(
SPEC_TYPE_FORMULA,
afterMain.getId(),
resolveFormulaTitle(afterMain),
afterMain.getIssueNumber(),
ACTION_UPDATE,
beforeSnapshot,
afterSnapshot,
items,
afterMain.getTenantId());
}
@Override
public void recordFormulaDelete(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList) {
if (main == null || StringUtils.isBlank(main.getId())) {
return;
}
String beforeSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildFormulaSnapshotJson(main, lineList);
List<MesXslFormulaSpecEditChangeItemVO> items =
buildChangeItems(SPEC_TYPE_FORMULA, beforeSnapshot, null);
saveLog(
SPEC_TYPE_FORMULA,
main.getId(),
resolveFormulaTitle(main),
main.getIssueNumber(),
ACTION_DELETE,
beforeSnapshot,
null,
items,
main.getTenantId());
}
@Override
public void recordMixingCreate(MesXslMixingSpecPage after) {
if (after == null || StringUtils.isBlank(after.getId())) {
return;
}
String afterSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildMixingSnapshotJson(after);
List<MesXslFormulaSpecEditChangeItemVO> items =
buildChangeItems(SPEC_TYPE_MIXING, null, afterSnapshot);
saveLog(
SPEC_TYPE_MIXING,
after.getId(),
resolveMixingTitle(after),
after.getIssueNumber(),
ACTION_CREATE,
null,
afterSnapshot,
items,
after.getTenantId());
}
@Override
public void recordMixingUpdate(MesXslMixingSpecPage before, MesXslMixingSpecPage after) {
if (after == null || StringUtils.isBlank(after.getId())) {
return;
}
String beforeSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildMixingSnapshotJson(before);
String afterSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildMixingSnapshotJson(after);
List<MesXslFormulaSpecEditChangeItemVO> items =
buildChangeItems(SPEC_TYPE_MIXING, beforeSnapshot, afterSnapshot);
if (items.isEmpty()) {
return;
}
saveLog(
SPEC_TYPE_MIXING,
after.getId(),
resolveMixingTitle(after),
after.getIssueNumber(),
ACTION_UPDATE,
beforeSnapshot,
afterSnapshot,
items,
after.getTenantId());
}
@Override
public void recordMixingDelete(MesXslMixingSpecPage before) {
if (before == null || StringUtils.isBlank(before.getId())) {
return;
}
String beforeSnapshot = MesXslFormulaSpecEditLogDiffUtil.buildMixingSnapshotJson(before);
List<MesXslFormulaSpecEditChangeItemVO> items =
buildChangeItems(SPEC_TYPE_MIXING, beforeSnapshot, null);
saveLog(
SPEC_TYPE_MIXING,
before.getId(),
resolveMixingTitle(before),
before.getIssueNumber(),
ACTION_DELETE,
beforeSnapshot,
null,
items,
before.getTenantId());
}
@Override
public MesXslFormulaSpecEditLogDetailVO getDetail(String id) {
MesXslFormulaSpecEditLog row = getById(id);
if (row == null) {
return null;
}
MesXslFormulaSpecEditLogDetailVO detail = new MesXslFormulaSpecEditLogDetailVO();
detail.setId(row.getId());
detail.setSpecType(row.getSpecType());
detail.setSpecId(row.getSpecId());
detail.setSpecTitle(row.getSpecTitle());
detail.setIssueNumber(row.getIssueNumber());
detail.setActionType(row.getActionType());
detail.setChangeSummary(row.getChangeSummary());
detail.setBeforeSnapshot(row.getBeforeSnapshot());
detail.setAfterSnapshot(row.getAfterSnapshot());
detail.setModifyTime(row.getModifyTime());
detail.setModifyBy(row.getModifyBy());
detail.setModifyByName(row.getModifyByName());
detail.setTenantId(row.getTenantId());
detail.setBeforeData(parseSnapshot(row.getBeforeSnapshot()));
detail.setAfterData(parseSnapshot(row.getAfterSnapshot()));
detail.setChangeItems(buildChangeItems(row.getSpecType(), row.getBeforeSnapshot(), row.getAfterSnapshot()));
return detail;
}
@Override
public List<MesXslFormulaSpecEditChangeItemVO> buildChangeItems(
String specType, String beforeSnapshot, String afterSnapshot) {
return MesXslFormulaSpecEditLogDiffUtil.compare(specType, beforeSnapshot, afterSnapshot);
}
private void saveLog(
String specType,
String specId,
String specTitle,
String issueNumber,
String actionType,
String beforeSnapshot,
String afterSnapshot,
List<MesXslFormulaSpecEditChangeItemVO> items,
Integer tenantId) {
LoginUser loginUser = resolveLoginUser();
MesXslFormulaSpecEditLog row = new MesXslFormulaSpecEditLog();
row.setSpecType(specType);
row.setSpecId(specId);
row.setSpecTitle(specTitle);
row.setIssueNumber(issueNumber);
row.setActionType(actionType);
row.setChangeSummary(MesXslFormulaSpecEditLogDiffUtil.buildSummary(actionType, items));
row.setBeforeSnapshot(beforeSnapshot);
row.setAfterSnapshot(afterSnapshot);
row.setModifyTime(new Date());
if (loginUser != null) {
row.setModifyBy(loginUser.getUsername());
row.setModifyByName(StringUtils.defaultIfBlank(loginUser.getRealname(), loginUser.getUsername()));
} else {
row.setModifyByName("未知");
}
row.setTenantId(tenantId);
save(row);
}
private static Object parseSnapshot(String snapshot) {
if (StringUtils.isBlank(snapshot)) {
return null;
}
return JSON.parse(snapshot);
}
private static String resolveFormulaTitle(MesXslFormulaSpec main) {
if (main == null) {
return null;
}
if (StringUtils.isNotBlank(main.getRubberCode())) {
return main.getRubberCode();
}
if (StringUtils.isNotBlank(main.getSpecCode())) {
return main.getSpecCode();
}
return main.getIssueNumber();
}
private static String resolveMixingTitle(MesXslMixingSpecPage page) {
if (page == null) {
return null;
}
return StringUtils.defaultIfBlank(page.getSpecName(), page.getIssueNumber());
}
private static LoginUser resolveLoginUser() {
try {
Object principal = SecurityUtils.getSubject().getPrincipal();
if (principal instanceof LoginUser loginUser) {
return loginUser;
}
} catch (Exception ignored) {
// 免密或未登录场景
}
return null;
}
}

View File

@@ -37,6 +37,7 @@ 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.IMesXslEquipmentLedgerService;
import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecEditLogService;
import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecService;
import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecSettingService;
import org.jeecg.modules.xslmes.service.IMesXslMixerMaterialKindCfgService;
@@ -95,6 +96,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
@Resource
private IMesXslMixerMaterialKindCfgService mesXslMixerMaterialKindCfgService;
@Resource
private IMesXslFormulaSpecEditLogService mesXslFormulaSpecEditLogService;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMain(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList) {
@@ -105,21 +109,43 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
this.save(main);
insertLines(main, lineList);
refreshMainSummary(main.getId());
//update-begin---author:cursor ---date:20260526 for【配方日志查询】配合示方新增落库修改日志-----------
MesXslFormulaSpec saved = getByIdWithLines(main.getId());
if (saved != null) {
mesXslFormulaSpecEditLogService.recordFormulaCreate(saved, saved.getLineList());
}
//update-end---author:cursor ---date:20260526 for【配方日志查询】配合示方新增落库修改日志-----------
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateMain(MesXslFormulaSpec main, List<MesXslFormulaSpecLine> lineList) {
//update-begin---author:cursor ---date:20260526 for【配方日志查询】配合示方编辑前抓取快照-----------
MesXslFormulaSpec before = getByIdWithLines(main.getId());
//update-end---author:cursor ---date:20260526 for【配方日志查询】配合示方编辑前抓取快照-----------
fillMainDefaults(main);
this.updateById(main);
lineMapper.delete(new LambdaQueryWrapper<MesXslFormulaSpecLine>().eq(MesXslFormulaSpecLine::getFormulaSpecId, main.getId()));
insertLines(main, lineList);
refreshMainSummary(main.getId());
//update-begin---author:cursor ---date:20260526 for【配方日志查询】配合示方编辑落库修改日志-----------
MesXslFormulaSpec after = getByIdWithLines(main.getId());
if (after != null) {
mesXslFormulaSpecEditLogService.recordFormulaUpdate(
before, before == null ? null : before.getLineList(), after, after.getLineList());
}
//update-end---author:cursor ---date:20260526 for【配方日志查询】配合示方编辑落库修改日志-----------
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delMain(String id) {
//update-begin---author:cursor ---date:20260526 for【配方日志查询】配合示方删除落库修改日志-----------
MesXslFormulaSpec before = getByIdWithLines(id);
if (before != null) {
mesXslFormulaSpecEditLogService.recordFormulaDelete(before, before.getLineList());
}
//update-end---author:cursor ---date:20260526 for【配方日志查询】配合示方删除落库修改日志-----------
lineMapper.delete(new LambdaQueryWrapper<MesXslFormulaSpecLine>().eq(MesXslFormulaSpecLine::getFormulaSpecId, id));
this.removeById(id);
}

View File

@@ -38,6 +38,7 @@ import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecMapper;
import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecMaterialMapper;
import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecStepMapper;
import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecTcuMapper;
import org.jeecg.modules.xslmes.service.IMesXslFormulaSpecEditLogService;
import org.jeecg.modules.xslmes.service.IMesXslMixingSpecService;
import org.jeecg.modules.xslmes.vo.MesXslMixingSpecPage;
import org.springframework.stereotype.Service;
@@ -74,6 +75,9 @@ public class MesXslMixingSpecServiceImpl extends ServiceImpl<MesXslMixingSpecMap
@Resource
private ISysCategoryService sysCategoryService;
@Resource
private IMesXslFormulaSpecEditLogService mesXslFormulaSpecEditLogService;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMain(
@@ -93,6 +97,12 @@ public class MesXslMixingSpecServiceImpl extends ServiceImpl<MesXslMixingSpecMap
trace.step("saveMain", "mainId", main.getId());
saveChildren(main.getId(), materialList, stepList, downStepList, tcuList, trace);
trace.finish();
//update-begin---author:cursor ---date:20260526 for【配方日志查询】混炼示方新增落库修改日志-----------
MesXslMixingSpecPage saved = queryPageById(main.getId());
if (saved != null) {
mesXslFormulaSpecEditLogService.recordMixingCreate(saved);
}
//update-end---author:cursor ---date:20260526 for【配方日志查询】混炼示方新增落库修改日志-----------
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】混炼示方主子表新增保存-----------
}
@@ -109,6 +119,9 @@ public class MesXslMixingSpecServiceImpl extends ServiceImpl<MesXslMixingSpecMap
trace.logPayloadSize(materialList, stepList, downStepList, tcuList);
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A47】混炼示方保存分步骤性能日志-----------
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】混炼示方主子表编辑保存-----------
//update-begin---author:cursor ---date:20260526 for【配方日志查询】混炼示方编辑前抓取快照-----------
MesXslMixingSpecPage before = queryPageById(main.getId());
//update-end---author:cursor ---date:20260526 for【配方日志查询】混炼示方编辑前抓取快照-----------
normalizeMain(main);
trace.step("normalizeMain");
this.updateById(main);
@@ -116,6 +129,12 @@ public class MesXslMixingSpecServiceImpl extends ServiceImpl<MesXslMixingSpecMap
clearChildren(main.getId(), trace);
saveChildren(main.getId(), materialList, stepList, downStepList, tcuList, trace);
trace.finish();
//update-begin---author:cursor ---date:20260526 for【配方日志查询】混炼示方编辑落库修改日志-----------
MesXslMixingSpecPage after = queryPageById(main.getId());
if (after != null) {
mesXslFormulaSpecEditLogService.recordMixingUpdate(before, after);
}
//update-end---author:cursor ---date:20260526 for【配方日志查询】混炼示方编辑落库修改日志-----------
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】混炼示方主子表编辑保存-----------
}
@@ -150,6 +169,14 @@ public class MesXslMixingSpecServiceImpl extends ServiceImpl<MesXslMixingSpecMap
if (CollectionUtils.isEmpty(mains)) {
return;
}
//update-begin---author:cursor ---date:20260526 for【配方日志查询】混炼示方删除落库修改日志-----------
for (String id : ids) {
MesXslMixingSpecPage before = queryPageById(id);
if (before != null) {
mesXslFormulaSpecEditLogService.recordMixingDelete(before);
}
}
//update-end---author:cursor ---date:20260526 for【配方日志查询】混炼示方删除落库修改日志-----------
clearChildrenBatch(ids);
this.removeByIds(ids);
Set<String> specNames = new LinkedHashSet<>();

View File

@@ -0,0 +1,30 @@
package org.jeecg.modules.xslmes.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 配方日志字段级对比项
*/
@Data
@Schema(description = "配方日志对比项")
public class MesXslFormulaSpecEditChangeItemVO {
@Schema(description = "所属区块 main/line/material/step/downStep/tcu")
private String section;
@Schema(description = "区块中文名")
private String sectionLabel;
@Schema(description = "字段键")
private String fieldKey;
@Schema(description = "字段中文名")
private String fieldLabel;
@Schema(description = "变更前值")
private String beforeValue;
@Schema(description = "变更后值")
private String afterValue;
}

View File

@@ -0,0 +1,25 @@
package org.jeecg.modules.xslmes.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jeecg.modules.xslmes.entity.MesXslFormulaSpecEditLog;
/**
* 配方日志详情(含对比项)
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "配方日志详情")
public class MesXslFormulaSpecEditLogDetailVO extends MesXslFormulaSpecEditLog {
@Schema(description = "变更前快照对象")
private Object beforeData;
@Schema(description = "变更后快照对象")
private Object afterData;
@Schema(description = "字段级对比项")
private List<MesXslFormulaSpecEditChangeItemVO> changeItems;
}