feat: 增加电站基本信息操作日志

This commit is contained in:
tangwei 2026-06-22 16:32:53 +08:00
parent 719a18934e
commit b0ef0ada66
10 changed files with 367 additions and 6 deletions

View File

@ -5,6 +5,7 @@ import com.yfd.platform.annotation.Log;
import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
import com.yfd.platform.qgc_base.domain.SdEngInfoBHOperateRequest;
import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest;
import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
import io.swagger.v3.oas.annotations.Operation;
@ -91,16 +92,16 @@ public class SdEngInfoBHController {
@Log(module = "电站管理", value = "新增电站")
@PostMapping("/add")
@Operation(summary = "新增电站")
public ResponseResult add(@RequestBody SdEngInfoBH engInfo) {
boolean result = engInfoBHService.addEngInfo(engInfo);
public ResponseResult add(@RequestBody SdEngInfoBHOperateRequest request) {
boolean result = engInfoBHService.addEngInfo(request.getEngInfo(), request.getSource());
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@Log(module = "电站管理", value = "修改电站")
@PostMapping("/update")
@Operation(summary = "修改电站")
public ResponseResult update(@RequestBody SdEngInfoBH engInfo) {
boolean result = engInfoBHService.updateEngInfo(engInfo);
public ResponseResult update(@RequestBody SdEngInfoBHOperateRequest request) {
boolean result = engInfoBHService.updateEngInfo(request.getEngInfo(), request.getSource());
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@ -111,4 +112,5 @@ public class SdEngInfoBHController {
boolean result = engInfoBHService.deleteEngInfo(stcd);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
}

View File

@ -0,0 +1,32 @@
package com.yfd.platform.qgc_base.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("MS_OPERATION_LOG")
public class MsOperationLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_UUID)
private String id;
@TableField("OPERATOR")
private String operator;
@TableField("OPERATE_TIME")
private Date operateTime;
@TableField("SOURCE")
private String source;
@TableField("REMARK")
private String remark;
}

View File

@ -0,0 +1,49 @@
package com.yfd.platform.qgc_base.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("MS_OPERATION_LOG_DETAIL")
public class MsOperationLogDetail implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_UUID)
private String id;
@TableField("MAIN_ID")
private String mainId;
@TableField("FIELD_CODE")
private String fieldCode;
@TableField("TABLE_NAME")
private String tableName;
@TableField("FIELD_MEANING")
private String fieldMeaning;
@TableField("STATION_CODE")
private String stationCode;
@TableField("OLD_VALUE_CODE")
private String oldValueCode;
@TableField("OLD_VALUE_NAME")
private String oldValueName;
@TableField("NEW_VALUE_CODE")
private String newValueCode;
@TableField("NEW_VALUE_NAME")
private String newValueName;
@TableField("REMARK")
private String remark;
}

View File

@ -0,0 +1,11 @@
package com.yfd.platform.qgc_base.domain;
import lombok.Data;
@Data
public class SdEngInfoBHOperateRequest {
private SdEngInfoBH engInfo;
private String source;
}

View File

@ -0,0 +1,7 @@
package com.yfd.platform.qgc_base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_base.domain.MsOperationLogDetail;
public interface MsOperationLogDetailMapper extends BaseMapper<MsOperationLogDetail> {
}

View File

@ -0,0 +1,7 @@
package com.yfd.platform.qgc_base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_base.domain.MsOperationLog;
public interface MsOperationLogMapper extends BaseMapper<MsOperationLog> {
}

View File

@ -0,0 +1,10 @@
package com.yfd.platform.qgc_base.service;
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
public interface IMsOperationLogService {
void recordEngAddLog(SdEngInfoBH engInfo, String source);
void recordEngUpdateLog(SdEngInfoBH before, SdEngInfoBH changeSet, String source);
}

View File

@ -52,11 +52,15 @@ public interface ISdEngInfoBHService extends IService<SdEngInfoBH> {
*/
boolean addEngInfo(SdEngInfoBH engInfo);
boolean addEngInfo(SdEngInfoBH engInfo, String source);
/**
* 修改电站
*/
boolean updateEngInfo(SdEngInfoBH engInfo);
boolean updateEngInfo(SdEngInfoBH engInfo, String source);
/**
* 删除电站
*/

View File

@ -0,0 +1,213 @@
package com.yfd.platform.qgc_base.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.yfd.platform.qgc_base.domain.MsOperationLog;
import com.yfd.platform.qgc_base.domain.MsOperationLogDetail;
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
import com.yfd.platform.qgc_base.mapper.MsOperationLogDetailMapper;
import com.yfd.platform.qgc_base.mapper.MsOperationLogMapper;
import com.yfd.platform.qgc_base.service.IMsOperationLogService;
import com.yfd.platform.utils.SecurityUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Service
public class MsOperationLogServiceImpl implements IMsOperationLogService {
private static final String ENG_TABLE_NAME = "SD_ENGINFO_B_H";
private static final Map<String, String> ENG_FIELD_MEANING_MAP = new LinkedHashMap<>();
static {
ENG_FIELD_MEANING_MAP.put("STCD", "电站编码");
ENG_FIELD_MEANING_MAP.put("ENNM", "电站名称");
ENG_FIELD_MEANING_MAP.put("BASE_ID", "所属基地编码");
ENG_FIELD_MEANING_MAP.put("HBRVCD", "所属基地流域编码");
ENG_FIELD_MEANING_MAP.put("RVCD", "所属流域编码");
ENG_FIELD_MEANING_MAP.put("ADDVCD", "所属行政区编码");
ENG_FIELD_MEANING_MAP.put("HYCD", "所属公司编码");
ENG_FIELD_MEANING_MAP.put("BLPRD", "所属建设阶段");
ENG_FIELD_MEANING_MAP.put("BLDSTT", "建设状态");
ENG_FIELD_MEANING_MAP.put("BLDSTT_CODE", "建设状态分类");
ENG_FIELD_MEANING_MAP.put("DVTP", "开发方式");
ENG_FIELD_MEANING_MAP.put("DTIN", "数据是否接入");
ENG_FIELD_MEANING_MAP.put("RGCP", "调节性能");
ENG_FIELD_MEANING_MAP.put("LGTD", "经度");
ENG_FIELD_MEANING_MAP.put("LTTD", "纬度");
ENG_FIELD_MEANING_MAP.put("STLC", "站址");
ENG_FIELD_MEANING_MAP.put("ORDER_INDEX", "排序");
}
@Resource
private MsOperationLogMapper msOperationLogMapper;
@Resource
private MsOperationLogDetailMapper msOperationLogDetailMapper;
@Override
public void recordEngAddLog(SdEngInfoBH engInfo, String source) {
if (engInfo == null) {
return;
}
MsOperationLog mainLog = buildMainLog("新增电站", source);
msOperationLogMapper.insert(mainLog);
List<MsOperationLogDetail> details = new ArrayList<>();
for (Field field : SdEngInfoBH.class.getDeclaredFields()) {
if (shouldSkipField(field)) {
continue;
}
field.setAccessible(true);
Object newValue = getFieldValue(field, engInfo);
if (newValue == null) {
continue;
}
details.add(buildDetail(mainLog.getId(), engInfo.getStcd(), resolveColumnName(field),
null, newValue, "新增字段值"));
}
batchInsertDetails(details);
}
@Override
public void recordEngUpdateLog(SdEngInfoBH before, SdEngInfoBH changeSet, String source) {
if (before == null || changeSet == null) {
return;
}
SdEngInfoBH after = BeanUtil.copyProperties(before, SdEngInfoBH.class);
BeanUtil.copyProperties(changeSet, after, CopyOptions.create().ignoreNullValue());
MsOperationLog mainLog = buildMainLog("修改电站", source);
msOperationLogMapper.insert(mainLog);
List<MsOperationLogDetail> details = new ArrayList<>();
for (Field field : SdEngInfoBH.class.getDeclaredFields()) {
if (shouldSkipField(field)) {
continue;
}
field.setAccessible(true);
Object oldValue = getFieldValue(field, before);
Object newValue = getFieldValue(field, after);
if (equalsValue(oldValue, newValue)) {
continue;
}
details.add(buildDetail(mainLog.getId(), after.getStcd(), resolveColumnName(field),
oldValue, newValue, "修改字段值"));
}
batchInsertDetails(details);
}
private MsOperationLog buildMainLog(String remark, String source) {
MsOperationLog log = new MsOperationLog();
log.setOperator(resolveOperator());
log.setOperateTime(new Date());
log.setSource(StrUtil.trimToNull(source));
log.setRemark(remark);
return log;
}
private MsOperationLogDetail buildDetail(String mainId,
String stationCode,
String fieldCode,
Object oldValue,
Object newValue,
String remark) {
MsOperationLogDetail detail = new MsOperationLogDetail();
detail.setMainId(mainId);
detail.setTableName(ENG_TABLE_NAME);
detail.setStationCode(stationCode);
detail.setFieldCode(fieldCode);
detail.setFieldMeaning(ENG_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode));
detail.setOldValueCode(formatValue(oldValue));
detail.setOldValueName(formatValue(oldValue));
detail.setNewValueCode(formatValue(newValue));
detail.setNewValueName(formatValue(newValue));
detail.setRemark(remark);
return detail;
}
private void batchInsertDetails(List<MsOperationLogDetail> details) {
msOperationLogDetailMapper.insert(details);
}
private boolean shouldSkipField(Field field) {
if (Modifier.isStatic(field.getModifiers())) {
return true;
}
TableField tableField = field.getAnnotation(TableField.class);
if (tableField != null && !tableField.exist()) {
return true;
}
return false;
}
private String resolveColumnName(Field field) {
TableId tableId = field.getAnnotation(TableId.class);
if (tableId != null) {
return camelToUpperUnderline(field.getName());
}
TableField tableField = field.getAnnotation(TableField.class);
if (tableField != null && StrUtil.isNotBlank(tableField.value())) {
return tableField.value();
}
return camelToUpperUnderline(field.getName());
}
private Object getFieldValue(Field field, Object target) {
try {
return field.get(target);
} catch (IllegalAccessException e) {
return null;
}
}
private boolean equalsValue(Object oldValue, Object newValue) {
return StrUtil.equals(formatValue(oldValue), formatValue(newValue));
}
private String formatValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Date date) {
return DateUtil.formatDateTime(date);
}
return String.valueOf(value);
}
private String resolveOperator() {
try {
return SecurityUtils.getCurrentUsername();
} catch (Exception ignored) {
try {
return SecurityUtils.getUserId();
} catch (Exception ex) {
return null;
}
}
}
private String camelToUpperUnderline(String text) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (Character.isUpperCase(ch) && i > 0) {
builder.append('_');
}
builder.append(Character.toUpperCase(ch));
}
return builder.toString();
}
}

View File

@ -22,11 +22,13 @@ import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo;
import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo;
import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo;
import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper;
import com.yfd.platform.qgc_base.service.IMsOperationLogService;
import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
import com.yfd.platform.utils.QgcQueryWrapperUtil;
import com.yfd.platform.utils.SecurityUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
@ -56,6 +58,9 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
@Resource
private SysUserDataScopeMapper sysUserDataScopeMapper;
@Resource
private IMsOperationLogService msOperationLogService;
@Override
public Page<SdEngInfoBH> queryPageList(Page<SdEngInfoBH> page, String ennm, String rvcd, String baseId, String hycd) {
LambdaQueryWrapper<SdEngInfoBH> wrapper = new LambdaQueryWrapper<>();
@ -190,12 +195,33 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
@Override
public boolean addEngInfo(SdEngInfoBH engInfo) {
return this.save(engInfo);
return addEngInfo(engInfo, null);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean addEngInfo(SdEngInfoBH engInfo, String source) {
boolean result = this.save(engInfo);
if (result) {
msOperationLogService.recordEngAddLog(engInfo, source);
}
return result;
}
@Override
public boolean updateEngInfo(SdEngInfoBH engInfo) {
return this.updateById(engInfo);
return updateEngInfo(engInfo, null);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateEngInfo(SdEngInfoBH engInfo, String source) {
SdEngInfoBH before = engInfo == null ? null : this.getById(engInfo.getStcd());
boolean result = this.updateById(engInfo);
if (result && before != null) {
msOperationLogService.recordEngUpdateLog(before, engInfo, source);
}
return result;
}
@Override