feat: 环保部-过鱼总量-二级弹窗列表

This commit is contained in:
tangwei 2026-08-12 17:25:17 +08:00
parent 7695bc0c12
commit 3f1c014617
4 changed files with 346 additions and 0 deletions

View File

@ -136,4 +136,10 @@ public class FishPassageController {
public ResponseResult getTreeStcdList(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(fpRunService.getTreeStcdList(dataSourceRequest));
}
@PostMapping("/query/qgc/getOverfishTotal")
@Operation(summary = "环保部-过鱼总量-二级弹窗列表SD_FPSSRL_R + SD_FPSS_R 合并)")
public ResponseResult getQgcOverfishTotal(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(fpRunService.processQgcOverfishTotalKendoList(dataSourceRequest));
}
}

View File

@ -0,0 +1,84 @@
package com.yfd.platform.qgc_env.fp.entity.vo;
import lombok.Data;
import java.util.Date;
/**
* <p>
* 环保部-过鱼总量-二级弹窗列表 VO
* </p>
* <p>对应旧系统 FpssrlRQueryVo.getQgcOverfishTotal查询 SD_FPSSRL_R + SD_FPSS_R 合并数据</p>
*/
@Data
public class FpOverfishTotalVo {
/** 过鱼设施编码 */
private String stcd;
/** 设施名称 */
private String stnm;
/** 基地编码 */
private String baseId;
/** 基地名称 */
private String baseName;
/** 电站编码 */
private String rstcd;
/** 电站名称 */
private String ennm;
/** 时间 */
private Date tm;
/** 过鱼年份 */
private String yr;
/** 鱼类名称 */
private String ftp;
/** 鱼类编码 */
private String fishId;
/** 大小 */
private String fsz;
/** 鱼宽度 */
private String width;
/** 鱼速度 */
private String fishspeed;
/** 游向0=上行 1=下行 */
private String direction;
/** 水温 */
private String temperature;
/** 流速 */
private String speed;
/** 过鱼通道 */
private String channelno;
/** 数量 */
private String fcnt;
/** 图片URL */
private String firstimgurl;
/** 视频URL */
private String videourl;
/** 监测方式1=人工 2=自动 */
private Integer mway;
/** 人工过鱼 开始日期 */
private Date strdt;
/** 人工过鱼 结束日期 */
private Date enddt;
}

View File

@ -10,6 +10,7 @@ import com.yfd.platform.qgc_env.fp.entity.vo.FpSdfpssrVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpTableVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpTreeStcdGroupVo;
import com.yfd.platform.qgc_env.fp.entity.vo.YearFpStatisticsVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpOverfishTotalVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpRunPlanVo;
import java.util.List;
@ -35,4 +36,6 @@ public interface FpRunService {
List<YearFpStatisticsVo> getYearFpStatic(String year,String stcd);
DataSourceResult<FpTreeStcdGroupVo> getTreeStcdList(DataSourceRequest dataSourceRequest);
DataSourceResult<FpOverfishTotalVo> processQgcOverfishTotalKendoList(DataSourceRequest dataSourceRequest);
}

View File

@ -17,6 +17,7 @@ import com.yfd.platform.qgc_env.fp.entity.vo.FbFishRunVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpFishSelectVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpFpssrlQueryVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpFtpStatisticsVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpOverfishTotalVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisHeadColumnVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisTableVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisVo;
@ -2838,5 +2839,257 @@ public class FpRunServiceImpl implements FpRunService {
};
}
// ==================== 环保部-过鱼总量-二级弹窗列表 ====================
@Override
public DataSourceResult<FpOverfishTotalVo> processQgcOverfishTotalKendoList(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) {
return queryOverfishTotalDetailList(dataSourceRequest, loadOptions);
}
return queryOverfishTotalGroupList(dataSourceRequest, loadOptions);
}
private DataSourceResult<FpOverfishTotalVo> queryOverfishTotalDetailList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ")
.append(buildOverfishTotalSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect()))
.append(" FROM (")
.append(buildOverfishTotalCoreSql())
.append(") t WHERE 1 = 1 ");
Map<String, Object> paramMap = new HashMap<>();
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
dataSourceRequest == null ? null : dataSourceRequest.getFilter(),
paramMap,
new int[]{0},
this::mapOverfishTotalColumn
);
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
sql.append(buildOverfishTotalOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
List<FpOverfishTotalVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
page, sql.toString(), paramMap, FpOverfishTotalVo.class
);
DataSourceResult<FpOverfishTotalVo> result = new DataSourceResult<>();
result.setData(list);
result.setTotal(page != null ? page.getTotal() : list.size());
result.setAggregates(new HashMap<>());
return result;
}
private DataSourceResult<FpOverfishTotalVo> queryOverfishTotalGroupList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup();
GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup();
List<String> selectItems = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapOverfishTotalColumn(descriptor.getField());
if (StrUtil.isBlank(column)) {
continue;
}
selectItems.add(column + " AS " + descriptor.getField().toUpperCase());
selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase());
if (CollUtil.isNotEmpty(descriptor.getAggregates())) {
for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) {
String aggregateColumn = mapOverfishTotalColumn(aggregate.getField());
if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) {
continue;
}
selectItems.add(buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField()));
}
}
}
if (selectItems.isEmpty()) {
selectItems.add("t.STCD AS STCD");
selectItems.add("COUNT(*) AS COUNT_STCD");
}
StringBuilder sql = new StringBuilder("SELECT ");
sql.append(String.join(", ", selectItems))
.append(" FROM (")
.append(buildOverfishTotalCoreSql())
.append(") t WHERE 1 = 1 ");
Map<String, Object> paramMap = new HashMap<>();
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
dataSourceRequest == null ? null : dataSourceRequest.getFilter(),
paramMap,
new int[]{0},
this::mapOverfishTotalColumn
);
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
List<String> groupByColumns = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapOverfishTotalColumn(descriptor.getField());
if (StrUtil.isNotBlank(column)) {
groupByColumns.add(column);
}
}
if (!groupByColumns.isEmpty()) {
sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" ");
}
List<Map<String, Object>> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap);
DataSourceResult<FpOverfishTotalVo> result = new DataSourceResult<>();
if (dataSourceRequest.getGroupResultFlat() != null && dataSourceRequest.getGroupResultFlat()) {
result.setData((List<FpOverfishTotalVo>) (List<?>) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos)));
} else {
result.setData((List<FpOverfishTotalVo>) (List<?>) new GroupHelper().group(rows, Arrays.asList(groupInfos)));
}
result.setTotal(0L);
result.setAggregates(new HashMap<>());
return result;
}
/**
* 过鱼总量核心 SQLSD_FPSSRL_R自动UNION ALL SD_FPSS_R人工
* <p>使用 V_MS_STBPRP_T 替代旧系统 MS_STBPRP_TV_SD_FISHDICTORY_B 替代旧版鱼类字典</p>
*/
private String buildOverfishTotalCoreSql() {
return "SELECT t.STCD, t.STNM, t.BASE_ID, t.BASE_NAME, " +
"t.RSTCD, t.ENNM, t.TM, t.YR, t.FTP, t.FISHID, t.FSZ, " +
"t.WIDTH, t.FISHSPEED, t.DIRECTION, t.TEMPERATURE, t.SPEED, " +
"t.CHANNELNO, t.FCNT, t.FIRSTIMGURL, t.VIDEOURL, " +
"t.MWAY, t.STRDT, t.ENDDT " +
"FROM ( " +
// ---- 自动监测 SD_FPSSRL_R ----
" SELECT a.STCD, msb.STNM, msb.BASE_ID, msb.BASE_NAME, msb.RSTCD, msb.ENNM, " +
" a.TM, TO_CHAR(a.TM, 'YYYY') AS YR, dict.NAME AS FTP, a.FTP AS FISHID, a.FSZ, " +
" TO_CHAR(a.WIDTH) AS WIDTH, TO_CHAR(a.FISHSPEED) AS FISHSPEED, " +
" TO_CHAR(a.DIRECTION) AS DIRECTION, TO_CHAR(a.TEMPERATURE) AS TEMPERATURE, " +
" TO_CHAR(a.SPEED) AS SPEED, a.CHANNELNO, TO_CHAR(a.FCNT) AS FCNT, " +
" a.FIRSTIMGURL, a.VIDEOURL, msb.MWAY, NULL AS STRDT, NULL AS ENDDT " +
" FROM SD_FPSSRL_R a " +
" INNER JOIN V_MS_STBPRP_T msb ON a.STCD = msb.STCD AND msb.DATA_SOURCE = 'SD_FPSS_B_H' " +
" INNER JOIN V_SD_FISHDICTORY_B dict ON a.FTP = dict.FISH_ID " +
" AND (msb.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') " +
" WHERE NVL(a.IS_DELETED, 0) = 0 " +
" UNION ALL " +
// ---- 人工监测 SD_FPSS_R ----
" SELECT a.STCD, msb.STNM, msb.BASE_ID, msb.BASE_NAME, msb.RSTCD, msb.ENNM, " +
" a.STRDT AS TM, TO_CHAR(a.STRDT, 'YYYY') AS YR, dict.NAME AS FTP, a.FTP AS FISHID, " +
" MIN(a.FSZ) AS FSZ, NULL AS WIDTH, NULL AS FISHSPEED, " +
" TO_CHAR(MIN(a.DIRECTION)) AS DIRECTION, NULL AS TEMPERATURE, NULL AS SPEED, " +
" NULL AS CHANNELNO, TO_CHAR(SUM(a.FCNT)) AS FCNT, " +
" NULL AS FIRSTIMGURL, NULL AS VIDEOURL, 1 AS MWAY, a.STRDT, a.ENDDT " +
" FROM SD_FPSS_R a " +
" INNER JOIN V_MS_STBPRP_T msb ON a.STCD = msb.STCD AND msb.DATA_SOURCE = 'SD_FPSS_B_H' " +
" INNER JOIN V_SD_FISHDICTORY_B dict ON a.FTP = dict.FISH_ID " +
" AND (msb.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') " +
" WHERE 1=1 " +
" AND NVL(a.IS_DELETED, 0) = 0 " +
" GROUP BY a.STCD, msb.STNM, msb.BASE_ID, msb.BASE_NAME, msb.RSTCD, msb.ENNM, " +
" a.STRDT, a.ENDDT, TO_CHAR(a.STRDT, 'YYYY'), dict.NAME, a.FTP " +
") t WHERE 1 = 1 ";
}
private String buildOverfishTotalSelectSql(List<String> selectFields) {
Map<String, String> columns = new LinkedHashMap<>();
columns.put("stcd", "t.STCD AS stcd");
columns.put("stnm", "t.STNM AS stnm");
columns.put("baseId", "t.BASE_ID AS baseId");
columns.put("baseName", "t.BASE_NAME AS baseName");
columns.put("rstcd", "t.RSTCD AS rstcd");
columns.put("ennm", "t.ENNM AS ennm");
columns.put("tm", "t.TM AS tm");
columns.put("yr", "t.YR AS yr");
columns.put("ftp", "t.FTP AS ftp");
columns.put("fishId", "t.FISHID AS fishId");
columns.put("fsz", "t.FSZ AS fsz");
columns.put("width", "t.WIDTH AS width");
columns.put("fishspeed", "t.FISHSPEED AS fishspeed");
columns.put("direction", "t.DIRECTION AS direction");
columns.put("temperature", "t.TEMPERATURE AS temperature");
columns.put("speed", "t.SPEED AS speed");
columns.put("channelno", "t.CHANNELNO AS channelno");
columns.put("fcnt", "t.FCNT AS fcnt");
columns.put("firstimgurl", "t.FIRSTIMGURL AS firstimgurl");
columns.put("videourl", "t.VIDEOURL AS videourl");
columns.put("mway", "t.MWAY AS mway");
columns.put("strdt", "t.STRDT AS strdt");
columns.put("enddt", "t.ENDDT AS enddt");
List<String> selected = new ArrayList<>();
if (CollUtil.isEmpty(selectFields)) {
selected.addAll(columns.values());
} else {
for (String field : selectFields) {
String column = columns.get(field);
if (StrUtil.isNotBlank(column)) {
selected.add(column);
}
}
if (selected.isEmpty()) {
selected.addAll(columns.values());
}
}
return String.join(", ", selected);
}
private String mapOverfishTotalColumn(String field) {
if (StrUtil.isBlank(field)) {
return null;
}
return switch (field.toLowerCase()) {
case "stcd" -> "t.STCD";
case "stnm" -> "t.STNM";
case "baseid" -> "t.BASE_ID";
case "basename" -> "t.BASE_NAME";
case "rstcd" -> "t.RSTCD";
case "ennm" -> "t.ENNM";
case "tm" -> "t.TM";
case "yr" -> "t.YR";
case "ftp" -> "t.FTP";
case "fishid" -> "t.FISHID";
case "fsz" -> "t.FSZ";
case "width" -> "t.WIDTH";
case "fishspeed" -> "t.FISHSPEED";
case "direction" -> "t.DIRECTION";
case "temperature" -> "t.TEMPERATURE";
case "speed" -> "t.SPEED";
case "channelno" -> "t.CHANNELNO";
case "fcnt" -> "t.FCNT";
case "mway" -> "t.MWAY";
case "strdt" -> "t.STRDT";
case "enddt" -> "t.ENDDT";
case "firstimgurl" -> "t.FIRSTIMGURL";
case "videourl" -> "t.VIDEOURL";
default -> null;
};
}
private String buildOverfishTotalOrderBySql(List<DataSourceRequest.SortDescriptor> sortList) {
if (CollUtil.isEmpty(sortList)) {
return " ORDER BY t.TM DESC";
}
List<String> orders = new ArrayList<>();
for (DataSourceRequest.SortDescriptor sort : sortList) {
if (sort == null || StrUtil.isBlank(sort.getField())) {
continue;
}
String column = mapOverfishTotalColumn(sort.getField());
if (StrUtil.isBlank(column)) {
continue;
}
String dir = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC";
orders.add(column + " " + dir);
}
return orders.isEmpty() ? " ORDER BY t.TM DESC" : " ORDER BY " + String.join(", ", orders);
}
}