diff --git a/src/main/java/com/spring/modules/part/controller/PartInformationController.java b/src/main/java/com/spring/modules/part/controller/PartInformationController.java index 5b982d40..a5dbe5a5 100644 --- a/src/main/java/com/spring/modules/part/controller/PartInformationController.java +++ b/src/main/java/com/spring/modules/part/controller/PartInformationController.java @@ -842,4 +842,20 @@ public class PartInformationController { partInformationService.deleteProjectPart(data); return R.ok(); } + + /** + * 查询物料关键字段(std_order_qty / estimated_material_cost)变更日志 + * + * @param site 工厂(必填) + * @param partNo 物料编码(必填) + * @param fieldName 字段名,可选:std_order_qty / estimated_material_cost;不传则查全部 + */ + @GetMapping("fieldChangeLog") + @ResponseBody + public R fieldChangeLog( + @RequestParam String site, + @RequestParam String partNo, + @RequestParam(required = false, defaultValue = "") String fieldName) { + return R.ok().put("rows", partInformationService.queryFieldChangeLog(site, partNo, fieldName)); + } } diff --git a/src/main/java/com/spring/modules/part/entity/PartFieldChangeLogEntity.java b/src/main/java/com/spring/modules/part/entity/PartFieldChangeLogEntity.java new file mode 100644 index 00000000..6aea53fd --- /dev/null +++ b/src/main/java/com/spring/modules/part/entity/PartFieldChangeLogEntity.java @@ -0,0 +1,55 @@ +package com.spring.modules.part.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 lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 物料关键字段变更日志 + * 追踪 std_order_qty 和 estimated_material_cost 的每次变更 + */ +@Data +@TableName("part_field_change_log") +public class PartFieldChangeLogEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + private Long id; + + /** 工厂 */ + private String site; + + /** 物料编码 */ + private String partNo; + + /** 变更字段名:std_order_qty 或 estimated_material_cost */ + private String fieldName; + + /** 变更前的值 */ + private BigDecimal oldValue; + + /** 变更后的值 */ + private BigDecimal newValue; + + /** 变更时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date changeTime; + + /** 数据库连接账号(触发器记录,可辨别是否来自存储过程/应用) */ + private String dbUser; + + /** 连接来源程序名(如 Microsoft JDBC Driver for SQL Server) */ + private String appName; + + /** 发起变更的主机名 */ + private String hostName; + + /** 备注(Java 层补充写入操作人、操作类型等) */ + private String remark; +} diff --git a/src/main/java/com/spring/modules/part/mapper/PartFieldChangeLogMapper.java b/src/main/java/com/spring/modules/part/mapper/PartFieldChangeLogMapper.java new file mode 100644 index 00000000..51755cb7 --- /dev/null +++ b/src/main/java/com/spring/modules/part/mapper/PartFieldChangeLogMapper.java @@ -0,0 +1,30 @@ +package com.spring.modules.part.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.spring.modules.part.entity.PartFieldChangeLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface PartFieldChangeLogMapper extends BaseMapper { + + /** + * 查询指定物料的字段变更记录 + */ + List queryChangeLog( + @Param("site") String site, + @Param("partNo") String partNo, + @Param("fieldName") String fieldName); + + /** + * 更新最近一条日志的 db_user(PLM 操作人)和 remark + */ + void updateLastLogUser( + @Param("site") String site, + @Param("partNo") String partNo, + @Param("fieldName") String fieldName, + @Param("operator") String operator, + @Param("remark") String remark); +} diff --git a/src/main/java/com/spring/modules/part/service/PartInformationService.java b/src/main/java/com/spring/modules/part/service/PartInformationService.java index 1b5e13c4..697f7f5f 100644 --- a/src/main/java/com/spring/modules/part/service/PartInformationService.java +++ b/src/main/java/com/spring/modules/part/service/PartInformationService.java @@ -173,4 +173,12 @@ public interface PartInformationService { PageUtils readPartFromFile(MultipartFile file, GetParamInData data, String searchType, String partNos); void copyPart2(PartInformationVo data); + + /** + * 查询物料关键字段变更日志(std_order_qty / estimated_material_cost) + * @param site 工厂 + * @param partNo 物料编码 + * @param fieldName 字段名,传空字符串则查两个字段 + */ + List queryFieldChangeLog(String site, String partNo, String fieldName); } diff --git a/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java b/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java index 7bbd8896..fc8aaa94 100644 --- a/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java +++ b/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java @@ -187,6 +187,9 @@ public class PartInformationServiceImpl extends ServiceImpl queryFieldChangeLog(String site, String partNo, String fieldName) { + return partFieldChangeLogMapper.queryChangeLog(site, partNo, fieldName); + } + + /** + * 触发器写入日志后,立即回填 PLM 操作人到 db_user,并写入 remark + * db_user 格式:"{username}|PLM|"(加标记方便与 DB 账号区分) + * 使用 try-catch 保证不影响主流程 + */ + private void recordChangeRemark(String site, String partNo, String operator, String operationType) { + try { + String user = (operator == null ? "unknown" : operator); + String dbUser = user + "|PLM|"; + String remark = operationType; + partFieldChangeLogMapper.updateLastLogUser(site, partNo, "std_order_qty", dbUser, remark); + partFieldChangeLogMapper.updateLastLogUser(site, partNo, "estimated_material_cost", dbUser, remark); + } catch (Exception e) { + log.warn("recordChangeRemark 写入失败,site={}, partNo={}, msg={}", site, partNo, e.getMessage()); + } + } + } diff --git a/src/main/resources/mapper/part/PartFieldChangeLogMapper.xml b/src/main/resources/mapper/part/PartFieldChangeLogMapper.xml new file mode 100644 index 00000000..abbb48c4 --- /dev/null +++ b/src/main/resources/mapper/part/PartFieldChangeLogMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + UPDATE part_field_change_log + SET db_user = #{operator}, + remark = #{remark} + WHERE id = ( + SELECT TOP 1 id + FROM part_field_change_log + WHERE site = #{site} + AND part_no = #{partNo} + AND field_name = #{fieldName} + AND db_user NOT LIKE '%|PLM|%' + ORDER BY change_time DESC + ) + + +