fix: 优化逻辑

This commit is contained in:
tangwei 2026-06-22 10:33:08 +08:00
parent 675d6a1927
commit 970de33016
2 changed files with 158 additions and 80 deletions

View File

@ -45,4 +45,5 @@ public class FprZyFishDicVo {
private String spawnMonth; private String spawnMonth;
private String orders; private String orders;
private String vlsr; private String vlsr;
private java.util.Date vlsrTm;
} }

View File

@ -250,87 +250,33 @@ public class FprMonitorServiceImpl implements FprMonitorService {
new int[]{0} new int[]{0}
); );
String baseSql = StrUtil.isBlank(rvcd) ? buildZyFishDicSummarySql() : buildZyFishDicBaseSql();
StringBuilder sql = new StringBuilder("SELECT * FROM (") StringBuilder sql = new StringBuilder("SELECT * FROM (")
.append(buildZyFishDicBaseSql()) .append(baseSql)
.append(") t WHERE 1 = 1 "); .append(") t WHERE 1 = 1 ");
if (StrUtil.isNotBlank(filterSql)) { if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" "); sql.append(" AND ").append(filterSql).append(" ");
} }
// 增加排序 sql.append(buildZyFishDicOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
if(dataSourceRequest.getSort() !=null && !dataSourceRequest.getSort().isEmpty()){ Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
List<DataSourceRequest.SortDescriptor> sortDescriptors = dataSourceRequest.getSort(); List<FprZyFishDicVo> resultList = microservicDynamicSQLMapper.pageAllListWithResultType(
StringBuilder orderSql = new StringBuilder(); page,
orderSql.append(" order by ");
for (DataSourceRequest.SortDescriptor sort:sortDescriptors){
orderSql.append(sort.getField()).append(" ").append(sort.getDir()).append(",");
}
sql.append(orderSql, 0, orderSql.length()-1);
// String[] beans = SpringContextHolder.getApplicationContext().getBeanDefinitionNames();
sql.append(" nulls last ");
}else{
sql.append(" order by rvcd nulls last ");
}
List<FprZyFishDicVo> list = microservicDynamicSQLMapper.getAllListWithResultType(
sql.toString(), sql.toString(),
paramMap, paramMap,
FprZyFishDicVo.class FprZyFishDicVo.class
); );
List<Map<String, Object>> rvcdRows = microservicDynamicSQLMapper.getAllList(
"SELECT RVCD AS rvcd, RVNM AS rvcdName FROM SD_RVCD_DIC",
null
);
Map<String, String> rvcdNameMap = new HashMap<>();
for (Map<String, Object> row : rvcdRows) {
Object rvcdKey = row.get("RVCD");
Object rvcdName = row.get("RVCDNAME");
if (rvcdKey != null && rvcdName != null) {
rvcdNameMap.put(String.valueOf(rvcdKey), String.valueOf(rvcdName));
}
}
List<FprZyFishDicVo> resultList;
Map<String, List<String>> rvcdMap = new HashMap<>();
if (StrUtil.isBlank(rvcd)) {
rvcdMap = list.stream()
.collect(Collectors.groupingBy(
item -> StrUtil.blankToDefault(item.getZyFishId(), item.getId()),
LinkedHashMap::new,
Collectors.mapping(FprZyFishDicVo::getRvcd, Collectors.toList())
));
LinkedHashMap<String, FprZyFishDicVo> distinctMap = new LinkedHashMap<>();
for (FprZyFishDicVo item : list) {
distinctMap.putIfAbsent(StrUtil.blankToDefault(item.getZyFishId(), item.getId()), item);
}
resultList = new ArrayList<>(distinctMap.values());
} else {
resultList = new ArrayList<>(list);
}
int startIndex = loadOptions == null || loadOptions.getSkip() == null ? 0 : Math.max(loadOptions.getSkip(), 0);
fillZyFishRvcdNames(resultList, rvcd);
for (int i = 0; i < resultList.size(); i++) { for (int i = 0; i < resultList.size(); i++) {
FprZyFishDicVo item = resultList.get(i); FprZyFishDicVo item = resultList.get(i);
item.setIndex(i + 1); item.setIndex(startIndex + i + 1);
item.setSpawnMonth(formatSpawnMonth(item.getSpawnMonth())); item.setSpawnMonth(formatSpawnMonth(item.getSpawnMonth()));
if (StrUtil.isBlank(rvcd)) {
List<String> rvcdList = rvcdMap.getOrDefault(
StrUtil.blankToDefault(item.getZyFishId(), item.getId()),
new ArrayList<>()
).stream().filter(StrUtil::isNotBlank).distinct().toList();
List<String> rvcdNames = new ArrayList<>();
for (String rvcdItem : rvcdList) {
String rvcdName = rvcdNameMap.get(rvcdItem);
if (StrUtil.isNotBlank(rvcdName)) {
rvcdNames.add(rvcdName);
}
}
item.setRvcdName(String.join(",", rvcdNames));
} else {
item.setRvcdName(rvcdNameMap.get(item.getRvcd()));
}
} }
DataSourceResult<FprZyFishDicVo> result = new DataSourceResult<>(); DataSourceResult<FprZyFishDicVo> result = new DataSourceResult<>();
result.setTotal((long) resultList.size()); result.setTotal(page != null ? page.getTotal() : resultList.size());
result.setData(paginateZyFishDicList(resultList, loadOptions)); result.setData(resultList);
result.setAggregates(new HashMap<>()); result.setAggregates(new HashMap<>());
return result; return result;
} }
@ -739,6 +685,7 @@ public class FprMonitorServiceImpl implements FprMonitorService {
"NVL(src.IS_DELETED, 0) AS isDeleted, " + "NVL(src.IS_DELETED, 0) AS isDeleted, " +
"CASE WHEN rel.ZY_FISH_ID IS NULL THEN src.ID ELSE rel.ZY_FISH_ID END AS zyFishId, " + "CASE WHEN rel.ZY_FISH_ID IS NULL THEN src.ID ELSE rel.ZY_FISH_ID END AS zyFishId, " +
"CASE WHEN rel.RVCD IS NULL THEN 'null' ELSE rel.RVCD END AS rvcd, " + "CASE WHEN rel.RVCD IS NULL THEN 'null' ELSE rel.RVCD END AS rvcd, " +
"rv.RVNM AS rvcdName, " +
"src.NAME AS name, " + "src.NAME AS name, " +
"src.TYPE AS type, " + "src.TYPE AS type, " +
"src.FAMILY AS family, " + "src.FAMILY AS family, " +
@ -769,15 +716,137 @@ public class FprMonitorServiceImpl implements FprMonitorService {
"src.LOGO AS logo, " + "src.LOGO AS logo, " +
"src.INFFILE AS inffile, " + "src.INFFILE AS inffile, " +
"src.ORDERS, \n" + "src.ORDERS, \n" +
"src.VLSR, \n"+ "src.VLSR AS vlsr, \n" +
"src.VLSR_TM AS vlsrTm, \n" +
"src.SPAWN_MONTH AS spawnMonth " + "src.SPAWN_MONTH AS spawnMonth " +
"FROM SD_FISHDICTORY_B src " + "FROM SD_FISHDICTORY_B src " +
"LEFT JOIN SD_FISHDICTORY_RLTN_B rel ON src.ID = rel.ZY_FISH_ID " + "LEFT JOIN SD_FISHDICTORY_RLTN_B rel ON src.ID = rel.ZY_FISH_ID " +
" AND rel.RVCD <> 'ZY' " + " AND rel.RVCD <> 'ZY' " +
" AND NVL(rel.IS_DELETED, 0) = 0 " + " AND NVL(rel.IS_DELETED, 0) = 0 " +
"LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = rel.RVCD " +
"WHERE NVL(src.IS_DELETED, 0) = 0 "; "WHERE NVL(src.IS_DELETED, 0) = 0 ";
} }
private String buildZyFishDicSummarySql() {
return "SELECT " +
"src.ID AS id, " +
"NVL(src.IS_DELETED, 0) AS isDeleted, " +
"src.ID AS zyFishId, " +
"NVL((SELECT MIN(rel2.RVCD) " +
" FROM SD_FISHDICTORY_RLTN_B rel2 " +
" WHERE rel2.ZY_FISH_ID = src.ID " +
" AND rel2.RVCD <> 'ZY' " +
" AND NVL(rel2.IS_DELETED, 0) = 0), 'null') AS rvcd, " +
"CAST(NULL AS VARCHAR2(1000)) AS rvcdName, " +
"src.NAME AS name, " +
"src.TYPE AS type, " +
"src.FAMILY AS family, " +
"src.GENUS AS genus, " +
"src.SPECIES AS species, " +
"src.NAME_EN AS nameEn, " +
"src.ALIAS AS alias, " +
"src.FSZ AS fsz, " +
"src.SHAPEDESC AS shapedesc, " +
"src.HABITATION AS habitation, " +
"src.HABIT_MIGRAT AS habitMigrat, " +
"src.FEEDING_HABIT AS feedingHabit, " +
"src.FOOD AS food, " +
"src.TIME_FEED AS timeFeed, " +
"src.ORIGN_DATE AS orignDate, " +
"CAST(NULL AS VARCHAR2(255)) AS filterContent, " +
"src.PRETEMP AS pretemp, " +
"src.FLOW_RATE AS flowRate, " +
"src.DEPTH AS depth, " +
"src.WQTQ AS wqtq, " +
"src.SPAWN_CHARACT AS spawnCharact, " +
"src.BOTM_MATER AS botmMater, " +
"src.PTYPE AS ptype, " +
"CASE src.PTYPE WHEN 1 THEN '濒危' WHEN 2 THEN '极危' WHEN 3 THEN '近危' WHEN 4 THEN '易危' WHEN 5 THEN '重点保护' WHEN 6 THEN '无危' WHEN 7 THEN '国家二级' WHEN 8 THEN '市二级保护' ELSE '未知' END AS ptypeName, " +
"src.SPEC_ORIGIN AS specOrigin, " +
"CASE WHEN src.SPEC_ORIGIN = 1 THEN '本土物种' WHEN src.SPEC_ORIGIN = 2 THEN '外来物种' ELSE NULL END AS specOriginName, " +
"src.DESCRIPTION AS description, " +
"src.LOGO AS logo, " +
"src.INFFILE AS inffile, " +
"src.ORDERS, " +
"src.VLSR AS vlsr, " +
"src.VLSR_TM AS vlsrTm, " +
"src.SPAWN_MONTH AS spawnMonth " +
"FROM SD_FISHDICTORY_B src " +
"WHERE NVL(src.IS_DELETED, 0) = 0 ";
}
private void fillZyFishRvcdNames(List<FprZyFishDicVo> list, String rvcdFilter) {
if (CollUtil.isEmpty(list)) {
return;
}
if (StrUtil.isNotBlank(rvcdFilter)) {
for (FprZyFishDicVo item : list) {
if (item != null && StrUtil.isBlank(item.getRvcdName()) && StrUtil.isNotBlank(item.getRvcd()) && !"null".equalsIgnoreCase(item.getRvcd())) {
item.setRvcdName(querySingleRvcdName(item.getRvcd()));
}
}
return;
}
List<String> fishIds = list.stream()
.map(item -> StrUtil.blankToDefault(item.getZyFishId(), item.getId()))
.filter(StrUtil::isNotBlank)
.distinct()
.toList();
if (CollUtil.isEmpty(fishIds)) {
return;
}
Map<String, Object> paramMap = new HashMap<>();
List<String> placeholders = new ArrayList<>();
for (int i = 0; i < fishIds.size(); i++) {
String key = "zyFishId" + i;
paramMap.put(key, fishIds.get(i));
placeholders.add("#{map." + key + "}");
}
String sql = "SELECT rel.ZY_FISH_ID AS zyFishId, rv.RVNM AS rvcdName " +
"FROM SD_FISHDICTORY_RLTN_B rel " +
"LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = rel.RVCD " +
"WHERE rel.ZY_FISH_ID IN (" + String.join(", ", placeholders) + ") " +
"AND rel.RVCD <> 'ZY' " +
"AND NVL(rel.IS_DELETED, 0) = 0 " +
"AND rv.RVNM IS NOT NULL";
List<Map<String, Object>> rows = microservicDynamicSQLMapper.getAllList(sql, paramMap);
Map<String, List<String>> rvcdNameMap = new HashMap<>();
for (Map<String, Object> row : rows) {
Object fishId = row.get("ZYFISHID");
Object rvcdName = row.get("RVCDNAME");
if (fishId == null || rvcdName == null) {
continue;
}
rvcdNameMap.computeIfAbsent(String.valueOf(fishId), key -> new ArrayList<>())
.add(String.valueOf(rvcdName));
}
for (FprZyFishDicVo item : list) {
if (item == null) {
continue;
}
String fishKey = StrUtil.blankToDefault(item.getZyFishId(), item.getId());
List<String> names = rvcdNameMap.getOrDefault(fishKey, new ArrayList<>()).stream()
.filter(StrUtil::isNotBlank)
.distinct()
.toList();
item.setRvcdName(String.join(",", names));
}
}
private String querySingleRvcdName(String rvcd) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("rvcd", rvcd);
List<Map<String, Object>> rows = microservicDynamicSQLMapper.getAllList(
"SELECT RVNM AS rvcdName FROM SD_RVCD_DIC WHERE RVCD = #{map.rvcd} AND ROWNUM = 1",
paramMap
);
if (CollUtil.isEmpty(rows)) {
return null;
}
Object value = rows.get(0).get("RVCDNAME");
return value == null ? null : String.valueOf(value);
}
private String buildMsstbprptDetailSelectSql(List<String> selectFields) { private String buildMsstbprptDetailSelectSql(List<String> selectFields) {
LinkedHashMap<String, String> columnMap = buildMsstbprptSelectColumnMap(); LinkedHashMap<String, String> columnMap = buildMsstbprptSelectColumnMap();
if (CollUtil.isEmpty(selectFields)) { if (CollUtil.isEmpty(selectFields)) {
@ -1384,6 +1453,7 @@ public class FprMonitorServiceImpl implements FprMonitorService {
case "isDeleted" -> "t.isDeleted"; case "isDeleted" -> "t.isDeleted";
case "zyFishId" -> "t.zyFishId"; case "zyFishId" -> "t.zyFishId";
case "rvcd" -> "t.rvcd"; case "rvcd" -> "t.rvcd";
case "rvcdName" -> "t.rvcdName";
case "name" -> "t.name"; case "name" -> "t.name";
case "type" -> "t.type"; case "type" -> "t.type";
case "family" -> "t.family"; case "family" -> "t.family";
@ -1412,26 +1482,33 @@ public class FprMonitorServiceImpl implements FprMonitorService {
case "logo" -> "t.logo"; case "logo" -> "t.logo";
case "inffile" -> "t.inffile"; case "inffile" -> "t.inffile";
case "spawnMonth" -> "t.spawnMonth"; case "spawnMonth" -> "t.spawnMonth";
case "orders" -> "t.orders";
case "vlsr" -> "t.vlsr";
case "vlsrTm" -> "t.vlsrTm";
default -> null; default -> null;
}; };
} }
private List<FprZyFishDicVo> paginateZyFishDicList(List<FprZyFishDicVo> resultList, DataSourceLoadOptionsBase loadOptions) { private String buildZyFishDicOrderBySql(List<DataSourceRequest.SortDescriptor> sorts) {
if (CollUtil.isEmpty(resultList) || loadOptions == null || loadOptions.getTake() == null || loadOptions.getTake() <= 0) { List<String> orderItems = new ArrayList<>();
return resultList; if (CollUtil.isNotEmpty(sorts)) {
for (DataSourceRequest.SortDescriptor sort : sorts) {
if (sort == null || StrUtil.isBlank(sort.getField())) {
continue;
}
String column = mapZyFishDicColumn(sort.getField());
if (StrUtil.isBlank(column)) {
continue;
}
String direction = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir())
? "DESC" : "ASC";
orderItems.add(column + " " + direction + " NULLS LAST");
}
} }
int page = loadOptions.getSkip() == null ? 1 : loadOptions.getSkip(); // 页码从1开始缺省为1 if (orderItems.isEmpty()) {
// 如果页码 0强制设为1避免负值 return " ORDER BY t.rvcd ASC NULLS LAST, t.name ASC";
if (page < 1) {
page = 1;
} }
int size = loadOptions.getTake(); return " ORDER BY " + String.join(", ", orderItems);
int start = (page - 1) * size;
int end = Math.min(start + size, resultList.size());
if (start >= resultList.size()) {
return new ArrayList<>();
}
return new ArrayList<>(resultList.subList(start, end));
} }
private String formatSpawnMonth(String input) { private String formatSpawnMonth(String input) {