fix: 优化日志查询bug

This commit is contained in:
tangwei 2026-08-11 09:07:05 +08:00
parent e3e3bd3c88
commit 13d0c52a84
3 changed files with 127 additions and 1 deletions

View File

@ -39,4 +39,10 @@ public class MsOperationLog implements Serializable {
@TableField("OPERATION_TYPE")
private String operationType;
/**
* 操作记录的名称瞬态字段不持久化由后端查询后填充
*/
@TableField(exist = false)
private String recordName;
}

View File

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.annotation.FieldChinese;
import com.yfd.platform.common.DataSourceRequest;
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.domain.SdEngInfoBH;
@ -20,6 +21,7 @@ import com.yfd.platform.utils.CodeToNameMetadataBo;
import com.yfd.platform.utils.DataSourceRequestUtil;
import com.yfd.platform.utils.SecurityUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -32,11 +34,28 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Slf4j
@Service
public class MsOperationLogServiceImpl extends ServiceImpl<MsOperationLogMapper, MsOperationLog> implements IMsOperationLogService {
private static final String ENG_TABLE_NAME = "SD_ENGINFO_B_H";
/**
* 表名 (主键列, 名称列) 配置映射
* 默认主键列 = STCD名称列 = STNM无需显式配置
* 仅在主键列或名称列与默认不同的情况下才需配置
*/
private record TableNameConfig(String pkColumn, String nameColumn) {}
private static final Map<String, TableNameConfig> TABLE_NAME_CONFIG_MAP = new HashMap<>();
static {
// Engine Info: 名称列是 ENNM 而非 STNM
TABLE_NAME_CONFIG_MAP.put("SD_ENGINFO_B_H", new TableNameConfig("STCD", "ENNM"));
// Hydro Base: 主键列是 BASEID名称列是 BASENAME
TABLE_NAME_CONFIG_MAP.put("SD_HYDROBASE", new TableNameConfig("BASEID", "BASENAME"));
// Fish Dictionary: 需确认结构后配置
TABLE_NAME_CONFIG_MAP.put("SD_FISHDICTORY_B", new TableNameConfig("ID", "NAME"));
}
private static final Map<String, String> ENG_FIELD_MEANING_MAP = new LinkedHashMap<>();
// 标准日期时间格式器
private static final DateTimeFormatter DATETIME_FORMATTER =
@ -282,6 +301,9 @@ public class MsOperationLogServiceImpl extends ServiceImpl<MsOperationLogMapper,
@Resource
private MsOperationLogDetailMapper msOperationLogDetailMapper;
@Resource
private MicroservicDynamicSQLMapper microservicDynamicSQLMapper;
@Override
public void recordEngAddLog(SdEngInfoBH engInfo, String source) {
if (engInfo == null) {
@ -936,9 +958,107 @@ public class MsOperationLogServiceImpl extends ServiceImpl<MsOperationLogMapper,
@Override
public Page<MsOperationLog> queryPageList(DataSourceRequest request) {
Page<MsOperationLog> msOperationLogPage = DataSourceRequestUtil.executeQuery(request, MsOperationLog.class, this);
// 批量解析操作记录名称
batchResolveRecordNames(msOperationLogPage.getRecords());
return msOperationLogPage;
}
/**
* 批量解析操作记录的名称
* tableName 分组后每张表一次批量查询名称
*/
private void batchResolveRecordNames(List<MsOperationLog> records) {
if (records == null || records.isEmpty()) {
return;
}
// tableName 分组收集 recordId
Map<String, List<String>> tableRecordIdsMap = new LinkedHashMap<>();
for (MsOperationLog log : records) {
if (StrUtil.isNotBlank(log.getTableName()) && StrUtil.isNotBlank(log.getRecordId())) {
tableRecordIdsMap.computeIfAbsent(log.getTableName(), k -> new ArrayList<>())
.add(log.getRecordId());
}
}
// 每个表批量查询名称
for (Map.Entry<String, List<String>> entry : tableRecordIdsMap.entrySet()) {
String tableName = entry.getKey();
List<String> recordIds = entry.getValue();
if (recordIds.isEmpty()) {
continue;
}
// 获取表配置
TableNameConfig config = TABLE_NAME_CONFIG_MAP.get(tableName);
String pkColumn;
String nameColumn;
if (config != null) {
pkColumn = config.pkColumn();
nameColumn = config.nameColumn();
} else {
// 默认主键列 = STCD名称列 = STNM
pkColumn = "STCD";
nameColumn = "STNM";
}
// 去重后构建 IN 参数
Set<String> distinctIds = new LinkedHashSet<>(recordIds);
Map<String, Object> paramMap = new HashMap<>();
String inPlaceholders = buildInPlaceholders(distinctIds, paramMap);
// 注意如果配置的表在数据库中不存在跳过
try {
String sql = "SELECT " + pkColumn + " AS pkVal, " + nameColumn + " AS nameVal " +
"FROM " + tableName +
" WHERE " + pkColumn + " IN (" + inPlaceholders + ")" +
" AND NVL(IS_DELETED, 0) = 0";
List<Map<String, Object>> results = microservicDynamicSQLMapper.getAllList(sql, paramMap);
// 构建 pkVal nameVal 映射
Map<String, String> nameMap = new HashMap<>();
for (Map<String, Object> row : results) {
Object pkObj = row.get("PKVAL");
Object nameObj = row.get("NAMEVAL");
if (pkObj != null && nameObj != null) {
nameMap.put(String.valueOf(pkObj), String.valueOf(nameObj));
}
}
// 回填 recordName
for (MsOperationLog log : records) {
if (tableName.equals(log.getTableName())) {
String name = nameMap.get(log.getRecordId());
if (name != null) {
log.setRecordName(name);
}
}
}
} catch (Exception e) {
// 表不存在或查询失败时静默跳过
log.warn("批量解析记录名称失败, tableName={}", tableName, e);
}
}
}
/**
* 构建 IN 子句占位符 #{map.p0}, #{map.p1}, ...
*/
private String buildInPlaceholders(Set<String> ids, Map<String, Object> paramMap) {
StringBuilder sb = new StringBuilder();
int i = 0;
for (String id : ids) {
if (i > 0) {
sb.append(", ");
}
String key = "p" + i;
sb.append("#{map.").append(key).append("}");
paramMap.put(key, id);
i++;
}
return sb.toString();
}
@Override
public List<MsOperationLogDetail> getDetailByMainId(String mainId) {
if (StringUtils.isBlank(mainId)) {

View File

@ -53,7 +53,7 @@ import java.util.stream.Collectors;
*/
@Service
public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEngInfoBH> implements ISdEngInfoBHService {
private static final String TABLE_NAME = "SD_FISHDICTORY_B";
private static final String TABLE_NAME = "SD_ENGINFO_B_H";
private static final Map<String, String> ENG_CODE_NAME_FIELD_MAP = new LinkedHashMap<>();
@Resource
private RedisCacheUtil redisCacheUtil;