新增配方日志查询功能,记录配方和混炼示方的创建、更新与删除操作,增强数据追溯能力。
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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, "配方日志查询");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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> {}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user