Browse Source

创建sys_diff_log:数据修改记录日志表作为通用模块的修改记录的存储

新增数据修改记录日志Mapper
新增数据修改记录日志Mapper.XML
新增数据修改记录日志Service接口
新增数据修改记录日志ServiceImpl实现类
新增 通用模块BusinessKeysConstants 修改数据记录日志业务模块常量类,用于记录业务模块数据,方便程序的维护,同时也能提高可读性
新增 系统模块 SysFieldDifferent  字段差异实体类,用于记录修改的字段名称,修改前值,修改后值,方便后续使用

新增自定义注解类:FieldCompare,采用和excel导出一样的模式,增加@FieldCompare注解,后续只需要在对应实体类上的成员变量增加@FieldCompare(chinesename="")就可使用
新增 通用模块字段对比工具类FieldCompareUtil,新增compare字段对比方法,采用反射的思想,自动获取带有FieldCompare注解的成员变量,然后对比拥有该注解的实体类,新值和旧的值进行对比,把相同实体类的成员变量修改前和修改后不同的值采用 [{fieldName,before,after},{},{}]的形式进行存储
新增 SysDiffLogVo 修改记录Vo类,用于前端列表展示修改的字段、修改前的值、修改后的值、修改时间、修改人
新增 数据修改记录日志Controller,用于后续统一处理所有模块的修改记录的展示,只需要传递相同且必要的值,就可使用,减少重复性代码
自定义常量BusinessKeysConstants类:新增 产品型号管理作为测试数据
SysFieldDifferent 字段差异实体类 新增 包含(fieldName、before、after)有参构造构造方法和无参构造方法,修改toString方法去掉 {}外面的SysFieldDifferent,用于存储[{fieldName,before,after},{},{}]这种形式,方便后面进行json数据的反序列化

前端新增修改记录通用列表展示页面diffLog.html,按照万材要求展示:修改字段、修改前的值、修改后的值、修改人、上次修改时间

SysDiffLogController层新增查询数据修改记录日志列表后端接口、新增打开数据修改记录前端页面后端接口

ISysDiffLogService层新增diff_data 把 数据通过JSON 序列化和反序列化 后端方法parseDiffData();新增 展示数据修改记录日志后端方法getDiffLogList()
SysDiffLogMapper层新增查询数据修改记录日志列表 后端方法selectSysDiffLogByBusiness()
SysDiffLogServiceImpl层新增 解析单个条目后端方法parseSingleEntry()
前端通用模块ry-ui.js新增双击某格触发的事件前端方法
测试通用修改记录日志:
SysProductModel实体类成员变量上加入@FieldCompare()注解
SysProductModelController层新增打开日志记录前端页面的后端接口,新增展示产品型号管理日志记录后端接口
修改SysProductModelServiceImpl新增产品型号管理后端方法:新增的同时新增一条修改记录日志数据;修改 修改操作方法,修改产品型号管理数据的同时:根据产品型号管理的唯一属性关联修改记录日志表,按照规定的格式里面存入修改的字段、修改前的值、修改后的值、修改时间、修改人数据
修改产品型号管理前端列表页面新增 onDblClickCell方法:按照万材要求:只有双击修改时间字段才会触发该事件,打开修改记录数据
去掉SysProductModelController层的新增有关修改记录日志的方法:提高通用性,把方法集中放在SysDiffLogController中;
修改 SysDiffLogController层的getDiffDataList方法,新增businessKey参数,提高通用性;
修改 onDblClickCell方法,现在只需要按照通用格式从前端传入businessId、businessKey参数就可全局通用
dev
liuxiaoxu 1 month ago
parent
commit
c0b67b2d5c
  1. 60
      ruoyi-admin/src/main/java/com/ruoyi/system/controller/SysDiffLogController.java
  2. 2
      ruoyi-admin/src/main/java/com/ruoyi/system/controller/SysProductModelController.java
  3. 84
      ruoyi-admin/src/main/java/com/ruoyi/system/domain/SysDiffLog.java
  4. 6
      ruoyi-admin/src/main/java/com/ruoyi/system/domain/SysProductModel.java
  5. 35
      ruoyi-admin/src/main/java/com/ruoyi/system/domain/Vo/SysDiffLogVo.java
  6. 85
      ruoyi-admin/src/main/java/com/ruoyi/system/mapper/SysDiffLogMapper.java
  7. 104
      ruoyi-admin/src/main/java/com/ruoyi/system/service/ISysDiffLogService.java
  8. 2
      ruoyi-admin/src/main/java/com/ruoyi/system/service/ISysProductModelService.java
  9. 272
      ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/SysDiffLogServiceImpl.java
  10. 38
      ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/SysProductModelServiceImpl.java
  11. 100
      ruoyi-admin/src/main/resources/mapper/system/SysDiffLogMapper.xml
  12. 59
      ruoyi-admin/src/main/resources/templates/system/diffLog/diffLog.html
  13. 9
      ruoyi-admin/src/main/resources/templates/system/model/model.html
  14. 25
      ruoyi-common/src/main/java/com/ruoyi/common/annotation/FieldCompare.java
  15. 15
      ruoyi-common/src/main/java/com/ruoyi/common/constant/BusinessKeysConstants.java
  16. 62
      ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysFieldDifferent.java
  17. 92
      ruoyi-common/src/main/java/com/ruoyi/common/utils/FieldCompareUtil.java

60
ruoyi-admin/src/main/java/com/ruoyi/system/controller/SysDiffLogController.java

@ -0,0 +1,60 @@
package com.ruoyi.system.controller;
import java.util.List;
import com.ruoyi.system.domain.Vo.SysDiffLogVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysDiffLog;
import com.ruoyi.system.service.ISysDiffLogService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 数据修改记录日志Controller
*
* @author 刘晓旭
* @date 2024-10-15
*/
@Controller
@RequestMapping("/system/diffLog")
public class SysDiffLogController extends BaseController
{
private String prefix = "system/diffLog";
@Autowired
private ISysDiffLogService sysDiffLogService;
/**
* 查询数据修改记录日志列表
*/
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(
@RequestParam Long businessId,
@RequestParam String businessKey
) {
startPage();
List<SysDiffLogVo> list = sysDiffLogService.getDiffLogList(businessId,businessKey);
return getDataTable(list);
}
/**
* 打开数据修改记录前端页面
* */
@GetMapping("/getDiffDataList/{businessId}/{businessKey}")
public String getDiffDataList(@PathVariable Long businessId, @PathVariable String businessKey,ModelMap mmap){
mmap.put("businessId", businessId);
mmap.put("businessKey", businessKey);
return prefix + "/diffLog";
}
}

2
ruoyi-admin/src/main/java/com/ruoyi/system/controller/SysProductModelController.java

@ -3,6 +3,7 @@ package com.ruoyi.system.controller;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysFieldDifferent;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
@ -206,4 +207,5 @@ public class SysProductModelController extends BaseController
} }

84
ruoyi-admin/src/main/java/com/ruoyi/system/domain/SysDiffLog.java

@ -0,0 +1,84 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 数据修改记录日志对象 sys_diff_log
*
* @author 刘晓旭
* @date 2024-10-15
*/
public class SysDiffLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 日志主键 */
private Long diffId;
/** 业务id */
@Excel(name = "业务id")
private Long businessId;
/** 业务名称 */
@Excel(name = "业务名称")
private String businessKey;
/** 业务更改数据 */
@Excel(name = "业务更改数据")
private String diffData;
public void setDiffId(Long diffId)
{
this.diffId = diffId;
}
public Long getDiffId()
{
return diffId;
}
public Long getBusinessId() {
return businessId;
}
public void setBusinessId(Long businessId) {
this.businessId = businessId;
}
public void setBusinessKey(String businessKey)
{
this.businessKey = businessKey;
}
public String getBusinessKey()
{
return businessKey;
}
public void setDiffData(String diffData)
{
this.diffData = diffData;
}
public String getDiffData()
{
return diffData;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("diffId", getDiffId())
.append("businessId", getBusinessId())
.append("businessKey", getBusinessKey())
.append("diffData", getDiffData())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

6
ruoyi-admin/src/main/java/com/ruoyi/system/domain/SysProductModel.java

@ -3,6 +3,7 @@ package com.ruoyi.system.domain;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.FieldCompare;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -31,21 +32,26 @@ public class SysProductModel extends BaseEntity
private String engineer; private String engineer;
/** 设备型号 */ /** 设备型号 */
@FieldCompare(chineseName = "设备型号")
@Excel(name = "设备型号") @Excel(name = "设备型号")
private String equipModel; private String equipModel;
@FieldCompare(chineseName = "设备名称")
/** 设备名称 */ /** 设备名称 */
@Excel(name = "设备名称") @Excel(name = "设备名称")
private String equipName; private String equipName;
@FieldCompare(chineseName = "规格说明")
/** 规格说明 */ /** 规格说明 */
@Excel(name = "规格说明") @Excel(name = "规格说明")
private String specification; private String specification;
@FieldCompare(chineseName = "差异说明")
/** 差异说明 */ /** 差异说明 */
@Excel(name = "差异说明") @Excel(name = "差异说明")
private String differences; private String differences;
@FieldCompare(chineseName = "备注")
/** 备注 */ /** 备注 */
@Excel(name = "备注") @Excel(name = "备注")
private String remark; private String remark;

35
ruoyi-admin/src/main/java/com/ruoyi/system/domain/Vo/SysDiffLogVo.java

@ -0,0 +1,35 @@
package com.ruoyi.system.domain.Vo;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import java.util.Date;
/**
* 用于展示修改记录日志
*
* @author 刘晓旭
* @date 2024-10-16
*/
@Data
public class SysDiffLogVo{
//修改的字段
private String fieldName;
//修改前
private String before;
//修改后
private String after;
//修改的时间
private Date updateTime;
//修改的人
private String updateBy;
}

85
ruoyi-admin/src/main/java/com/ruoyi/system/mapper/SysDiffLogMapper.java

@ -0,0 +1,85 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.SysDiffLog;
/**
* 数据修改记录日志Mapper接口
*
* @author 刘晓旭
* @date 2024-10-15
*/
public interface SysDiffLogMapper
{
/**
* 查询数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 数据修改记录日志
*/
public SysDiffLog selectSysDiffLogById(Long diffId);
/**
* 查询数据修改记录日志列表
*
* @param sysDiffLog 数据修改记录日志
* @return 数据修改记录日志集合
*/
public List<SysDiffLog> selectSysDiffLogList(SysDiffLog sysDiffLog);
/**
* 查询数据修改记录日志列表
*
* @param sysDiffLog 数据修改记录日志
* @return 数据修改记录日志集合
*/
public SysDiffLog selectSysDiffLogByBusiness(SysDiffLog sysDiffLog);
/**
* 新增数据修改记录日志
*
* @param sysDiffLog 数据修改记录日志
* @return 结果
*/
public int insertSysDiffLog(SysDiffLog sysDiffLog);
/**
* 修改数据修改记录日志
*
* @param sysDiffLog 数据修改记录日志
* @return 结果
*/
public int updateSysDiffLog(SysDiffLog sysDiffLog);
/**
* 删除数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
public int deleteSysDiffLogById(Long diffId);
/**
* 批量删除数据修改记录日志
*
* @param diffIds 需要删除的数据ID
* @return 结果
*/
public int deleteSysDiffLogByIds(String[] diffIds);
/**
* 作废数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
public int cancelSysDiffLogById(Long diffId);
/**
* 恢复数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
public int restoreSysDiffLogById(Long diffId);
}

104
ruoyi-admin/src/main/java/com/ruoyi/system/service/ISysDiffLogService.java

@ -0,0 +1,104 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysFieldDifferent;
import com.ruoyi.system.domain.SysDiffLog;
import com.ruoyi.system.domain.Vo.SysDiffLogVo;
/**
* 数据修改记录日志Service接口
*
* @author 刘晓旭
* @date 2024-10-15
*/
public interface ISysDiffLogService
{
/**
* 查询数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 数据修改记录日志
*/
public SysDiffLog selectSysDiffLogById(Long diffId);
/**
* 查询数据修改记录日志列表
*
* @param sysDiffLog 数据修改记录日志
* @return 数据修改记录日志集合
*/
public List<SysDiffLog> selectSysDiffLogList(SysDiffLog sysDiffLog);
/**
* 查询数据修改记录日志列表
*
* @param sysDiffLog 数据修改记录日志
* @return 数据修改记录日志集合
*/
public SysDiffLog selectSysDiffLogByBusiness(SysDiffLog sysDiffLog);
/**
* 新增数据修改记录日志
*
* @param sysDiffLog 数据修改记录日志
* @return 结果
*/
public int insertSysDiffLog(SysDiffLog sysDiffLog);
/**
* 修改数据修改记录日志
*
* @param sysDiffLog 数据修改记录日志
* @return 结果
*/
public int updateSysDiffLog(SysDiffLog sysDiffLog);
/**
* 修改数据修改记录日志通过其他模块
*
*/
public int updateSysDiffLogByBusiness(Long businessId, String businessKey, List<SysFieldDifferent> changes);
/**
* 批量删除数据修改记录日志
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteSysDiffLogByIds(String ids);
/**
* 删除数据修改记录日志信息
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
public int deleteSysDiffLogById(Long diffId);
/**
* 作废数据修改记录日志
* @param diffId 数据修改记录日志ID
* @return
*/
int cancelSysDiffLogById(Long diffId);
/**
* 恢复数据修改记录日志
* @param diffId 数据修改记录日志ID
* @return
*/
int restoreSysDiffLogById(Long diffId);
/**
* diff_data 数据通过JSON 序列化和反序列化
* */
public List<SysFieldDifferent> parseDiffData(String diffData);
/**
* 展示数据修改记录日志
* */
List<SysDiffLogVo> getDiffLogList(Long businessId,String businessKey);
}

2
ruoyi-admin/src/main/java/com/ruoyi/system/service/ISysProductModelService.java

@ -1,5 +1,6 @@
package com.ruoyi.system.service; package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysFieldDifferent;
import com.ruoyi.system.domain.SysProductModel; import com.ruoyi.system.domain.SysProductModel;
import java.util.List; import java.util.List;
@ -83,4 +84,5 @@ public interface ISysProductModelService
* 根据产品型号id数组查询产品型号列表集合 * 根据产品型号id数组查询产品型号列表集合
* */ * */
List<SysProductModel> selectSysProductModelListByCodes(String[] pcodes); List<SysProductModel> selectSysProductModelListByCodes(String[] pcodes);
} }

272
ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/SysDiffLogServiceImpl.java

@ -0,0 +1,272 @@
package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ruoyi.common.constant.BusinessKeysConstants;
import com.ruoyi.common.core.domain.entity.SysFieldDifferent;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.domain.Vo.SysDiffLogVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysDiffLogMapper;
import com.ruoyi.system.domain.SysDiffLog;
import com.ruoyi.system.service.ISysDiffLogService;
import com.ruoyi.common.core.text.Convert;
/**
* 数据修改记录日志Service业务层处理
*
* @author 刘晓旭
* @date 2024-10-15
*/
@Service
public class SysDiffLogServiceImpl implements ISysDiffLogService
{
@Autowired
private SysDiffLogMapper sysDiffLogMapper;
/**
* 查询数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 数据修改记录日志
*/
@Override
public SysDiffLog selectSysDiffLogById(Long diffId)
{
return sysDiffLogMapper.selectSysDiffLogById(diffId);
}
/**
* 查询数据修改记录日志列表
*
* @param sysDiffLog 数据修改记录日志
* @return 数据修改记录日志
*/
@Override
public List<SysDiffLog> selectSysDiffLogList(SysDiffLog sysDiffLog)
{
return sysDiffLogMapper.selectSysDiffLogList(sysDiffLog);
}
/**
* 查询数据修改记录日志列表
*
* @param sysDiffLog 数据修改记录日志
* @return 数据修改记录日志集合
*/
@Override
public SysDiffLog selectSysDiffLogByBusiness(SysDiffLog sysDiffLog){
return sysDiffLogMapper.selectSysDiffLogByBusiness(sysDiffLog);
}
/**
* 新增数据修改记录日志
*
* @param sysDiffLog 数据修改记录日志
* @return 结果
*/
@Override
public int insertSysDiffLog(SysDiffLog sysDiffLog)
{
String loginName = ShiroUtils.getLoginName();
sysDiffLog.setCreateBy(loginName);
sysDiffLog.setCreateTime(DateUtils.getNowDate());
return sysDiffLogMapper.insertSysDiffLog(sysDiffLog);
}
/**
* 修改数据修改记录日志
*
* @param sysDiffLog 数据修改记录日志
* @return 结果
*/
@Override
public int updateSysDiffLog(SysDiffLog sysDiffLog)
{
String loginName = ShiroUtils.getLoginName();
sysDiffLog.setUpdateBy(loginName);
sysDiffLog.setUpdateTime(DateUtils.getNowDate());
return sysDiffLogMapper.updateSysDiffLog(sysDiffLog);
}
/**
* 修改数据修改记录日志
*
* @param businessId 业务ID
* @param businessKey 业务键
* @param changes 字段变化列表
* @return 更新行数
*/
@Override
public int updateSysDiffLogByBusiness(Long businessId, String businessKey, List<SysFieldDifferent> changes) {
SysDiffLog sysDiffLog = new SysDiffLog();
sysDiffLog.setBusinessId(businessId);
sysDiffLog.setBusinessKey(businessKey);
SysDiffLog existingLog = sysDiffLogMapper.selectSysDiffLogByBusiness(sysDiffLog);
if (existingLog != null) {
existingLog.setDiffData(changesToString(changes));
existingLog.setUpdateBy(ShiroUtils.getLoginName());
existingLog.setUpdateTime(DateUtils.getNowDate());
return sysDiffLogMapper.updateSysDiffLog(existingLog);
} else {
sysDiffLog.setDiffData(changesToString(changes));
sysDiffLog.setCreateBy(ShiroUtils.getLoginName());
sysDiffLog.setCreateTime(DateUtils.getNowDate());
sysDiffLog.setUpdateBy(ShiroUtils.getLoginName());
sysDiffLog.setUpdateTime(DateUtils.getNowDate());
return sysDiffLogMapper.insertSysDiffLog(sysDiffLog);
}
}
private String changesToString(List<SysFieldDifferent> changes) {
return changes.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
}
/**
* 删除数据修改记录日志对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteSysDiffLogByIds(String ids)
{
return sysDiffLogMapper.deleteSysDiffLogByIds(Convert.toStrArray(ids));
}
/**
* 删除数据修改记录日志信息
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
@Override
public int deleteSysDiffLogById(Long diffId)
{
return sysDiffLogMapper.deleteSysDiffLogById(diffId);
}
/**
* 作废数据修改记录日志
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
@Override
public int cancelSysDiffLogById(Long diffId)
{
return sysDiffLogMapper.cancelSysDiffLogById(diffId);
}
/**
* 恢复数据修改记录日志信息
*
* @param diffId 数据修改记录日志ID
* @return 结果
*/
@Override
public int restoreSysDiffLogById(Long diffId)
{
return sysDiffLogMapper.restoreSysDiffLogById(diffId);
}
/**
* diff_data 数据通过JSON 序列化和反序列化
* */
public List<SysFieldDifferent> parseDiffData(String diffData) {
if (diffData == null || diffData.trim().isEmpty()) {
return new ArrayList<>();
}
List<SysFieldDifferent> sysFieldDifferents = new ArrayList<>();
Pattern pattern = Pattern.compile("\\{(.*?)\\}");
Matcher matcher = pattern.matcher(diffData);
while (matcher.find()) {
String entry = matcher.group(1);
SysFieldDifferent sysFieldDifferent = parseSingleEntry(entry);
if (sysFieldDifferent != null) {
sysFieldDifferents.add(sysFieldDifferent);
}
}
return sysFieldDifferents;
}
// 解析单个条目
private static SysFieldDifferent parseSingleEntry(String entryStr) {
SysFieldDifferent sysFieldDifferent = new SysFieldDifferent();
String[] parts = entryStr.split(", ");
for (String part : parts) {
String[] keyValue = part.split("=");
if (keyValue.length == 2) {
String key = keyValue[0].trim();
String value = keyValue[1].trim();
value = value.replaceAll("^'|'$", ""); // 去掉首尾的单引号
switch (key) {
case "fieldName":
sysFieldDifferent.setFieldName(value);
break;
case "before":
sysFieldDifferent.setBefore(value);
break;
case "after":
sysFieldDifferent.setAfter(value);
break;
default:
break;
}
}
}
return sysFieldDifferent;
}
/**
* 展示数据修改记录日志
* */
@Override
public List<SysDiffLogVo> getDiffLogList(Long businessId,String businessKey) {
List<SysDiffLogVo> sysDiffLogVos = new ArrayList<>();
SysDiffLog sysDiffLog = new SysDiffLog();
sysDiffLog.setBusinessId(businessId);
sysDiffLog.setBusinessKey(businessKey);
SysDiffLog tempDiffLog = sysDiffLogMapper.selectSysDiffLogByBusiness(sysDiffLog);
// 检查查询结果是否为空
if (tempDiffLog == null || tempDiffLog.getDiffData() == null) {
return sysDiffLogVos; // 直接返回空列表
}
List<SysFieldDifferent> sysFieldDifferents = parseDiffData(tempDiffLog.getDiffData());
sysFieldDifferents.forEach(sysFieldDifferent -> {
SysDiffLogVo sysDiffLogVo = new SysDiffLogVo();
sysDiffLogVo.setFieldName(sysFieldDifferent.getFieldName());
sysDiffLogVo.setBefore(sysFieldDifferent.getBefore());
sysDiffLogVo.setAfter(sysFieldDifferent.getAfter());
sysDiffLogVo.setUpdateTime(tempDiffLog.getUpdateTime());
sysDiffLogVo.setUpdateBy(tempDiffLog.getUpdateBy());
sysDiffLogVos.add(sysDiffLogVo);
});
return sysDiffLogVos;
}
}

38
ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/SysProductModelServiceImpl.java

@ -1,20 +1,27 @@
package com.ruoyi.system.service.impl; package com.ruoyi.system.service.impl;
import com.ruoyi.common.constant.BusinessKeysConstants;
import com.ruoyi.common.core.domain.entity.SysFieldDifferent;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.FieldCompareUtil;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysAttach; import com.ruoyi.system.domain.SysAttach;
import com.ruoyi.system.domain.SysDiffLog;
import com.ruoyi.system.domain.SysProductModel; import com.ruoyi.system.domain.SysProductModel;
import com.ruoyi.system.mapper.SysProductModelMapper; import com.ruoyi.system.mapper.SysProductModelMapper;
import com.ruoyi.system.service.ISysAttachFileService; import com.ruoyi.system.service.ISysAttachFileService;
import com.ruoyi.system.service.ISysAttachService; import com.ruoyi.system.service.ISysAttachService;
import com.ruoyi.system.service.ISysDiffLogService;
import com.ruoyi.system.service.ISysProductModelService; import com.ruoyi.system.service.ISysProductModelService;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
@ -40,6 +47,10 @@ public class SysProductModelServiceImpl implements ISysProductModelService
@Autowired @Autowired
private ISysAttachFileService attachFileService; private ISysAttachFileService attachFileService;
@Autowired
private ISysDiffLogService diffLogService;
/** /**
* 查询产品型号管理 * 查询产品型号管理
* *
@ -80,6 +91,14 @@ public class SysProductModelServiceImpl implements ISysProductModelService
sysProductModel.setCreateTime(DateUtils.getNowDate()); sysProductModel.setCreateTime(DateUtils.getNowDate());
int result = sysProductModelMapper.insertSysProductModel(sysProductModel); int result = sysProductModelMapper.insertSysProductModel(sysProductModel);
Long pid = sysProductModel.getPid(); Long pid = sysProductModel.getPid();
SysDiffLog sysDiffLog = new SysDiffLog();
sysDiffLog.setBusinessId(pid);
sysDiffLog.setBusinessKey(BusinessKeysConstants.PRODUCT_MODEL);
int insertSysDiffLog = diffLogService.insertSysDiffLog(sysDiffLog);
if (insertSysDiffLog <= 0){
throw new RuntimeException("新增产品型号管理数据修改记录失败");
}
String fileIdStr = sysProductModel.getFileIdStr(); String fileIdStr = sysProductModel.getFileIdStr();
if (StringUtils.isNotBlank(fileIdStr)){ if (StringUtils.isNotBlank(fileIdStr)){
//保存附件关联 //保存附件关联
@ -104,11 +123,27 @@ public class SysProductModelServiceImpl implements ISysProductModelService
* @param sysProductModel 产品型号管理 * @param sysProductModel 产品型号管理
* @return 结果 * @return 结果
*/ */
@SneakyThrows
@Transactional(rollbackFor = Exception.class)
@Override @Override
public int updateSysProductModel(SysProductModel sysProductModel) public int updateSysProductModel(SysProductModel sysProductModel)
{ {
String loginName = ShiroUtils.getLoginName();
sysProductModel.setUpdateTime(DateUtils.getNowDate()); sysProductModel.setUpdateTime(DateUtils.getNowDate());
sysProductModel.setUpdateBy(ShiroUtils.getLoginName()); sysProductModel.setUpdateBy(loginName);
Long pid = sysProductModel.getPid();
SysProductModel oldProductModel = sysProductModelMapper.selectSysProductModelById(pid);
if (oldProductModel == null){
throw new RuntimeException("产品型号管理数据不存在");
}
List<SysFieldDifferent> compare = FieldCompareUtil.compare(SysProductModel.class, sysProductModel,oldProductModel);
if (!CollectionUtils.isEmpty(compare)){
int updateSysDiffLog = diffLogService.updateSysDiffLogByBusiness(pid,BusinessKeysConstants.PRODUCT_MODEL,compare);
if (updateSysDiffLog <= 0){
throw new RuntimeException("修改产品型号管理数据修改记录失败");
}
}
return sysProductModelMapper.updateSysProductModel(sysProductModel); return sysProductModelMapper.updateSysProductModel(sysProductModel);
} }
@ -178,4 +213,5 @@ public class SysProductModelServiceImpl implements ISysProductModelService
public List<SysProductModel> selectSysProductModelListByCodes(String[] pcodes) { public List<SysProductModel> selectSysProductModelListByCodes(String[] pcodes) {
return sysProductModelMapper.selectSysProductModelListByCodes(pcodes); return sysProductModelMapper.selectSysProductModelListByCodes(pcodes);
} }
} }

100
ruoyi-admin/src/main/resources/mapper/system/SysDiffLogMapper.xml

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysDiffLogMapper">
<resultMap type="SysDiffLog" id="SysDiffLogResult">
<result property="diffId" column="diff_id" />
<result property="businessId" column="business_id" />
<result property="businessKey" column="business_key" />
<result property="diffData" column="diff_data" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectSysDiffLogVo">
select diff_id, business_id, business_key, diff_data, create_by, create_time, update_by, update_time, remark from sys_diff_log
</sql>
<select id="selectSysDiffLogList" parameterType="SysDiffLog" resultMap="SysDiffLogResult">
<include refid="selectSysDiffLogVo"/>
<where>
<if test="businessId != null "> and business_id = #{businessId}</if>
<if test="businessKey != null and businessKey != ''"> and business_key = #{businessKey}</if>
</where>
</select>
<select id="selectSysDiffLogById" parameterType="Long" resultMap="SysDiffLogResult">
<include refid="selectSysDiffLogVo"/>
where diff_id = #{diffId}
</select>
<select id="selectSysDiffLogByBusiness" parameterType="SysDiffLog" resultMap="SysDiffLogResult">
<include refid="selectSysDiffLogVo"/>
where business_id = #{businessId}
and business_key = #{businessKey}
</select>
<insert id="insertSysDiffLog" parameterType="SysDiffLog" useGeneratedKeys="true" keyProperty="diffId">
insert into sys_diff_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="businessId != null">business_id,</if>
<if test="businessKey != null">business_key,</if>
<if test="diffData != null">diff_data,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="businessId != null">#{businessId},</if>
<if test="businessKey != null">#{businessKey},</if>
<if test="diffData != null">#{diffData},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateSysDiffLog" parameterType="SysDiffLog">
update sys_diff_log
<trim prefix="SET" suffixOverrides=",">
<if test="businessId != null">business_id = #{businessId},</if>
<if test="businessKey != null">business_key = #{businessKey},</if>
<if test="diffData != null">diff_data = #{diffData},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where diff_id = #{diffId}
</update>
<delete id="deleteSysDiffLogById" parameterType="Long">
delete from sys_diff_log where diff_id = #{diffId}
</delete>
<delete id="deleteSysDiffLogByIds" parameterType="String">
delete from sys_diff_log where diff_id in
<foreach item="diffId" collection="array" open="(" separator="," close=")">
#{diffId}
</foreach>
</delete>
<update id="cancelSysDiffLogById" parameterType="Long">
update sys_diff_log set del_flag = '1' where diff_id = #{diffId}
</update>
<update id="restoreSysDiffLogById" parameterType="Long">
update sys_diff_log set del_flag = '0' where diff_id = #{diffId}
</update>
</mapper>

59
ruoyi-admin/src/main/resources/templates/system/diffLog/diffLog.html

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('数据修改记录日志列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "system/diffLog";
var businessId = [[${businessId}]];
var businessKey = [[${businessKey}]];
$(function() {
var options = {
url: prefix + "/list",
showColumns: false,
showToggle: false,
showRefresh:false,
showSearch:false,
modalName: "数据修改记录日志",
queryParams : {
businessId: businessId,
businessKey: businessKey
},
columns: [
{
title: '修改字段',
field: 'fieldName',
},
{
title: '修改前的值',
field: 'before',
},
{
title: '修改后的值',
field: 'after',
},
{
title: '更新人',
field: 'updateBy',
},
{
title: '上次更新时间',
field: 'updateTime',
},]
};
$.table.init(options);
});
</script>
</body>
</html>

9
ruoyi-admin/src/main/resources/templates/system/model/model.html

@ -86,6 +86,15 @@
modalName: "产品型号管理", modalName: "产品型号管理",
fixedColumns: true, // 启用冻结列 fixedColumns: true, // 启用冻结列
fixedRightNumber: 1, // 冻结右列个数 fixedRightNumber: 1, // 冻结右列个数
onDblClickCell: function(field, value, row, $element) {
var businessId = row.pid;
var businessKey = "1";
if(field == 'updateTime'){
var url = ctx + "system/diffLog/getDiffDataList/" + businessId + "/" + businessKey;
$.modal.open("数据修改记录", url);
}
}, //双击单列字段触发事件
columns: [ columns: [
{checkbox: true}, {checkbox: true},
{ title: '产品型号管理表id',field: 'pid',visible: false}, { title: '产品型号管理表id',field: 'pid',visible: false},

25
ruoyi-common/src/main/java/com/ruoyi/common/annotation/FieldCompare.java

@ -0,0 +1,25 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.*;
/**
* 自定义注解字段对比
*
* @author 刘晓旭
* @date 2024-10-16
* */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface FieldCompare {
/** 字段对应的中文 */
String chineseName();
/**
* 类型映射
* 使用方式 1:,0:
*/
String properties() default "";
}

15
ruoyi-common/src/main/java/com/ruoyi/common/constant/BusinessKeysConstants.java

@ -0,0 +1,15 @@
package com.ruoyi.common.constant;
/**
* 修改数据记录日志业务模块常量
*
* @author 刘晓旭
* @date 2024-10-15
*/
public class BusinessKeysConstants {
/** 测试产品型号管理 */
public static final String PRODUCT_MODEL = "1";
}

62
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysFieldDifferent.java

@ -0,0 +1,62 @@
package com.ruoyi.common.core.domain.entity;
/**
* 字段差异实体类
*
* @author 刘晓旭
* @date 2024-10-15
*/
public class SysFieldDifferent {
//差异字段名称
private String fieldName;
//修改前
private String before;
//修改后
private String after;
public SysFieldDifferent() {
}
public SysFieldDifferent(String fieldName, String before, String after) {
this.fieldName = fieldName;
this.before = before;
this.after = after;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getBefore() {
return before;
}
public void setBefore(String before) {
this.before = before;
}
public String getAfter() {
return after;
}
public void setAfter(String after) {
this.after = after;
}
@Override
public String toString() {
return "{" +
"fieldName='" + fieldName + '\'' +
", before='" + before + '\'' +
", after='" + after + '\'' +
'}';
}
}

92
ruoyi-common/src/main/java/com/ruoyi/common/utils/FieldCompareUtil.java

@ -0,0 +1,92 @@
package com.ruoyi.common.utils;
import com.ruoyi.common.annotation.FieldCompare;
import com.ruoyi.common.core.domain.entity.SysFieldDifferent;
import com.ruoyi.common.exception.BusinessException;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
/**
* 字段对比工具类
*
* @author 刘晓旭
* @date 2024-10-16
* */
public class FieldCompareUtil {
public static <T> List<SysFieldDifferent> compare(Class<T> type, T newObject, T oldObject) throws Exception {
// 变更的记录列表
List<SysFieldDifferent> changeLogFields = new ArrayList<>();
Class<?> newObj = newObject.getClass();
Field[] newFields = type.getDeclaredFields();
for (int i = 0; i < newFields.length; i++) {
FieldCompare newAnnotation = newFields[i].getAnnotation(FieldCompare.class);
if (null != newAnnotation) {
PropertyDescriptor newPd = new PropertyDescriptor(newFields[i].getName(), newObj);
Method getMethodNew = newPd.getReadMethod();
Object oldVal = getMethodNew.invoke(oldObject);
Object newVal = getMethodNew.invoke(newObject);
boolean eq = false;
if (oldVal instanceof String) {
String s1 = String.valueOf(oldVal).trim();
String s2 = String.valueOf(newVal).trim();
eq = !s1.equals(s2);
} else if (oldVal instanceof Integer) {
int i1 = (Integer) oldVal;
int i2 = (Integer) newVal;
eq = i1 != i2;
} else if (oldVal instanceof Double) {
double d1 = (Double) oldVal;
double d2 = (Double) newVal;
eq = d1 != d2;
} else if (oldVal instanceof BigDecimal) {
BigDecimal b1 = (BigDecimal) oldVal;
BigDecimal b2 = (BigDecimal) newVal;
eq = b1.compareTo(b2) != 0;
} else if (oldVal instanceof Long) {
long l1 = (Long) oldVal;
long l2 = (Long) newVal;
eq = l1 != l2;
} else {
eq = !oldVal.equals(newVal);
}
String s1 = oldVal == null ? "" : oldVal.toString().trim();
String s2 = newVal == null ? "" : newVal.toString().trim();
if (eq) {
Map<String, String> map = codeToNameMap(newAnnotation);
if (map.size() > 0) {
changeLogFields.add(new SysFieldDifferent(newAnnotation.chineseName(), map.get(s1), map.get(s2)));
} else {
changeLogFields.add(new SysFieldDifferent(newAnnotation.chineseName(), s1, s2));
}
}
}
}
return changeLogFields;
}
/**
* 字典映射 使用方式:
* @param newAnnotation
* @return
*/
private static Map<String, String> codeToNameMap(FieldCompare newAnnotation) {
Map<String, String> map = new HashMap<>();
String properties = newAnnotation.properties();
if (properties != null && properties.length() > 0) {
String[] propertiesArr = properties.split(",");
for (String propertie : propertiesArr) {
String[] split = propertie.split(":");
map.put(split[0], split[1]);
}
}
return map;
}
}
Loading…
Cancel
Save