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 bd654d5d..8212bef8 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 @@ -243,6 +243,7 @@ public class SdWTMonitorController { return ResponseResult.successData(sdWtMonitorService.getCxDetailList(dataSourceRequest)); } + @Log(module = "水温监测", value = "删除垂向水温数据") @PostMapping("/cxDetail/removeKendoByIds") @Operation(summary = "删除垂向水温数据") public ResponseResult removeCxDetailByIds(@RequestBody BatchDeleteAo batchDeleteAo) { @@ -250,10 +251,14 @@ public class SdWTMonitorController { return ResponseResult.success(); } + @Log(module = "水温监测", value = "修改垂向水温数据") @PostMapping("/cxDetail/updateWtvtRData") @Operation(summary = "修改垂向水温数据") public ResponseResult updateWtvtRData(@RequestBody WtOperateRequest wtOperateRequest) { - sdWtvtRService.updateWtvtRData(wtOperateRequest.getUpdateData()); + sdWtvtRService.updateWtvtRData( + wtOperateRequest == null ? null : wtOperateRequest.getUpdateData(), + wtOperateRequest == null ? null : wtOperateRequest.getSource() + ); return ResponseResult.success(); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java index 2b62f2b3..43c165a0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java @@ -24,5 +24,5 @@ public interface SdWtvtRService { boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); - void updateWtvtRData(Map updateData); + void updateWtvtRData(Map updateData, String source); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java index c91fcda6..80a91b5a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java @@ -1,13 +1,18 @@ package com.yfd.platform.qgc_env.wt.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.qgc_base.domain.MsOperationLog; +import com.yfd.platform.qgc_base.domain.MsOperationLogDetail; 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.qgc_env.wt.entity.vo.SdWtvtYearVo; import com.yfd.platform.qgc_env.wt.mapper.SdWtvtRMapper; import com.yfd.platform.qgc_env.wt.service.SdWtvtRService; @@ -22,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import java.util.HashSet; import java.util.HashMap; import java.util.List; @@ -37,6 +43,28 @@ import java.util.Set; */ @Service public class SdWtvtRServiceImpl extends ServiceImpl implements SdWtvtRService { + private static final String WT_CX_TABLE_NAME = "SD_WTVT_R"; + private static final Map WT_CX_FIELD_MEANING_MAP = new LinkedHashMap<>(); + + static { + WT_CX_FIELD_MEANING_MAP.put("ID", "主键ID"); + WT_CX_FIELD_MEANING_MAP.put("STCD", "垂向水温站编码"); + WT_CX_FIELD_MEANING_MAP.put("TM", "时间"); + WT_CX_FIELD_MEANING_MAP.put("WTHG", "水温深度"); + WT_CX_FIELD_MEANING_MAP.put("VWT", "水温"); + WT_CX_FIELD_MEANING_MAP.put("FID", "附件ID"); + WT_CX_FIELD_MEANING_MAP.put("RECORD_USER", "创建人"); + WT_CX_FIELD_MEANING_MAP.put("RECORD_TIME", "创建时间"); + WT_CX_FIELD_MEANING_MAP.put("MODIFY_USER", "更新人"); + WT_CX_FIELD_MEANING_MAP.put("MODIFY_TIME", "更新时间"); + WT_CX_FIELD_MEANING_MAP.put("IS_DELETED", "是否已删除"); + WT_CX_FIELD_MEANING_MAP.put("DELETE_USER", "删除人"); + WT_CX_FIELD_MEANING_MAP.put("DELETE_TIME", "删除时间"); + WT_CX_FIELD_MEANING_MAP.put("RZ", "坝前水位"); + WT_CX_FIELD_MEANING_MAP.put("HGT", "测点高程"); + WT_CX_FIELD_MEANING_MAP.put("REMARK", "备注"); + WT_CX_FIELD_MEANING_MAP.put("WER_ID", "所属水生生态调查数据表ID"); + } @Resource private SdWtvtRMapper sdWtvtRMapper; @@ -47,6 +75,12 @@ public class SdWtvtRServiceImpl extends ServiceImpl @Resource private JdbcTemplate jdbcTemplate; + @Resource + private MsOperationLogMapper msOperationLogMapper; + + @Resource + private MsOperationLogDetailMapper msOperationLogDetailMapper; + @Override public DataSourceResult getWtrvDefaultYear(DataSourceRequest dataSourceRequest) { DataSourceResult dataSourceResult = new DataSourceResult<>(); @@ -91,6 +125,7 @@ public class SdWtvtRServiceImpl extends ServiceImpl public boolean removeKendoByIds(BatchDeleteAo batchDeleteAo) { String dataType = batchDeleteAo == null ? null : batchDeleteAo.getDataType(); List dataList = batchDeleteAo == null ? null : batchDeleteAo.getDataList(); + String source = batchDeleteAo == null ? null : batchDeleteAo.getSource(); if (CollUtil.isEmpty(dataList)) { return true; } @@ -104,7 +139,9 @@ public class SdWtvtRServiceImpl extends ServiceImpl continue; } if ("TIME".equalsIgnoreCase(dataType)) { + List> beforeRows = queryWtvtRows(subList); deleteWtvtRData(subList); + recordWtvtDeleteLog(beforeRows, "删除垂向水温数据", source); Map dateRangeMap = new HashMap<>(); Map monthRangeMap = new HashMap<>(); for (DataParam param : subList) { @@ -160,7 +197,7 @@ public class SdWtvtRServiceImpl extends ServiceImpl @Override @Transactional(rollbackFor = Exception.class) - public void updateWtvtRData(Map updateData) { + public void updateWtvtRData(Map updateData, String source) { if (updateData == null || updateData.isEmpty()) { return; } @@ -171,7 +208,10 @@ public class SdWtvtRServiceImpl extends ServiceImpl return; } + Map> beforeRowMap = buildWtvtBeforeRowMap(stcd, dt); + List> dataList = new ArrayList<>(); + List logDetails = new ArrayList<>(); rawMap.forEach((wthgObj, vwtObj) -> { if (wthgObj == null) { return; @@ -192,12 +232,32 @@ public class SdWtvtRServiceImpl extends ServiceImpl // item.put("recordUser", "admin"); item.put("recordUser", SecurityUtils.getUserId()); dataList.add(item); + + String depthKey = buildWtvtDepthKey(item.get("wthg")); + Map beforeRow = beforeRowMap.get(depthKey); + Object oldValue = beforeRow == null ? null : beforeRow.get("VWT"); + Object newValue = item.get("vwt"); + if (StringUtils.equals(formatWtvtLogValue(oldValue), formatWtvtLogValue(newValue))) { + return; + } + logDetails.add(buildWtvtDetail(null, stcd, "VWT", + oldValue, resolveWtvtDisplayValue("VWT", oldValue), + newValue, resolveWtvtDisplayValue("VWT", newValue), + buildWtvtDepthRemark("修改字段值", item.get("wthg")))); }); if (dataList.isEmpty()) { return; } batchUpdateWtvtRData(dataList); + if (CollUtil.isNotEmpty(logDetails)) { + MsOperationLog mainLog = buildWtvtMainLog(null,"修改垂向水温数据", source); + msOperationLogMapper.insert(mainLog); + for (MsOperationLogDetail detail : logDetails) { + detail.setMainId(mainLog.getId()); + } + batchInsertWtvtLogDetails(logDetails); + } String dateStr = dt.substring(0, 10); statisticsDayDataFromHour(stcd, dateStr, dateStr); @@ -363,4 +423,163 @@ public class SdWtvtRServiceImpl extends ServiceImpl private String asString(Object value) { return value == null ? null : String.valueOf(value); } + + private List> queryWtvtRows(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, WTHG, VWT, FID, ") + .append("RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME, RZ, HGT, REMARK, WER_ID ") + .append("FROM SD_WTVT_R WHERE "); + List params = new ArrayList<>(); + List conditions = new ArrayList<>(); + for (DataParam item : dataParamList) { + if (item == null || StringUtils.isBlank(item.getId()) || StringUtils.isBlank(item.getDt())) { + continue; + } + conditions.add("(STCD = ? AND TM = TO_DATE(SUBSTR(?, 1, 19), 'YYYY-MM-DD HH24:MI:SS'))"); + params.add(item.getId()); + params.add(item.getDt()); + } + if (conditions.isEmpty()) { + return new ArrayList<>(); + } + sql.append(String.join(" OR ", conditions)); + return normalizeWtvtRows(jdbcTemplate.queryForList(sql.toString(), params.toArray())); + } + + private Map> buildWtvtBeforeRowMap(String stcd, String dt) { + Map> result = new HashMap<>(); + if (StringUtils.isBlank(stcd) || StringUtils.isBlank(dt)) { + return result; + } + String sql = "SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WTHG, VWT, FID, " + + "RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME, RZ, HGT, REMARK, WER_ID " + + "FROM SD_WTVT_R WHERE WTHG IS NOT NULL AND VWT IS NOT NULL AND STCD = ? AND TM = TO_DATE(SUBSTR(?, 1, 19), 'YYYY-MM-DD HH24:MI:SS')"; + List> rows = normalizeWtvtRows(jdbcTemplate.queryForList(sql, stcd, dt)); + for (Map row : rows) { + + result.put(String.valueOf(Double.parseDouble(row.get("WTHG").toString())), row); + } + return result; + } + + private List> normalizeWtvtRows(List> rows) { + List> result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + Map normalized = new LinkedHashMap<>(); + for (Map.Entry entry : row.entrySet()) { + normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue()); + } + result.add(normalized); + } + return result; + } + + private void recordWtvtDeleteLog(List> rows, String remark, String source) { + if (CollUtil.isEmpty(rows)) { + return; + } + MsOperationLog mainLog = buildWtvtMainLog(null,remark, source); + msOperationLogMapper.insert(mainLog); + List details = new ArrayList<>(); + for (Map row : rows) { + String stcd = asString(row.get("STCD")); + Object depth = row.get("WTHG"); + for (Map.Entry entry : row.entrySet()) { + String fieldCode = entry.getKey(); + Object oldValue = entry.getValue(); + if (StringUtils.isBlank(fieldCode) || oldValue == null) { + continue; + } + details.add(buildWtvtDetail(mainLog.getId(), stcd, fieldCode, + oldValue, resolveWtvtDisplayValue(fieldCode, oldValue), + null, null, buildWtvtDepthRemark("删除字段值", depth))); + } + } + batchInsertWtvtLogDetails(details); + } + + private MsOperationLog buildWtvtMainLog(String recordId,String remark, String source) { + MsOperationLog log = new MsOperationLog(); + log.setOperator(resolveWtvtLogOperator()); + log.setOperateTime(new Date()); + log.setTableName(WT_CX_TABLE_NAME); + log.setRecordId(remark); + log.setSource(StringUtils.trimToNull(source)); + log.setRemark(remark); + return log; + } + + private MsOperationLogDetail buildWtvtDetail(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_CX_TABLE_NAME); + detail.setStationCode(stationCode); + detail.setFieldCode(fieldCode); + detail.setFieldMeaning(WT_CX_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode)); + detail.setOldValueCode(formatWtvtLogValue(oldValueCode)); + detail.setOldValueName(formatWtvtLogValue(oldValueName)); + detail.setNewValueCode(formatWtvtLogValue(newValueCode)); + detail.setNewValueName(formatWtvtLogValue(newValueName)); + detail.setRemark(remark); + return detail; + } + + private void batchInsertWtvtLogDetails(List details) { + if (CollUtil.isEmpty(details)) { + return; + } + for (MsOperationLogDetail detail : details) { + if (detail == null) { + continue; + } + msOperationLogDetailMapper.insert(detail); + } + } + + private Object resolveWtvtDisplayValue(String fieldCode, Object rawValue) { + return formatWtvtLogValue(rawValue); + } + + private String resolveWtvtLogOperator() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception ignored) { + try { + return SecurityUtils.getUserId(); + } catch (Exception ex) { + return null; + } + } + } + + private String formatWtvtLogValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return DateUtil.formatDateTime(date); + } + return String.valueOf(value); + } + + private String buildWtvtDepthKey(Object depth) { + return formatWtvtLogValue(depth); + } + + private String buildWtvtDepthRemark(String action, Object depth) { + String depthText = formatWtvtLogValue(depth); + return depthText == null ? action : action + "(深度:" + depthText + ")"; + } }