diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprZyFishDicVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprZyFishDicVo.java index 2fb1bf67..7dad88bf 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprZyFishDicVo.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprZyFishDicVo.java @@ -45,4 +45,5 @@ public class FprZyFishDicVo { private String spawnMonth; private String orders; private String vlsr; + private java.util.Date vlsrTm; } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java index ab2cfaca..a1503c2e 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java @@ -250,87 +250,33 @@ public class FprMonitorServiceImpl implements FprMonitorService { new int[]{0} ); + String baseSql = StrUtil.isBlank(rvcd) ? buildZyFishDicSummarySql() : buildZyFishDicBaseSql(); StringBuilder sql = new StringBuilder("SELECT * FROM (") - .append(buildZyFishDicBaseSql()) + .append(baseSql) .append(") t WHERE 1 = 1 "); if (StrUtil.isNotBlank(filterSql)) { sql.append(" AND ").append(filterSql).append(" "); } - // 增加排序 - if(dataSourceRequest.getSort() !=null && !dataSourceRequest.getSort().isEmpty()){ - List sortDescriptors = dataSourceRequest.getSort(); - StringBuilder orderSql = new StringBuilder(); - 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 list = microservicDynamicSQLMapper.getAllListWithResultType( + sql.append(buildZyFishDicOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List resultList = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, FprZyFishDicVo.class ); - List> rvcdRows = microservicDynamicSQLMapper.getAllList( - "SELECT RVCD AS rvcd, RVNM AS rvcdName FROM SD_RVCD_DIC", - null - ); - Map rvcdNameMap = new HashMap<>(); - for (Map 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 resultList; - Map> 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 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++) { FprZyFishDicVo item = resultList.get(i); - item.setIndex(i + 1); + item.setIndex(startIndex + i + 1); item.setSpawnMonth(formatSpawnMonth(item.getSpawnMonth())); - if (StrUtil.isBlank(rvcd)) { - List rvcdList = rvcdMap.getOrDefault( - StrUtil.blankToDefault(item.getZyFishId(), item.getId()), - new ArrayList<>() - ).stream().filter(StrUtil::isNotBlank).distinct().toList(); - List 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 result = new DataSourceResult<>(); - result.setTotal((long) resultList.size()); - result.setData(paginateZyFishDicList(resultList, loadOptions)); + result.setTotal(page != null ? page.getTotal() : resultList.size()); + result.setData(resultList); result.setAggregates(new HashMap<>()); return result; } @@ -739,6 +685,7 @@ public class FprMonitorServiceImpl implements FprMonitorService { "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.RVCD IS NULL THEN 'null' ELSE rel.RVCD END AS rvcd, " + + "rv.RVNM AS rvcdName, " + "src.NAME AS name, " + "src.TYPE AS type, " + "src.FAMILY AS family, " + @@ -769,15 +716,137 @@ public class FprMonitorServiceImpl implements FprMonitorService { "src.LOGO AS logo, " + "src.INFFILE AS inffile, " + "src.ORDERS, \n" + - "src.VLSR, \n"+ + "src.VLSR AS vlsr, \n" + + "src.VLSR_TM AS vlsrTm, \n" + "src.SPAWN_MONTH AS spawnMonth " + "FROM SD_FISHDICTORY_B src " + "LEFT JOIN SD_FISHDICTORY_RLTN_B rel ON src.ID = rel.ZY_FISH_ID " + " AND rel.RVCD <> 'ZY' " + " 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 "; } + 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 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 fishIds = list.stream() + .map(item -> StrUtil.blankToDefault(item.getZyFishId(), item.getId())) + .filter(StrUtil::isNotBlank) + .distinct() + .toList(); + if (CollUtil.isEmpty(fishIds)) { + return; + } + Map paramMap = new HashMap<>(); + List 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> rows = microservicDynamicSQLMapper.getAllList(sql, paramMap); + Map> rvcdNameMap = new HashMap<>(); + for (Map 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 names = rvcdNameMap.getOrDefault(fishKey, new ArrayList<>()).stream() + .filter(StrUtil::isNotBlank) + .distinct() + .toList(); + item.setRvcdName(String.join(",", names)); + } + } + + private String querySingleRvcdName(String rvcd) { + Map paramMap = new HashMap<>(); + paramMap.put("rvcd", rvcd); + List> 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 selectFields) { LinkedHashMap columnMap = buildMsstbprptSelectColumnMap(); if (CollUtil.isEmpty(selectFields)) { @@ -1384,6 +1453,7 @@ public class FprMonitorServiceImpl implements FprMonitorService { case "isDeleted" -> "t.isDeleted"; case "zyFishId" -> "t.zyFishId"; case "rvcd" -> "t.rvcd"; + case "rvcdName" -> "t.rvcdName"; case "name" -> "t.name"; case "type" -> "t.type"; case "family" -> "t.family"; @@ -1412,26 +1482,33 @@ public class FprMonitorServiceImpl implements FprMonitorService { case "logo" -> "t.logo"; case "inffile" -> "t.inffile"; case "spawnMonth" -> "t.spawnMonth"; + case "orders" -> "t.orders"; + case "vlsr" -> "t.vlsr"; + case "vlsrTm" -> "t.vlsrTm"; default -> null; }; } - private List paginateZyFishDicList(List resultList, DataSourceLoadOptionsBase loadOptions) { - if (CollUtil.isEmpty(resultList) || loadOptions == null || loadOptions.getTake() == null || loadOptions.getTake() <= 0) { - return resultList; + private String buildZyFishDicOrderBySql(List sorts) { + List orderItems = new ArrayList<>(); + 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 - // 如果页码 ≤ 0,强制设为1(避免负值) - if (page < 1) { - page = 1; + if (orderItems.isEmpty()) { + return " ORDER BY t.rvcd ASC NULLS LAST, t.name ASC"; } - int size = loadOptions.getTake(); - 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)); + return " ORDER BY " + String.join(", ", orderItems); } private String formatSpawnMonth(String input) {