diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java index f72e1270..bd654d5d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.wt.controller; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.annotation.Log; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; @@ -55,10 +56,14 @@ public class SdWTMonitorController { return ResponseResult.successData(result); } + @Log(module = "水温监测", value = "修改表层水温日数据") @PostMapping("/alongDetail/updateWtrvRData") @Operation(summary = "修改表层水温日数据") - public ResponseResult updateWtrvRData(@RequestBody Map updateData) { - alongDetailService.updateWtrvRData(updateData); + public ResponseResult updateWtrvRData(@RequestBody WtOperateRequest wtOperateRequest) { + alongDetailService.updateWtrvRData( + wtOperateRequest == null ? null : wtOperateRequest.getUpdateData(), + wtOperateRequest == null ? null : wtOperateRequest.getSource() + ); return ResponseResult.success(); } @@ -76,6 +81,7 @@ public class SdWTMonitorController { return ResponseResult.successData(result); } + @Log(module = "水温监测", value = "删除出库水温周旬月季年数据") @PostMapping("/alongDetail/drtp/removeKendoByIds") @Operation(summary = "删除出库水温周旬月季年数据") public ResponseResult removeKendoByIds(@RequestBody BatchDeleteAo batchDeleteAo) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java index 5465ec79..a4de4324 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java @@ -43,6 +43,6 @@ public interface AlongDetailService extends IService { boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); - void updateWtrvRData(Map updateData); + void updateWtrvRData(Map updateData, String source); -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java index 009f7cf6..12572375 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java @@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.common.*; import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.qgc_base.domain.MsOperationLog; +import com.yfd.platform.qgc_base.domain.MsOperationLogDetail; import com.yfd.platform.qgc_env.wt.mapper.AlongDetailMapper; import com.yfd.platform.qgc_env.wt.mapper.SdWtrvdrtpSMapper; import com.yfd.platform.qgc_env.wt.service.AlongDetailService; @@ -17,6 +19,8 @@ import com.yfd.platform.qgc_env.wt.entity.vo.SdAlongDrtpDetailVO; import com.yfd.platform.qgc_env.wt.entity.vo.WtrvInfo; import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo; import com.yfd.platform.qgc_base.entity.vo.DataParam; +import com.yfd.platform.qgc_base.mapper.MsOperationLogDetailMapper; +import com.yfd.platform.qgc_base.mapper.MsOperationLogMapper; import com.yfd.platform.utils.CollectionExtUtils; import com.yfd.platform.utils.QgcQueryWrapperUtil; import com.yfd.platform.utils.SecurityUtils; @@ -37,6 +41,29 @@ import java.util.stream.Collectors; */ @Service public class AlongDetailServiceImpl extends ServiceImpl implements AlongDetailService { + private static final String WT_HOUR_TABLE_NAME = "SD_WTRV_R"; + private static final Map WT_UPDATE_COLUMN_MAP = new LinkedHashMap<>(); + private static final Map WT_FIELD_MEANING_MAP = new LinkedHashMap<>(); + + static { + WT_UPDATE_COLUMN_MAP.put("wt", "WT"); + + WT_FIELD_MEANING_MAP.put("ID", "主键ID"); + WT_FIELD_MEANING_MAP.put("STCD", "水温站编码"); + WT_FIELD_MEANING_MAP.put("TM", "数据时间"); + WT_FIELD_MEANING_MAP.put("WT", "水温"); + WT_FIELD_MEANING_MAP.put("REMARK", "备注"); + WT_FIELD_MEANING_MAP.put("FID", "附件ID"); + WT_FIELD_MEANING_MAP.put("WER_ID", "所属水生生态调查数据表ID"); + WT_FIELD_MEANING_MAP.put("RECORD_USER", "创建人"); + WT_FIELD_MEANING_MAP.put("RECORD_TIME", "创建时间"); + WT_FIELD_MEANING_MAP.put("MODIFY_USER", "更新人"); + WT_FIELD_MEANING_MAP.put("MODIFY_TIME", "更新时间"); + WT_FIELD_MEANING_MAP.put("IS_DELETED", "是否已删除"); + WT_FIELD_MEANING_MAP.put("DELETE_USER", "删除人"); + WT_FIELD_MEANING_MAP.put("DELETE_TIME", "删除时间"); + } + @Resource private DynamicSQLMapper dynamicSQLMapper; @Resource @@ -50,6 +77,12 @@ public class AlongDetailServiceImpl extends ServiceImpl filterResult, Page page) { DataSourceResult dataSourceResult = new DataSourceResult(); @@ -799,6 +832,7 @@ public class AlongDetailServiceImpl extends ServiceImpl dataList = batchDeleteAo.getDataList(); + String source = batchDeleteAo == null ? null : batchDeleteAo.getSource(); if(CollUtil.isEmpty(dataList)){ return true; } @@ -816,7 +850,9 @@ public class AlongDetailServiceImpl extends ServiceImpl> beforeRows = queryWtHourRows(subList); sdWtrvdrtpSMapper.deleteWtrvRData(subList, DateUtil.now(), SecurityUtils.getCurrentUsername()); + recordWtDeleteLog(beforeRows, "删除表层水温日数据", source); // 删除小时数据后,需要重新统计对应的日数据和月数据 Map dateRangeMap = new HashMap<>(); Map monthRangeMap = new HashMap<>(); @@ -1048,13 +1084,14 @@ public class AlongDetailServiceImpl extends ServiceImpl updateData) { + public void updateWtrvRData(Map updateData, String source) { + String stcd = asString(getValueIgnoreCase(updateData, "stcd")); + String tm = asString(getValueIgnoreCase(updateData, "dt")); + Map beforeRow = queryWtHourRow(stcd, tm); sdWtrvdrtpSMapper.updateWtrvRData(updateData); + recordWtUpdateLog(beforeRow, updateData, source); // 获取测站编码和时间 - String stcd = (String) updateData.get("stcd"); - String tm = (String) updateData.get("dt"); - if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm)) { // 提取日期部分(yyyy-MM-dd) String dateStr = tm.substring(0, 10); @@ -1074,4 +1111,199 @@ public class AlongDetailServiceImpl extends ServiceImpl queryWtHourRow(String stcd, String tm) { + if (StrUtil.isBlank(stcd) || StrUtil.isBlank(tm)) { + return new HashMap<>(); + } + String sql = "SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WT, REMARK, FID, WER_ID, " + + "RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME " + + "FROM SD_WTRV_R WHERE STCD = ? AND TM = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS')"; + List> rows = jdbcTemplate.queryForList(sql, stcd, tm); + return rows.isEmpty() ? new HashMap<>() : normalizeWtLogRow(rows.getFirst()); + } + + private List> queryWtHourRows(List dataParamList) { + if (CollUtil.isEmpty(dataParamList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WT, REMARK, FID, WER_ID, ") + .append("RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME ") + .append("FROM SD_WTRV_R WHERE "); + List params = new ArrayList<>(); + for (int i = 0; i < dataParamList.size(); i++) { + if (i > 0) { + sql.append(" OR "); + } + sql.append("(STCD = ? AND TM = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'))"); + DataParam item = dataParamList.get(i); + params.add(item == null ? null : item.getId()); + params.add(item == null ? null : item.getDt()); + } + return normalizeWtLogRows(jdbcTemplate.queryForList(sql.toString(), params.toArray())); + } + + private List> normalizeWtLogRows(List> rows) { + List> result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + result.add(normalizeWtLogRow(row)); + } + return result; + } + + private Map normalizeWtLogRow(Map row) { + Map normalized = new LinkedHashMap<>(); + if (row == null || row.isEmpty()) { + return normalized; + } + for (Map.Entry entry : row.entrySet()) { + normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue()); + } + return normalized; + } + + private void recordWtUpdateLog(Map beforeRow, Map updateData, String source) { + if (updateData == null || updateData.isEmpty()) { + return; + } + String stcd = asString(getValueIgnoreCase(updateData, "stcd")); + List details = new ArrayList<>(); + for (Map.Entry entry : WT_UPDATE_COLUMN_MAP.entrySet()) { + if (!containsKeyIgnoreCase(updateData, entry.getKey())) { + continue; + } + String column = entry.getValue(); + Object oldValue = beforeRow == null ? null : beforeRow.get(column); + Object newValue = getValueIgnoreCase(updateData, entry.getKey()); + if (StrUtil.equals(formatWtLogValue(oldValue), formatWtLogValue(newValue))) { + continue; + } + details.add(buildWtDetail(null, stcd, column, + oldValue, resolveWtDisplayValue(column, oldValue), + newValue, resolveWtDisplayValue(column, newValue), "修改字段值")); + } + if (details.isEmpty()) { + return; + } + MsOperationLog mainLog = buildWtMainLog("修改表层水温日数据", source); + msOperationLogMapper.insert(mainLog); + for (MsOperationLogDetail detail : details) { + detail.setMainId(mainLog.getId()); + } + batchInsertWtLogDetails(details); + } + + private void recordWtDeleteLog(List> rows, String remark, String source) { + if (CollUtil.isEmpty(rows)) { + return; + } + MsOperationLog mainLog = buildWtMainLog(remark, source); + msOperationLogMapper.insert(mainLog); + List details = new ArrayList<>(); + for (Map row : rows) { + String stcd = asString(row.get("STCD")); + for (Map.Entry entry : row.entrySet()) { + String fieldCode = entry.getKey(); + Object oldValue = entry.getValue(); + if (StrUtil.isBlank(fieldCode) || oldValue == null) { + continue; + } + details.add(buildWtDetail(mainLog.getId(), stcd, fieldCode, + oldValue, resolveWtDisplayValue(fieldCode, oldValue), + null, null, "删除字段值")); + } + } + batchInsertWtLogDetails(details); + } + + private MsOperationLog buildWtMainLog(String remark, String source) { + MsOperationLog log = new MsOperationLog(); + log.setOperator(resolveWtLogOperator()); + log.setOperateTime(new Date()); + log.setSource(StrUtil.trimToNull(source)); + log.setRemark(remark); + return log; + } + + private MsOperationLogDetail buildWtDetail(String mainId, + String stationCode, + String fieldCode, + Object oldValueCode, + Object oldValueName, + Object newValueCode, + Object newValueName, + String remark) { + MsOperationLogDetail detail = new MsOperationLogDetail(); + detail.setMainId(mainId); + detail.setTableName(WT_HOUR_TABLE_NAME); + detail.setStationCode(stationCode); + detail.setFieldCode(fieldCode); + detail.setFieldMeaning(WT_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode)); + detail.setOldValueCode(formatWtLogValue(oldValueCode)); + detail.setOldValueName(formatWtLogValue(oldValueName)); + detail.setNewValueCode(formatWtLogValue(newValueCode)); + detail.setNewValueName(formatWtLogValue(newValueName)); + detail.setRemark(remark); + return detail; + } + + private void batchInsertWtLogDetails(List details) { + if (CollUtil.isEmpty(details)) { + return; + } + for (MsOperationLogDetail detail : details) { + if (detail == null) { + continue; + } + msOperationLogDetailMapper.insert(detail); + } + } + + private Object resolveWtDisplayValue(String fieldCode, Object rawValue) { + return formatWtLogValue(rawValue); + } + + private String resolveWtLogOperator() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception ignored) { + try { + return SecurityUtils.getUserId(); + } catch (Exception ex) { + return null; + } + } + } + + private String formatWtLogValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return DateUtil.formatDateTime(date); + } + return String.valueOf(value); + } + + private String asString(Object value) { + return value == null ? null : String.valueOf(value); + } + + private boolean containsKeyIgnoreCase(Map data, String key) { + if (data == null || StrUtil.isBlank(key)) { + return false; + } + if (data.containsKey(key)) { + return true; + } + for (String mapKey : data.keySet()) { + if (StrUtil.equalsIgnoreCase(mapKey, key)) { + return true; + } + } + return false; + } }