fix: 优化水质删除修改逻辑

This commit is contained in:
tangwei 2026-06-29 11:41:09 +08:00
parent dcbe70f5f9
commit fae68975d4
3 changed files with 431 additions and 48 deletions

View File

@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.wq.controller;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo; import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo;
import com.yfd.platform.qgc_env.wq.entity.vo.WqOperateRequest; import com.yfd.platform.qgc_env.wq.entity.vo.WqOperateRequest;
import com.yfd.platform.qgc_env.wq.service.EnvWqDataService; import com.yfd.platform.qgc_env.wq.service.EnvWqDataService;
@ -58,13 +59,18 @@ public class EnvWqDataController {
return ResponseResult.successData(envWqDataService.getDrtpKendoListCust(dataSourceRequest)); return ResponseResult.successData(envWqDataService.getDrtpKendoListCust(dataSourceRequest));
} }
@Log(module = "水质统计分析", value = "修改水质小时数据")
@PostMapping("/updateWqRsData") @PostMapping("/updateWqRsData")
@Operation(summary = "修改水质小时数据") @Operation(summary = "修改水质小时数据")
public ResponseResult updateWqRsData(@RequestBody WqOperateRequest wqOperateRequest) { public ResponseResult updateWqRsData(@RequestBody WqOperateRequest wqOperateRequest) {
envWqDataService.updateWqRsData(wqOperateRequest.getUpdateData()); envWqDataService.updateWqRsData(
wqOperateRequest == null ? null : wqOperateRequest.getUpdateData(),
wqOperateRequest == null ? null : wqOperateRequest.getSource()
);
return ResponseResult.success(); return ResponseResult.success();
} }
@Log(module = "水质统计分析", value = "删除水质小时/日/月数据")
@PostMapping("/removeKendoByIds") @PostMapping("/removeKendoByIds")
@Operation(summary = "删除水质小时/日/月数据") @Operation(summary = "删除水质小时/日/月数据")
public ResponseResult removeKendoByIds(@RequestBody BatchDeleteAo batchDeleteAo) { public ResponseResult removeKendoByIds(@RequestBody BatchDeleteAo batchDeleteAo) {

View File

@ -39,7 +39,7 @@ public interface EnvWqDataService {
DataSourceResult getStTbYsBVoKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getStTbYsBVoKendoListCust(DataSourceRequest dataSourceRequest);
boolean updateWqRsData(Map<String, Object> updateData); boolean updateWqRsData(Map<String, Object> updateData, String source);
boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); boolean removeKendoByIds(BatchDeleteAo batchDeleteAo);
} }

View File

@ -1,12 +1,17 @@
package com.yfd.platform.qgc_env.wq.service.impl; package com.yfd.platform.qgc_env.wq.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.common.*; import com.yfd.platform.common.*;
import com.yfd.platform.common.exception.BizException; 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_base.entity.vo.BatchDeleteAo; import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo;
import com.yfd.platform.qgc_base.entity.vo.DataParam; 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.wq.entity.vo.*; import com.yfd.platform.qgc_env.wq.entity.vo.*;
import com.yfd.platform.qgc_env.wq.service.EnvWqDataService; import com.yfd.platform.qgc_env.wq.service.EnvWqDataService;
import com.yfd.platform.qgc_env.wt.entity.vo.WbsbVo; import com.yfd.platform.qgc_env.wt.entity.vo.WbsbVo;
@ -36,12 +41,125 @@ import java.util.stream.Collectors;
@Service @Service
public class EnvWqDataServiceImpl implements EnvWqDataService { public class EnvWqDataServiceImpl implements EnvWqDataService {
private static final String WQ_HOUR_TABLE_NAME = "SD_WQ_R";
private static final String WQ_DAY_TABLE_NAME = "SD_WQDAY_S";
private static final String WQ_MONTH_TABLE_NAME = "SD_WQDRTP_S";
private static final String WQ_STATION_TABLE_NAME = "SD_WQ_B_H";
private static final LinkedHashMap<String, String> WQ_UPDATE_COLUMN_MAP = new LinkedHashMap<>();
private static final Map<String, String> WQ_FIELD_MEANING_MAP = new LinkedHashMap<>();
private static final List<String> WQ_SNAPSHOT_COLUMNS = Arrays.asList(
"STCD", "TM", "DT", "DRTP", "YEAR", "MONTH",
"WTMP", "PH", "DOX", "CODMN", "CODCR", "BOD5", "NH3N", "TP", "TN",
"CU", "ZN", "F", "SE", "ARS", "HG", "CD", "CR6", "PB", "CN",
"VLPH", "OIL", "LAS", "S2", "FCG", "CL", "SO4", "NO3", "THRD",
"COND", "FE", "MN", "AL", "CHLA", "CLARITY", "TU", "CYANO",
"WQGRD", "SFDB", "WQ_SFDBHN_YS", "IS_DELETED"
);
static {
WQ_UPDATE_COLUMN_MAP.put("wtmp", "WTMP");
WQ_UPDATE_COLUMN_MAP.put("ph", "PH");
WQ_UPDATE_COLUMN_MAP.put("dox", "DOX");
WQ_UPDATE_COLUMN_MAP.put("codmn", "CODMN");
WQ_UPDATE_COLUMN_MAP.put("codcr", "CODCR");
WQ_UPDATE_COLUMN_MAP.put("bod5", "BOD5");
WQ_UPDATE_COLUMN_MAP.put("nh3n", "NH3N");
WQ_UPDATE_COLUMN_MAP.put("tp", "TP");
WQ_UPDATE_COLUMN_MAP.put("tn", "TN");
WQ_UPDATE_COLUMN_MAP.put("cu", "CU");
WQ_UPDATE_COLUMN_MAP.put("zn", "ZN");
WQ_UPDATE_COLUMN_MAP.put("f", "F");
WQ_UPDATE_COLUMN_MAP.put("se", "SE");
WQ_UPDATE_COLUMN_MAP.put("ars", "ARS");
WQ_UPDATE_COLUMN_MAP.put("hg", "HG");
WQ_UPDATE_COLUMN_MAP.put("cd", "CD");
WQ_UPDATE_COLUMN_MAP.put("cr6", "CR6");
WQ_UPDATE_COLUMN_MAP.put("pb", "PB");
WQ_UPDATE_COLUMN_MAP.put("cn", "CN");
WQ_UPDATE_COLUMN_MAP.put("vlph", "VLPH");
WQ_UPDATE_COLUMN_MAP.put("oil", "OIL");
WQ_UPDATE_COLUMN_MAP.put("las", "LAS");
WQ_UPDATE_COLUMN_MAP.put("s2", "S2");
WQ_UPDATE_COLUMN_MAP.put("fcg", "FCG");
WQ_UPDATE_COLUMN_MAP.put("cl", "CL");
WQ_UPDATE_COLUMN_MAP.put("so4", "SO4");
WQ_UPDATE_COLUMN_MAP.put("no3", "NO3");
WQ_UPDATE_COLUMN_MAP.put("thrd", "THRD");
WQ_UPDATE_COLUMN_MAP.put("cond", "COND");
WQ_UPDATE_COLUMN_MAP.put("fe", "FE");
WQ_UPDATE_COLUMN_MAP.put("mn", "MN");
WQ_UPDATE_COLUMN_MAP.put("al", "AL");
WQ_UPDATE_COLUMN_MAP.put("chla", "CHLA");
WQ_UPDATE_COLUMN_MAP.put("clarity", "CLARITY");
WQ_UPDATE_COLUMN_MAP.put("tu", "TU");
WQ_UPDATE_COLUMN_MAP.put("cyano", "CYANO");
WQ_UPDATE_COLUMN_MAP.put("wqgrd", "WQGRD");
WQ_UPDATE_COLUMN_MAP.put("sfdb", "SFDB");
WQ_UPDATE_COLUMN_MAP.put("wqSfdbhnYs", "WQ_SFDBHN_YS");
WQ_FIELD_MEANING_MAP.put("STCD", "站点编码");
WQ_FIELD_MEANING_MAP.put("TM", "监测时间");
WQ_FIELD_MEANING_MAP.put("DT", "统计日期");
WQ_FIELD_MEANING_MAP.put("DRTP", "统计类型");
WQ_FIELD_MEANING_MAP.put("YEAR", "年份");
WQ_FIELD_MEANING_MAP.put("MONTH", "月份");
WQ_FIELD_MEANING_MAP.put("WTMP", "水温");
WQ_FIELD_MEANING_MAP.put("PH", "酸碱度");
WQ_FIELD_MEANING_MAP.put("DOX", "溶解氧");
WQ_FIELD_MEANING_MAP.put("CODMN", "高锰酸盐指数");
WQ_FIELD_MEANING_MAP.put("CODCR", "化学需氧量");
WQ_FIELD_MEANING_MAP.put("BOD5", "五日生化需氧量");
WQ_FIELD_MEANING_MAP.put("NH3N", "氨氮");
WQ_FIELD_MEANING_MAP.put("TP", "总磷");
WQ_FIELD_MEANING_MAP.put("TN", "总氮");
WQ_FIELD_MEANING_MAP.put("CU", "");
WQ_FIELD_MEANING_MAP.put("ZN", "");
WQ_FIELD_MEANING_MAP.put("F", "氟化物");
WQ_FIELD_MEANING_MAP.put("SE", "");
WQ_FIELD_MEANING_MAP.put("ARS", "");
WQ_FIELD_MEANING_MAP.put("HG", "");
WQ_FIELD_MEANING_MAP.put("CD", "");
WQ_FIELD_MEANING_MAP.put("CR6", "六价铬");
WQ_FIELD_MEANING_MAP.put("PB", "");
WQ_FIELD_MEANING_MAP.put("CN", "氰化物");
WQ_FIELD_MEANING_MAP.put("VLPH", "挥发酚");
WQ_FIELD_MEANING_MAP.put("OIL", "石油类");
WQ_FIELD_MEANING_MAP.put("LAS", "阴离子表面活性剂");
WQ_FIELD_MEANING_MAP.put("S2", "硫化物");
WQ_FIELD_MEANING_MAP.put("FCG", "粪大肠菌群");
WQ_FIELD_MEANING_MAP.put("CL", "氯化物");
WQ_FIELD_MEANING_MAP.put("SO4", "硫酸盐");
WQ_FIELD_MEANING_MAP.put("NO3", "硝酸盐");
WQ_FIELD_MEANING_MAP.put("THRD", "总硬度");
WQ_FIELD_MEANING_MAP.put("COND", "电导率");
WQ_FIELD_MEANING_MAP.put("FE", "");
WQ_FIELD_MEANING_MAP.put("MN", "");
WQ_FIELD_MEANING_MAP.put("AL", "");
WQ_FIELD_MEANING_MAP.put("CHLA", "叶绿素a");
WQ_FIELD_MEANING_MAP.put("CLARITY", "透明度");
WQ_FIELD_MEANING_MAP.put("TU", "浊度");
WQ_FIELD_MEANING_MAP.put("CYANO", "蓝绿藻");
WQ_FIELD_MEANING_MAP.put("WQGRD", "水质类别");
WQ_FIELD_MEANING_MAP.put("WWQTG", "水功能区目标");
WQ_FIELD_MEANING_MAP.put("SFDB", "是否达标");
WQ_FIELD_MEANING_MAP.put("WQ_SFDBHN_YS", "是否达标湖内饮用水源");
WQ_FIELD_MEANING_MAP.put("ROW_KEY", "删除记录标识");
WQ_FIELD_MEANING_MAP.put("ROW_DATA", "删除记录数据");
}
@Resource @Resource
private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; private MicroservicDynamicSQLMapper microservicDynamicSQLMapper;
@Resource @Resource
private JdbcTemplate jdbcTemplate; private JdbcTemplate jdbcTemplate;
@Resource
private MsOperationLogMapper msOperationLogMapper;
@Resource
private MsOperationLogDetailMapper msOperationLogDetailMapper;
@Override @Override
public DataSourceResult processKendoList(DataSourceRequest dataSourceRequest) { public DataSourceResult processKendoList(DataSourceRequest dataSourceRequest) {
boolean calculated = CommonConstant.CALCULATE_SUCCESS.equals( boolean calculated = CommonConstant.CALCULATE_SUCCESS.equals(
@ -3671,15 +3789,18 @@ public class EnvWqDataServiceImpl implements EnvWqDataService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean updateWqRsData(Map<String, Object> updateData) { public boolean updateWqRsData(Map<String, Object> updateData, String source) {
if (updateData == null || updateData.isEmpty()) { if (updateData == null || updateData.isEmpty()) {
return true; return true;
} }
updateWqHourData(updateData);
updateWqTargetIfNeeded(updateData);
String stcd = asString(updateData.get("stcd")); String stcd = asString(updateData.get("stcd"));
String tm = asString(updateData.get("tm")); String tm = asString(updateData.get("tm"));
Map<String, Object> beforeHour = queryWqHourRow(stcd, tm);
Map<String, Object> beforeStation = queryWqStationRow(stcd);
updateWqHourData(updateData);
updateWqTargetIfNeeded(updateData);
recordWqUpdateLog(beforeHour, beforeStation, updateData, source);
if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm) && tm.length() >= 10) { if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm) && tm.length() >= 10) {
String dateStr = tm.substring(0, 10); String dateStr = tm.substring(0, 10);
statisticsDayDataFromHour(stcd, dateStr, dateStr); statisticsDayDataFromHour(stcd, dateStr, dateStr);
@ -3704,17 +3825,24 @@ public class EnvWqDataServiceImpl implements EnvWqDataService {
return true; return true;
} }
String dataType = StrUtil.blankToDefault(batchDeleteAo.getDataType(), "").toUpperCase(); String dataType = StrUtil.blankToDefault(batchDeleteAo.getDataType(), "").toUpperCase();
String source = batchDeleteAo == null ? null : batchDeleteAo.getSource();
int batchSize = 500; int batchSize = 500;
for (int i = 0; i < dataList.size(); i += batchSize) { for (int i = 0; i < dataList.size(); i += batchSize) {
List<DataParam> subList = dataList.subList(i, Math.min(i + batchSize, dataList.size())); List<DataParam> subList = dataList.subList(i, Math.min(i + batchSize, dataList.size()));
if ("MON".equals(dataType)) { if ("MON".equals(dataType)) {
List<Map<String, Object>> beforeRows = queryWqMonthRows(subList);
softDeleteWqMonthData(subList); softDeleteWqMonthData(subList);
recordWqDeleteLog(beforeRows, WQ_MONTH_TABLE_NAME, "删除水质月数据", source);
} }
if ("DATE".equals(dataType)) { if ("DATE".equals(dataType)) {
List<Map<String, Object>> beforeRows = queryWqDayRows(subList);
softDeleteWqDayData(subList); softDeleteWqDayData(subList);
recordWqDeleteLog(beforeRows, WQ_DAY_TABLE_NAME, "删除水质日数据", source);
} }
if ("TIME".equals(dataType)) { if ("TIME".equals(dataType)) {
List<Map<String, Object>> beforeRows = queryWqHourRows(subList);
deleteWqHourData(subList); deleteWqHourData(subList);
recordWqDeleteLog(beforeRows, WQ_HOUR_TABLE_NAME, "删除水质小时数据", source);
Map<String, String[]> dateRangeMap = new HashMap<>(); Map<String, String[]> dateRangeMap = new HashMap<>();
Map<String, String[]> monthRangeMap = new HashMap<>(); Map<String, String[]> monthRangeMap = new HashMap<>();
@ -3765,50 +3893,9 @@ public class EnvWqDataServiceImpl implements EnvWqDataService {
} }
private void updateWqHourData(Map<String, Object> updateData) { private void updateWqHourData(Map<String, Object> updateData) {
LinkedHashMap<String, String> columnMap = new LinkedHashMap<>();
columnMap.put("wtmp", "WTMP");
columnMap.put("ph", "PH");
columnMap.put("dox", "DOX");
columnMap.put("codmn", "CODMN");
columnMap.put("codcr", "CODCR");
columnMap.put("bod5", "BOD5");
columnMap.put("nh3n", "NH3N");
columnMap.put("tp", "TP");
columnMap.put("tn", "TN");
columnMap.put("cu", "CU");
columnMap.put("zn", "ZN");
columnMap.put("f", "F");
columnMap.put("se", "SE");
columnMap.put("ars", "ARS");
columnMap.put("hg", "HG");
columnMap.put("cd", "CD");
columnMap.put("cr6", "CR6");
columnMap.put("pb", "PB");
columnMap.put("cn", "CN");
columnMap.put("vlph", "VLPH");
columnMap.put("oil", "OIL");
columnMap.put("las", "LAS");
columnMap.put("s2", "S2");
columnMap.put("fcg", "FCG");
columnMap.put("cl", "CL");
columnMap.put("so4", "SO4");
columnMap.put("no3", "NO3");
columnMap.put("thrd", "THRD");
columnMap.put("cond", "COND");
columnMap.put("fe", "FE");
columnMap.put("mn", "MN");
columnMap.put("al", "AL");
columnMap.put("chla", "CHLA");
columnMap.put("clarity", "CLARITY");
columnMap.put("tu", "TU");
columnMap.put("cyano", "CYANO");
columnMap.put("wqgrd", "WQGRD");
columnMap.put("sfdb", "SFDB");
columnMap.put("wqSfdbhnYs", "WQ_SFDBHN_YS");
List<String> setClauses = new ArrayList<>(); List<String> setClauses = new ArrayList<>();
List<Object> params = new ArrayList<>(); List<Object> params = new ArrayList<>();
for (Map.Entry<String, String> entry : columnMap.entrySet()) { for (Map.Entry<String, String> entry : WQ_UPDATE_COLUMN_MAP.entrySet()) {
if (updateData.containsKey(entry.getKey())) { if (updateData.containsKey(entry.getKey())) {
setClauses.add(entry.getValue() + " = ?"); setClauses.add(entry.getValue() + " = ?");
params.add(updateData.get(entry.getKey())); params.add(updateData.get(entry.getKey()));
@ -3909,6 +3996,296 @@ public class EnvWqDataServiceImpl implements EnvWqDataService {
jdbcTemplate.update(sql.toString(), params.toArray()); jdbcTemplate.update(sql.toString(), params.toArray());
} }
private Map<String, Object> queryWqHourRow(String stcd, String tm) {
if (StrUtil.isBlank(stcd) || StrUtil.isBlank(tm)) {
return new HashMap<>();
}
String sql = "SELECT " + buildWqHourLogSelectColumns() +
" FROM SD_WQ_R WHERE STCD = ? AND TM = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS')";
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, stcd, tm);
return rows.isEmpty() ? new HashMap<>() : normalizeLogRow(rows.getFirst());
}
private Map<String, Object> queryWqStationRow(String stcd) {
if (StrUtil.isBlank(stcd)) {
return new HashMap<>();
}
String sql = "SELECT STCD, WWQTG FROM SD_WQ_B_H WHERE STCD = ? AND NVL(IS_DELETED, 0) = 0";
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, stcd);
return rows.isEmpty() ? new HashMap<>() : normalizeLogRow(rows.getFirst());
}
private List<Map<String, Object>> queryWqHourRows(List<DataParam> dataParamList) {
if (CollUtil.isEmpty(dataParamList)) {
return new ArrayList<>();
}
StringBuilder sql = new StringBuilder("SELECT ")
.append(buildWqHourLogSelectColumns())
.append(" FROM SD_WQ_R WHERE ");
List<Object> params = new ArrayList<>();
appendHourRowConditions(sql, params, dataParamList);
return normalizeLogRows(jdbcTemplate.queryForList(sql.toString(), params.toArray()));
}
private List<Map<String, Object>> queryWqDayRows(List<DataParam> dataParamList) {
if (CollUtil.isEmpty(dataParamList)) {
return new ArrayList<>();
}
StringBuilder sql = new StringBuilder("SELECT ")
.append(buildWqDayLogSelectColumns())
.append(" FROM SD_WQDAY_S WHERE ");
List<Object> params = new ArrayList<>();
for (int i = 0; i < dataParamList.size(); i++) {
if (i > 0) {
sql.append(" OR ");
}
sql.append("(STCD = ? AND DT = 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 normalizeLogRows(jdbcTemplate.queryForList(sql.toString(), params.toArray()));
}
private List<Map<String, Object>> queryWqMonthRows(List<DataParam> dataParamList) {
if (CollUtil.isEmpty(dataParamList)) {
return new ArrayList<>();
}
StringBuilder sql = new StringBuilder("SELECT ")
.append(buildWqMonthLogSelectColumns())
.append(" FROM SD_WQDRTP_S WHERE ");
List<Object> params = new ArrayList<>();
for (int i = 0; i < dataParamList.size(); i++) {
if (i > 0) {
sql.append(" OR ");
}
sql.append("(STCD = ? AND DRTP = ? AND YEAR = ? AND MONTH = ?)");
DataParam item = dataParamList.get(i);
params.add(item == null ? null : item.getId());
params.add(item == null ? null : item.getDrtp());
params.add(item == null ? null : item.getYear());
params.add(item == null ? null : item.getMonth());
}
return normalizeLogRows(jdbcTemplate.queryForList(sql.toString(), params.toArray()));
}
private void appendHourRowConditions(StringBuilder sql, List<Object> params, List<DataParam> dataParamList) {
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.getTm());
}
}
private String buildWqHourLogSelectColumns() {
return "STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, " +
"WTMP, PH, DOX, CODMN, CODCR, BOD5, NH3N, TP, TN, CU, ZN, F, SE, ARS, HG, CD, CR6, PB, CN, " +
"VLPH, OIL, LAS, S2, FCG, CL, SO4, NO3, THRD, COND, FE, MN, AL, CHLA, CLARITY, TU, CYANO, " +
"WQGRD, SFDB, WQ_SFDBHN_YS";
}
private String buildWqDayLogSelectColumns() {
return "STCD, TO_CHAR(DT, 'YYYY-MM-DD HH24:MI:SS') AS DT, " +
"WTMP, PH, DOX, CODMN, CODCR, BOD5, NH3N, TP, TN, CU, ZN, F, SE, ARS, HG, CD, CR6, PB, CN, " +
"VLPH, OIL, LAS, S2, FCG, CL, SO4, NO3, THRD, COND, FE, MN, AL, CHLA, CLARITY, TU, CYANO, " +
"WQGRD, SFDB, IS_DELETED";
}
private String buildWqMonthLogSelectColumns() {
return "STCD, DRTP, YEAR, MONTH, " +
"WTMP, PH, DOX, CODMN, CODCR, BOD5, NH3N, TP, TN, CU, ZN, F, SE, ARS, HG, CD, CR6, PB, CN, " +
"VLPH, OIL, LAS, S2, FCG, CL, SO4, NO3, THRD, COND, FE, MN, AL, CHLA, CLARITY, TU, CYANO, " +
"WQGRD, SFDB, IS_DELETED";
}
private List<Map<String, Object>> normalizeLogRows(List<Map<String, Object>> rows) {
List<Map<String, Object>> result = new ArrayList<>();
if (CollUtil.isEmpty(rows)) {
return result;
}
for (Map<String, Object> row : rows) {
result.add(normalizeLogRow(row));
}
return result;
}
private Map<String, Object> normalizeLogRow(Map<String, Object> row) {
Map<String, Object> normalized = new LinkedHashMap<>();
if (row == null || row.isEmpty()) {
return normalized;
}
for (Map.Entry<String, Object> entry : row.entrySet()) {
normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue());
}
return normalized;
}
private void recordWqUpdateLog(Map<String, Object> beforeHour,
Map<String, Object> beforeStation,
Map<String, Object> updateData,
String source) {
if (updateData == null || updateData.isEmpty()) {
return;
}
String stcd = asString(updateData.get("stcd"));
List<MsOperationLogDetail> details = new ArrayList<>();
for (Map.Entry<String, String> entry : WQ_UPDATE_COLUMN_MAP.entrySet()) {
if (!updateData.containsKey(entry.getKey())) {
continue;
}
String column = entry.getValue();
Object oldValue = beforeHour == null ? null : beforeHour.get(column);
Object newValue = updateData.get(entry.getKey());
if (StrUtil.equals(formatLogValue(oldValue), formatLogValue(newValue))) {
continue;
}
details.add(buildWqDetail(null, WQ_HOUR_TABLE_NAME, stcd, column,
oldValue, resolveWqDisplayValue(column, oldValue),
newValue, resolveWqDisplayValue(column, newValue), "修改字段值"));
}
if (updateData.containsKey("wwqtg")) {
Object oldValue = beforeStation == null ? null : beforeStation.get("WWQTG");
Object newValue = updateData.get("wwqtg");
if (!StrUtil.equals(formatLogValue(oldValue), formatLogValue(newValue))) {
details.add(buildWqDetail(null, WQ_STATION_TABLE_NAME, stcd, "WWQTG",
oldValue, resolveWqDisplayValue("WWQTG", oldValue),
newValue, resolveWqDisplayValue("WWQTG", newValue), "修改字段值"));
}
}
if (details.isEmpty()) {
return;
}
MsOperationLog mainLog = buildWqMainLog("修改水质小时数据", source);
msOperationLogMapper.insert(mainLog);
for (MsOperationLogDetail detail : details) {
detail.setMainId(mainLog.getId());
}
batchInsertWqLogDetails(details);
}
private void recordWqDeleteLog(List<Map<String, Object>> rows, String tableName, String remark, String source) {
if (CollUtil.isEmpty(rows)) {
return;
}
MsOperationLog mainLog = buildWqMainLog(remark, source);
msOperationLogMapper.insert(mainLog);
List<MsOperationLogDetail> details = new ArrayList<>();
for (Map<String, Object> row : rows) {
String stcd = asString(row.get("STCD"));
String rowKey = buildWqRowKey(tableName, row);
String rowSnapshot = buildWqRowSnapshot(row);
details.add(buildWqDetail(mainLog.getId(), tableName, stcd, "ROW_KEY",
rowKey, rowKey, null, null, "删除记录"));
details.add(buildWqDetail(mainLog.getId(), tableName, stcd, "ROW_DATA",
rowSnapshot, rowSnapshot, null, null, "删除记录"));
}
batchInsertWqLogDetails(details);
}
private MsOperationLog buildWqMainLog(String remark, String source) {
MsOperationLog log = new MsOperationLog();
log.setOperator(resolveLogOperator());
log.setOperateTime(new Date());
log.setSource(StrUtil.trimToNull(source));
log.setRemark(remark);
return log;
}
private MsOperationLogDetail buildWqDetail(String mainId,
String tableName,
String stationCode,
String fieldCode,
Object oldValueCode,
Object oldValueName,
Object newValueCode,
Object newValueName,
String remark) {
MsOperationLogDetail detail = new MsOperationLogDetail();
detail.setMainId(mainId);
detail.setTableName(tableName);
detail.setStationCode(stationCode);
detail.setFieldCode(fieldCode);
detail.setFieldMeaning(WQ_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode));
detail.setOldValueCode(formatLogValue(oldValueCode));
detail.setOldValueName(formatLogValue(oldValueName));
detail.setNewValueCode(formatLogValue(newValueCode));
detail.setNewValueName(formatLogValue(newValueName));
detail.setRemark(remark);
return detail;
}
private void batchInsertWqLogDetails(List<MsOperationLogDetail> details) {
if (CollUtil.isEmpty(details)) {
return;
}
msOperationLogDetailMapper.insert(details);
}
private String buildWqRowKey(String tableName, Map<String, Object> row) {
if (WQ_HOUR_TABLE_NAME.equals(tableName)) {
return "STCD=" + formatLogValue(row.get("STCD")) + ", TM=" + formatLogValue(row.get("TM"));
}
if (WQ_DAY_TABLE_NAME.equals(tableName)) {
return "STCD=" + formatLogValue(row.get("STCD")) + ", DT=" + formatLogValue(row.get("DT"));
}
return "STCD=" + formatLogValue(row.get("STCD")) + ", DRTP=" + formatLogValue(row.get("DRTP")) +
", YEAR=" + formatLogValue(row.get("YEAR")) + ", MONTH=" + formatLogValue(row.get("MONTH"));
}
private String buildWqRowSnapshot(Map<String, Object> row) {
if (row == null || row.isEmpty()) {
return null;
}
List<String> parts = new ArrayList<>();
for (String column : WQ_SNAPSHOT_COLUMNS) {
Object value = row.get(column);
String text = formatLogValue(value);
if (StrUtil.isBlank(text)) {
continue;
}
parts.add(column + "=" + text);
}
return parts.isEmpty() ? null : String.join("; ", parts);
}
private Object resolveWqDisplayValue(String fieldCode, Object rawValue) {
String text = formatLogValue(rawValue);
if (StrUtil.isBlank(text)) {
return rawValue;
}
return switch (fieldCode) {
case "WQGRD", "WWQTG" -> getWqLevelName(text);
case "SFDB" -> parseInteger(text) == null ? text : getSfdbName(parseInteger(text));
default -> text;
};
}
private String resolveLogOperator() {
try {
return SecurityUtils.getCurrentUsername();
} catch (Exception ignored) {
try {
return SecurityUtils.getUserId();
} catch (Exception ex) {
return null;
}
}
}
private String formatLogValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Date date) {
return DateUtil.formatDateTime(date);
}
return String.valueOf(value);
}
private String getMonthEndDate(Integer year, Integer month) { private String getMonthEndDate(Integer year, Integer month) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.set(year, month - 1, 1); calendar.set(year, month - 1, 1);