From 4ad2014e6128a256414ab0a63462f00b676592ec Mon Sep 17 00:00:00 2001 From: lilin <18811154576@163.com> Date: Wed, 17 Jun 2026 11:42:49 +0800 Subject: [PATCH 01/65] =?UTF-8?q?=E5=9B=BE=E5=B1=82=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=9B=BE=E4=BE=8B=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=EF=BC=8C=E6=9F=A5=E8=AF=A2=20=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/config/SecurityConfig.java | 2 + .../yfd/platform/config/SwaggerConfig.java | 16 ++ .../controller/MapLayerController.java | 71 +++++ .../controller/MapLegendController.java | 102 +++++++ .../qgc_sys/mapLayer/domain/MsMaplayerB.java | 191 +++++++++++++ .../qgc_sys/mapLayer/domain/MsMaplegendB.java | 134 +++++++++ .../qgc_sys/mapLayer/domain/MsMapmoduleB.java | 95 +++++++ .../mapLayer/entity/vo/MapLayerAo.java | 15 + .../mapLayer/mapper/MsMaplayerBMapper.java | 14 + .../mapLayer/mapper/MsMaplegendBMapper.java | 14 + .../mapLayer/mapper/MsMapmoduleBMapper.java | 14 + .../mapLayer/service/IMapLayerBizService.java | 22 ++ .../mapLayer/service/IMapLayerService.java | 28 ++ .../mapLayer/service/IMapLegendService.java | 22 ++ .../service/impl/MapLayerBizServiceImpl.java | 165 +++++++++++ .../service/impl/MapLayerServiceImpl.java | 256 ++++++++++++++++++ .../service/impl/MapLegendServiceImpl.java | 97 +++++++ .../controller/MapmoduleBController.java | 101 +++++++ .../mapcfg/service/IMapmoduleBService.java | 36 +++ .../service/impl/MapmoduleBServiceImpl.java | 92 +++++++ 20 files changed, 1487 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplayerB.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerAo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplayerBMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplegendBMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerServiceImpl.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 79a4e331..d0fca320 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -71,6 +71,8 @@ public class SecurityConfig { // .requestMatchers("/fp/**").permitAll() // .requestMatchers("/fh/**").permitAll() // .requestMatchers("/data/**").permitAll() + .requestMatchers("/mapLayer/**").permitAll() + .requestMatchers("/mapLegend/**").permitAll() .requestMatchers("/sms/**").permitAll() .requestMatchers(HttpMethod.GET, "/").permitAll() .requestMatchers(HttpMethod.GET, diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index 443e06a6..c07a6cf5 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -146,4 +146,20 @@ public class SwaggerConfig { .packagesToScan("com.yfd.platform.qgc_eng.eq.controller") .build(); } + + @Bean + public GroupedOpenApi groupSysApi() { + return GroupedOpenApi.builder() + .group("5. 图层管理") + .packagesToScan("com.yfd.platform.qgc_sys.mapLayer.controller") + .build(); + } + + @Bean + public GroupedOpenApi groupSysMlgApi() { + return GroupedOpenApi.builder() + .group("5.1 图例结构管理") + .packagesToScan("com.yfd.platform.qgc_sys.mapLegend.controller") + .build(); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java new file mode 100644 index 00000000..981346ce --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java @@ -0,0 +1,71 @@ +package com.yfd.platform.qgc_sys.mapLayer.controller; + +import cn.hutool.core.util.StrUtil; +import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerBizService; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 地图图层管理 + * + * @author migration + */ +@RestController +@RequestMapping("/mapLayer") +@Tag(name = "地图图层管理") +public class MapLayerController { + + @Resource + private IMapLayerBizService mapLayerBizService; + + @Resource + private IMapLayerService layerService; + + /** + * 地图图层管理图层树(所有) + */ + @Operation(summary = "地图图层管理图层树(所有)") + @PostMapping("/getAllMapLayerTree") + public ResponseResult getAllMapLayerTree(@RequestBody MapLayerAo flag) { + List tree = mapLayerBizService.getMapLayerTree(flag); + return ResponseResult.successData(tree); + } + + /** + * 图层新增修改 + */ + @Operation(summary = "图层新增修改") + @PostMapping("/save") + public ResponseResult addLayer(@RequestBody MsMaplayerB layer) { + if (layer == null) { + return ResponseResult.error("图层信息不能为空."); + } + if (StrUtil.isBlank(layer.getCode())) { + throw new BizException("图层编码(code)不能为空."); + } + if (StrUtil.isBlank(layer.getTitle())) { + throw new BizException("图层名称(title)不能为空."); + } + layerService.saveOrUpdate(layer); + return ResponseResult.success("保存成功."); + } + + /** + * 图层删除 + */ + @Operation(summary = "图层删除") + @PostMapping("/delete") + public ResponseResult deleteLayer(@RequestBody List ids) { + layerService.delelteByIds(ids); + return ResponseResult.success("删除成功."); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java new file mode 100644 index 00000000..f038b8e7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java @@ -0,0 +1,102 @@ +package com.yfd.platform.qgc_sys.mapLayer.controller; + + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendService; +import com.yfd.platform.utils.DataSourceRequestUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 地图图例管理 + * + * @author migration + */ +@RestController +@RequestMapping("/mapLegend") +@Tag(name = "地图图例管理") +public class MapLegendController { + + @Resource + private IMapLegendService mapLegendService; + + /** + * 条件过滤数据列表(Kendo UI 数据源) + */ + @Operation(summary = "条件过滤数据列表") + @PostMapping("/GetKendoList") + public ResponseResult getKendoList(@RequestBody DataSourceRequest dataSourceRequest) { + // 构建查询条件 + QueryWrapper wrapper = DataSourceRequestUtil.buildQueryWrapper( + dataSourceRequest, MsMaplegendB.class); + + // 执行分页查询 + Page page = DataSourceRequestUtil.getPage(dataSourceRequest); + Page resultPage; + if (page != null) { + resultPage = mapLegendService.page(page, wrapper); + } else { + List list = mapLegendService.list(wrapper); + resultPage = new Page<>(); + resultPage.setRecords(list); + resultPage.setTotal(list.size()); + } + + // 构建 Kendo 数据源结果 + DataSourceResult dataSourceResult = new DataSourceResult<>(); + dataSourceResult.setData(resultPage.getRecords()); + dataSourceResult.setTotal(resultPage.getTotal()); + + return ResponseResult.successData(dataSourceResult); + } + + /** + * 图例新增修改 + */ + @Operation(summary = "图例新增修改") + @PostMapping("/save") + public ResponseResult addLayer(@RequestBody MsMaplegendB legend) { + if (legend == null) { + return ResponseResult.error("图例信息不能为空."); + } + if (StrUtil.isBlank(legend.getCode())) { + throw new BizException("图例类型(code: pointLayer=用于锚点,baseLayer=地图GIS)不能为空."); + } + if (StrUtil.isBlank(legend.getName())) { + throw new BizException("图例名称(name)不能为空."); + } + if (StrUtil.isBlank(legend.getNameEn())) { + throw new BizException("图例编码(nameEn)不能为空."); + } + if (legend.getDataType() == null) { + throw new BizException("图例数据类型(dataType: 1=结构,2=数据)不能为空."); + } + if (legend.getDataType() == 2 && StrUtil.isBlank(legend.getLayerCode())) { + throw new BizException("关联的图层编码(layerCode)不能为空."); + } + mapLegendService.saveOrUpdate(legend); + return ResponseResult.success("保存成功."); + } + + /** + * 图例删除 + */ + @Operation(summary = "图例删除") + @PostMapping("/delete") + public ResponseResult deleteLayer(@RequestBody List ids) { + mapLegendService.delelteByIds(ids); + return ResponseResult.success("删除成功."); + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplayerB.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplayerB.java new file mode 100644 index 00000000..25904a0b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplayerB.java @@ -0,0 +1,191 @@ +package com.yfd.platform.qgc_sys.mapLayer.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 地图图层表 + * + * @author migration + */ +@Data +@TableName("MS_MAPLAYER_B") +public class MsMaplayerB implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + /** 类型 */ + @TableField("TYPE") + private String type; + + /** 标识字段 */ + @TableField("KEY") + private String key; + + /** 编码 */ + @TableField("CODE") + private String code; + + /** 名称 */ + @TableField("TITLE") + private String title; + + /** 名称英文 */ + @TableField("TITLE_EN") + private String titleEn; + + /** 所属父节点 */ + @TableField("PARENT_ID") + private String parentId; + + /** 树全路径 */ + @TableField("FULL_PATH") + private String fullPath; + + /** 层级 */ + @TableField("TREE_LEVEL") + private Integer treeLevel; + + /** 是否有子集:0=否 1=有 */ + @TableField("HAS_CHILDREN") + private Integer hasChildren; + + /** 对应锚点接口 */ + @TableField("URL") + private String url; + + /** 对应三维锚点接口 */ + @TableField("URL_THD") + private String urlThd; + + /** 参数设置 */ + @TableField("OPTIONS") + private String options; + + /** 访问令牌 */ + @TableField("TOKEN") + private String token; + + /** 用户名 */ + @TableField("USERNAME") + private String username; + + /** 密码 */ + @TableField("PASSWORD") + private String password; + + /** 地图中心点经度 */ + @TableField("CENTER_LGTD") + private BigDecimal centerLgtd; + + /** 地图中心点纬度 */ + @TableField("CENTER_LTTD") + private BigDecimal centerLttd; + + /** 默认缩放级别 */ + @TableField("DEFAULT_ZOOM") + private String defaultZoom; + + /** 所属国家 */ + @TableField("COUNTRY") + private String country; + + /** 图标 */ + @TableField("ICON") + private String icon; + + /** 是否可选择:0=否 1=是 */ + @TableField("CHECKABLE") + private Integer checkable; + + /** 图层上下层层级关系 */ + @TableField("Z_INDEX") + private String zIndex; + + /** 各类站点图层对应类型 */ + @TableField("STTP_TYPE") + private String sttpType; + + /** 图层展示数据格式 */ + @TableField("LAYERS") + private String layers; + + /** 图层透明度 */ + @TableField("OPACITY") + private BigDecimal opacity; + + /** 额外参数 */ + @TableField("PARAMJSON") + private String paramJson; + + /** 备注 */ + @TableField("DESCRIPTION") + private String description; + + /** 是否启用:0=禁用 1=启用 */ + @TableField("ENABLE") + private Integer enable; + + /** 排序 */ + @TableField("ORDER_INDEX") + private Integer orderIndex; + + /** 过滤内容 */ + @TableField("FILTER_CONTENT") + private String filterContent; + + /** 创建人 */ + @TableField("RECORD_USER") + private String recordUser; + + /** 创建时间 */ + @TableField("RECORD_TIME") + private Date recordTime; + + /** 更新人 */ + @TableField("MODIFY_USER") + private String modifyUser; + + /** 更新时间 */ + @TableField("MODIFY_TIME") + private Date modifyTime; + + /** 是否已删除:0=未删除 1=已删除 */ + @TableField("IS_DELETED") + private Integer isDeleted; + + /** 删除人 */ + @TableField("DELETE_USER") + private String deleteUser; + + /** 删除时间 */ + @TableField("DELETE_TIME") + private Date deleteTime; + + /** 数据类型:1=结构,2=数据 */ + @TableField("DATA_TYPE") + private Integer dataType; + + /** 标签层级 */ + @TableField("LABEL_LEVEL") + private Integer labelLevel; + + /** 子级集合(非数据库字段) */ + @TableField(exist = false) + private List children; + + /** 创建人名称(非数据库字段) */ + @TableField(exist = false) + private String displayRecordUser; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java new file mode 100644 index 00000000..6147f6c3 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java @@ -0,0 +1,134 @@ +package com.yfd.platform.qgc_sys.mapLayer.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 地图图例表 + * + * @author migration + */ +@Data +@TableName("MS_MAPLEGEND_B") +public class MsMaplegendB implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + @TableField("NAME") + private String name; + + @TableField("NAME_EN") + private String nameEn; + + @TableField("CODE") + private String code; + + @TableField("ICON") + private String icon; + + @TableField("GROUP_NAME") + private String groupName; + + @TableField("PARENT_NAME") + private String parentName; + + @TableField("LAYER_CODE") + private String layerCode; + + @TableField("MIN_ZOOM") + private Integer minZoom; + + @TableField("MAX_ZOOM") + private Integer maxZoom; + + @TableField("MIN_HEIGHT_THD") + private BigDecimal minHeightThd; + + @TableField("MAX_HEIGHT_THD") + private BigDecimal maxHeightThd; + + @TableField("DESCRIPTION") + private String description; + + @TableField("ENABLE") + private Integer enable; + + @TableField("INTERNAL") + private Integer internal; + + @TableField("ORDER_INDEX") + private Integer orderIndex; + + @TableField("FILTER_CONTENT") + private String filterContent; + + @TableField("RECORD_USER") + private String recordUser; + + @TableField("RECORD_TIME") + private Date recordTime; + + @TableField("MODIFY_USER") + private String modifyUser; + + @TableField("MODIFY_TIME") + private Date modifyTime; + + @TableField("IS_DELETED") + private Integer isDeleted; + + @TableField("DELETE_USER") + private String deleteUser; + + @TableField("DELETE_TIME") + private Date deleteTime; + + @TableField("IF_SHOW") + private Integer ifShow; + + @TableField("EXPRESSION") + private String expression; + + @TableField("EXT") + private String ext; + + @TableField("DATA_TYPE") + private Integer dataType; + + @TableField("PARENT_ID") + private String parentId; + + @TableField("FULL_PATH") + private String fullPath; + + @TableField("TREE_LEVEL") + private Integer treeLevel; + + @TableField("HAS_CHILDREN") + private Integer hasChildren; + + @TableField("COLOR") + private String color; + + @TableField("SHAPE") + private String shape; + + @TableField("MIN_VAL") + private BigDecimal minVal; + + @TableField("MAX_VAL") + private BigDecimal maxVal; + + @TableField("IS_FILTER") + private Integer isFilter; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java new file mode 100644 index 00000000..aac57f40 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java @@ -0,0 +1,95 @@ +package com.yfd.platform.qgc_sys.mapLayer.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 地图与菜单映射表 + * + * @author migration + */ +@Data +@TableName("MS_MAPMODULE_B") +public class MsMapmoduleB implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + @TableField("MODULE_ID") + private String moduleId; + + @TableField("RES_TYPE") + private String resType; + + @TableField("RES_ID") + private String resId; + + @TableField("CHILD_NODE") + private Integer childNode; + + @TableField("MULTI_SELECT") + private Integer multiSelect; + + @TableField("CAN_BE_CHECKED") + private Integer canBeChecked; + + @TableField("CHECKED") + private Integer checked; + + @TableField("DESCRIPTION") + private String description; + + @TableField("ENABLE") + private Integer enable; + + @TableField("ORDER_INDEX") + private Integer orderIndex; + + @TableField("FILTER_CONTENT") + private String filterContent; + + @TableField("RECORD_USER") + private String recordUser; + + @TableField("RECORD_TIME") + private Date recordTime; + + @TableField("MODIFY_USER") + private String modifyUser; + + @TableField("MODIFY_TIME") + private Date modifyTime; + + @TableField("IS_DELETED") + private Integer isDeleted; + + @TableField("DELETE_USER") + private String deleteUser; + + @TableField("DELETE_TIME") + private Date deleteTime; + + @TableField("TEMPLATE_ID") + private String templateId; + + /** + * 归属的系统ID(非数据库字段,用于字典翻译) + */ + @TableField(exist = false) + private String systemId; + + /** + * 菜单名称(非数据库字段,用于字典翻译) + */ + @TableField(exist = false) + private String moduleName; + +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerAo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerAo.java new file mode 100644 index 00000000..9d8e38ae --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerAo.java @@ -0,0 +1,15 @@ +package com.yfd.platform.qgc_sys.mapLayer.entity.vo; + +import lombok.Data; + +/** + * 地图图层查询参数 + * + * @author migration + */ +@Data +public class MapLayerAo { + + /** 图层名称(模糊查询) */ + private String title; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplayerBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplayerBMapper.java new file mode 100644 index 00000000..50a275ec --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplayerBMapper.java @@ -0,0 +1,14 @@ +package com.yfd.platform.qgc_sys.mapLayer.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; +import org.apache.ibatis.annotations.Mapper; + +/** + * 地图图层表 Mapper 接口 + * + * @author migration + */ +@Mapper +public interface MsMaplayerBMapper extends BaseMapper { +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplegendBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplegendBMapper.java new file mode 100644 index 00000000..d6df58bc --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaplegendBMapper.java @@ -0,0 +1,14 @@ +package com.yfd.platform.qgc_sys.mapLayer.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; +import org.apache.ibatis.annotations.Mapper; + +/** + * 地图图例表 Mapper 接口 + * + * @author migration + */ +@Mapper +public interface MsMaplegendBMapper extends BaseMapper { +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java new file mode 100644 index 00000000..774e4c00 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java @@ -0,0 +1,14 @@ +package com.yfd.platform.qgc_sys.mapLayer.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import org.apache.ibatis.annotations.Mapper; + +/** + * 地图与菜单映射表 Mapper 接口 + * + * @author migration + */ +@Mapper +public interface MsMapmoduleBMapper extends BaseMapper { +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java new file mode 100644 index 00000000..f0933a77 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java @@ -0,0 +1,22 @@ +package com.yfd.platform.qgc_sys.mapLayer.service; + +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo; + +import java.util.List; + +/** + * 地图图层业务服务接口 + * + * @author migration + */ +public interface IMapLayerBizService { + + /** + * 获取所有地图图层树 + * + * @param flag 查询参数 + * @return 图层树列表 + */ + List getMapLayerTree(MapLayerAo flag); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerService.java new file mode 100644 index 00000000..7aff13e5 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerService.java @@ -0,0 +1,28 @@ +package com.yfd.platform.qgc_sys.mapLayer.service; + +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; + +import java.util.List; + +/** + * 地图图层基础服务接口 + * + * @author migration + */ +public interface IMapLayerService { + + /** + * 新增或修改图层 + * + * @param layer 图层实体 + * @return 是否成功 + */ + boolean saveOrUpdate(MsMaplayerB layer); + + /** + * 根据ID列表删除图层 + * + * @param ids 图层ID列表 + */ + void delelteByIds(List ids); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendService.java new file mode 100644 index 00000000..273398ae --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendService.java @@ -0,0 +1,22 @@ +package com.yfd.platform.qgc_sys.mapLayer.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; + +import java.util.List; + +/** + * 地图图例基础服务接口 + * + * @author migration + */ +public interface IMapLegendService extends IService { + + /** + * 根据ID列表删除图例 + * + * @param ids 图例ID列表 + */ + void delelteByIds(List ids); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java new file mode 100644 index 00000000..4ba92e0a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java @@ -0,0 +1,165 @@ +package com.yfd.platform.qgc_sys.mapLayer.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplayerBMapper; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerBizService; +import com.yfd.platform.system.domain.SysDictionary; +import com.yfd.platform.system.domain.SysDictionaryItems; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysDictionaryItemsMapper; +import com.yfd.platform.system.mapper.SysDictionaryMapper; +import com.yfd.platform.system.mapper.SysUserMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 地图图层业务服务实现 + * + * @author migration + */ +@Service +public class MapLayerBizServiceImpl implements IMapLayerBizService { + + @Resource + private MsMaplayerBMapper msMaplayerBMapper; + + @Resource + private SysDictionaryMapper sysDictionaryMapper; + + @Resource + private SysDictionaryItemsMapper sysDictionaryItemsMapper; + + @Resource + private SysUserMapper sysUserMapper; + + @Override + public List getMapLayerTree(MapLayerAo flag) { + // 1. 查询字典 "DTZJLX" 获取需要排除的图层类型 + Set excludeTypes = getExcludeTypes(); + + // 2. 查询所有未删除的图层数据,排除特殊类型,支持按名称模糊查询 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(MsMaplayerB::getIsDeleted, 0); + + // 排除特殊类型 + if (!excludeTypes.isEmpty()) { + wrapper.and(w -> w.notIn(MsMaplayerB::getType, excludeTypes).or().isNull(MsMaplayerB::getType)); + } + + // 按名称模糊查询 + if (StrUtil.isNotBlank(flag.getTitle())) { + wrapper.like(MsMaplayerB::getTitle, flag.getTitle()); + } + + List mapLayers = msMaplayerBMapper.selectList(wrapper); + + // 3. 当按名称过滤时,补充缺失的父级节点 + if (StrUtil.isNotBlank(flag.getTitle()) && !mapLayers.isEmpty()) { + Set hasKeys = mapLayers.stream() + .filter(it -> StrUtil.isNotBlank(it.getKey())) + .map(MsMaplayerB::getKey) + .collect(Collectors.toSet()); + + Set idList = new HashSet<>(); + for (MsMaplayerB layer : mapLayers) { + if (StrUtil.isNotBlank(layer.getFullPath()) && StrUtil.isNotBlank(layer.getKey())) { + String[] ids = layer.getFullPath().replace(layer.getKey() + ",", "").split(","); + for (String id : ids) { + if (StrUtil.isNotBlank(id) && !hasKeys.contains(id)) { + idList.add(id); + } + } + } + } + + if (!idList.isEmpty()) { + LambdaQueryWrapper parentWrapper = new LambdaQueryWrapper<>(); + parentWrapper.eq(MsMaplayerB::getIsDeleted, 0) + .in(MsMaplayerB::getKey, idList); + List parentLayers = msMaplayerBMapper.selectList(parentWrapper); + if (!parentLayers.isEmpty()) { + mapLayers.addAll(parentLayers); + } + } + } + + // 4. 填充创建人名称 + if (!mapLayers.isEmpty()) { + LambdaQueryWrapper userWrapper = new LambdaQueryWrapper<>(); + List users = sysUserMapper.selectList(userWrapper); + Map userMap = users.stream() + .collect(Collectors.toMap(SysUser::getId, SysUser::getNickname, (v1, v2) -> v1)); + + for (MsMaplayerB layer : mapLayers) { + if (StrUtil.isNotBlank(layer.getRecordUser())) { + layer.setDisplayRecordUser(userMap.get(layer.getRecordUser())); + } + } + } + + // 5. 构建树结构:取第一级 + List parents = mapLayers.stream() + .filter(p -> StrUtil.isBlank(p.getParentId())) + .sorted(Comparator.comparing(MsMaplayerB::getRecordTime, Comparator.nullsLast(Comparator.reverseOrder()))) + .collect(Collectors.toList()); + + // 通过父级id分组子节点 + Map> childrenMap = mapLayers.stream() + .filter(p -> StrUtil.isNotBlank(p.getParentId())) + .collect(Collectors.groupingBy(MsMaplayerB::getParentId)); + + // 递归构建树 + convertTree(parents, childrenMap); + + return parents; + } + + /** + * 查询字典 "DTZJLX" 中需要排除的图层类型值 + */ + private Set getExcludeTypes() { + Set excludeTypes = new HashSet<>(); + try { + LambdaQueryWrapper dictWrapper = new LambdaQueryWrapper<>(); + dictWrapper.eq(SysDictionary::getDictCode, "DTZJLX"); + SysDictionary dictionary = sysDictionaryMapper.selectOne(dictWrapper); + if (dictionary != null) { + LambdaQueryWrapper itemWrapper = new LambdaQueryWrapper<>(); + itemWrapper.eq(SysDictionaryItems::getDictId, dictionary.getId()); + List items = sysDictionaryItemsMapper.selectList(itemWrapper); + if (items != null) { + excludeTypes = items.stream() + .map(SysDictionaryItems::getDictName) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + } + } + } catch (Exception e) { + // 字典查询失败时不中断主流程 + } + return excludeTypes; + } + + /** + * 递归转换图层数据为树结构 + */ + private void convertTree(List parents, Map> childrenMap) { + if (parents == null || parents.isEmpty()) { + return; + } + for (MsMaplayerB parent : parents) { + String id = parent.getId(); + List children = childrenMap.get(id); + if (children != null && !children.isEmpty()) { + parent.setChildren(children); + convertTree(children, childrenMap); + } + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerServiceImpl.java new file mode 100644 index 00000000..fbe64e5b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerServiceImpl.java @@ -0,0 +1,256 @@ +package com.yfd.platform.qgc_sys.mapLayer.service.impl; + +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplegendBMapper; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplayerBMapper; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerService; +import com.yfd.platform.utils.SecurityUtils; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 地图图层基础服务实现 + * + * @author migration + */ +@Service +public class MapLayerServiceImpl implements IMapLayerService { + + @Resource + private MsMaplayerBMapper msMaplayerBMapper; + + @Resource + private MsMaplegendBMapper msMaplegendBMapper; + + @Resource + private MsMapmoduleBMapper msMapmoduleBMapper; + + @Override + public boolean saveOrUpdate(MsMaplayerB layer) { + // 校验编码唯一性 + if (hasSameCode(layer)) { + throw new BizException("存在相同编码的数据"); + } + + // 当type等于SLDT/DXDT/YXDT,校验地图json格式 + String paramJson = layer.getParamJson(); + String type = layer.getType(); + if (("SLDT".equals(type) || "DXDT".equals(type) || "YXDT".equals(type)) + && StrUtil.isNotBlank(paramJson)) { + try { + JSONUtil.toBean(paramJson, HashMap.class); + } catch (Exception e) { + throw new BizException("请检查地图json格式"); + } + } + + if (StrUtil.isNotBlank(layer.getId())) { + // 修改 + msMaplayerBMapper.updateById(layer); + + // 判断是否启用且有子级,则子数据都要设置为启用状态 + if (layer.getEnable() != null && layer.getEnable() == 1 + && layer.getHasChildren() != null && layer.getHasChildren() == 1) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(MsMaplayerB::getIsDeleted, 0) + .like(MsMaplayerB::getFullPath, layer.getId() + ","); + List children = msMaplayerBMapper.selectList(wrapper); + for (MsMaplayerB child : children) { + MsMaplayerB temp = new MsMaplayerB(); + temp.setId(child.getId()); + temp.setEnable(1); + msMaplayerBMapper.updateById(temp); + } + } + } else { + // 新增 + String id = IdUtil.fastSimpleUUID(); + layer.setId(id); + + // 获取同级子节点,计算最大排序号 + List subList = getSubList(layer.getParentId()); + Integer maxOrderIndex = getMaxOrderIndex(subList); + layer.setOrderIndex(maxOrderIndex + 1); + + MsMaplayerB parentLayer = null; + if (StrUtil.isNotBlank(layer.getParentId())) { + // 获取父级信息 + parentLayer = msMaplayerBMapper.selectById(layer.getParentId()); + if (parentLayer == null) { + throw new BizException("获取父级图层信息失败.请检查父级图层(parentId)是否存在."); + } + // 设置key + layer.setKey(parentLayer.getKey() + "-" + layer.getOrderIndex()); + // 设置fullPath + layer.setFullPath(parentLayer.getFullPath() + layer.getKey() + ","); + // 设置treeLevel + layer.setTreeLevel(parentLayer.getTreeLevel() + 1); + // 设置hasChildren + layer.setHasChildren(0); + } else { + // 无父级,则为创建的顶级图层 + layer.setTreeLevel(1); + layer.setKey("0-" + layer.getOrderIndex()); + layer.setFullPath(layer.getKey() + ","); + layer.setHasChildren(0); + } + + // 设置可选 + layer.setCheckable(0); + // 设置不可用 + layer.setEnable(0); + + String userId = getCurrentUserId(); + layer.setRecordUser(userId); + layer.setModifyUser(userId); + layer.setRecordTime(new Date()); + + msMaplayerBMapper.insert(layer); + + // 新增完成后,设置父级hasChildren为1 + if (parentLayer != null) { + MsMaplayerB temp = new MsMaplayerB(); + temp.setId(parentLayer.getId()); + temp.setHasChildren(1); + msMaplayerBMapper.updateById(temp); + } + } + return true; + } + + @Override + public void delelteByIds(List ids) { + if (ids == null || ids.isEmpty()) { + return; + } + for (String id : ids) { + // 根据id查询是否有子级数据 + MsMaplayerB layer = msMaplayerBMapper.selectById(id); + if (layer == null) { + continue; + } + + LambdaQueryWrapper childWrapper = new LambdaQueryWrapper<>(); + childWrapper.eq(MsMaplayerB::getParentId, id); + List children = msMaplayerBMapper.selectList(childWrapper); + if (!children.isEmpty()) { + throw new BizException("有子级图层,无法删除."); + } + + // 判断是否启用 + if (layer.getEnable() != null && layer.getEnable() == 1) { + throw new BizException("无法删除已启用的图层."); + } + + // 判断是否已经关联了图例 + QueryWrapper legendWrapper = new QueryWrapper<>(); + legendWrapper.eq("LAYER_CODE", layer.getCode()); + legendWrapper.eq("IS_DELETED", 0); + List legendList = msMaplegendBMapper.selectList(legendWrapper); + if (!legendList.isEmpty()) { + throw new BizException("图层关联了图例,无法删除."); + } + + // 判断父级是否存在 + if (StrUtil.isBlank(layer.getParentId())) { + // 逻辑删除 + msMaplayerBMapper.deleteById(id); + } else { + MsMaplayerB parent = msMaplayerBMapper.selectById(layer.getParentId()); + // 逻辑删除 + msMaplayerBMapper.deleteById(id); + + // 判断父级下是否只有一个子级,如果是当前图层,则设置父级hasChildren为0 + if (parent != null) { + LambdaQueryWrapper siblingWrapper = new LambdaQueryWrapper<>(); + siblingWrapper.eq(MsMaplayerB::getParentId, parent.getId()); + List siblings = msMaplayerBMapper.selectList(siblingWrapper); + if (siblings.size() == 1 && id.equals(siblings.get(0).getId())) { + MsMaplayerB temp = new MsMaplayerB(); + temp.setId(parent.getId()); + temp.setHasChildren(0); + msMaplayerBMapper.updateById(temp); + } + } + } + + // 判断是否关联菜单,删除关联 + QueryWrapper moduleWrapper = new QueryWrapper<>(); + moduleWrapper.eq("RES_TYPE", "layer"); + moduleWrapper.eq("IS_DELETED", 0); + moduleWrapper.eq("RES_ID", id); + List moduleList = msMapmoduleBMapper.selectList(moduleWrapper); + if (!moduleList.isEmpty()) { + Set moduleIds = moduleList.stream() + .map(MsMapmoduleB::getId) + .collect(Collectors.toSet()); + msMapmoduleBMapper.deleteBatchIds(moduleIds); + } + } + } + + /** + * 获取当前用户ID + */ + private String getCurrentUserId() { + try { + return SecurityUtils.getUserId(); + } catch (Exception e) { + return null; + } + } + + /** + * 根据父级编码查询子一级数据 + */ + private List getSubList(String parentId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (StrUtil.isNotBlank(parentId)) { + wrapper.eq(MsMaplayerB::getParentId, parentId); + } else { + wrapper.eq(MsMaplayerB::getTreeLevel, 1); + } + wrapper.orderByAsc(MsMaplayerB::getOrderIndex); + return msMaplayerBMapper.selectList(wrapper); + } + + /** + * 获取最大排序号 + */ + private Integer getMaxOrderIndex(List list) { + if (list.isEmpty()) { + return 0; + } + return list.stream() + .sorted(Comparator.comparing(MsMaplayerB::getOrderIndex, Comparator.nullsLast(Comparator.reverseOrder()))) + .collect(Collectors.toList()) + .get(0) + .getOrderIndex(); + } + + /** + * 判断同级下是否有编码一样的数据 + */ + private boolean hasSameCode(MsMaplayerB layer) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(MsMaplayerB::getCode, layer.getCode()) + .eq(MsMaplayerB::getIsDeleted, 0); + List list = msMaplayerBMapper.selectList(wrapper); + if (list.isEmpty()) { + return false; + } + return !list.get(0).getId().equals(layer.getId()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java new file mode 100644 index 00000000..5152e819 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java @@ -0,0 +1,97 @@ +package com.yfd.platform.qgc_sys.mapLayer.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplegendBMapper; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 地图图例基础服务实现 + * + * @author migration + */ +@Service +public class MapLegendServiceImpl extends ServiceImpl + implements IMapLegendService { + + @Resource + private MsMapmoduleBMapper msMapmoduleBMapper; + + @Override + public void delelteByIds(List ids) { + if (CollectionUtil.isEmpty(ids)) { + return; + } + for (String id : ids) { + // 根据id查询是否有数据或者子级数据 + MsMaplegendB legend = this.getById(id); + if (legend == null) { + continue; + } + + LambdaQueryWrapper childWrapper = new LambdaQueryWrapper<>(); + childWrapper.eq(MsMaplegendB::getParentId, id) + .eq(MsMaplegendB::getIsDeleted, 0); + List children = this.list(childWrapper); + if (!children.isEmpty()) { + throw new BizException("有子级图例,无法删除."); + } + + // 判断是否内置的数据 + if (legend.getInternal() != null && legend.getInternal() == 1) { + throw new BizException("无法删除系统内置的图例."); + } + + // 判断是否启用 + if (legend.getEnable() != null && legend.getEnable() == 1) { + throw new BizException("无法删除已启用的图例."); + } + + // 判断图例是否关联了菜单 + QueryWrapper moduleWrapper = new QueryWrapper<>(); + moduleWrapper.eq("IS_DELETED", 0); + moduleWrapper.eq("RES_TYPE", "legend"); + moduleWrapper.eq("RES_ID", id); + List moduleList = msMapmoduleBMapper.selectList(moduleWrapper); + if (!moduleList.isEmpty()) { + throw new BizException("无法删除:图例关联了菜单."); + } + + // 判断父级是否存在 + if (StrUtil.isBlank(legend.getParentId())) { + this.removeById(id); // 逻辑删除 + return; + } + + // 删除数据 + this.removeById(id); // 逻辑删除 + + if (StrUtil.isNotBlank(legend.getParentId())) { + // 判断父级下是否只有一个子级,如果只有一个子级并且是当前图例,则需要设置父级的hasChildren为0 + MsMaplegendB parent = this.getById(legend.getParentId()); + if (parent != null) { + LambdaQueryWrapper siblingWrapper = new LambdaQueryWrapper<>(); + siblingWrapper.eq(MsMaplegendB::getParentId, parent.getId()); + List siblings = this.list(siblingWrapper); + if (siblings.size() == 1 && id.equals(siblings.get(0).getId())) { + MsMaplegendB updateParent = new MsMaplegendB(); + updateParent.setId(parent.getId()); + updateParent.setHasChildren(0); + this.updateById(updateParent); + } + } + } + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java new file mode 100644 index 00000000..09204d83 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java @@ -0,0 +1,101 @@ +package com.yfd.platform.qgc_sys.mapcfg.controller; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapcfg.service.IMapmoduleBService; +import com.yfd.platform.utils.DataSourceRequestUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 地图菜单配置控制层 + * + * @author migration + */ +@RestController +@RequestMapping("/mapmodule") +@Tag(name = "地图菜单配置") +public class MapmoduleBController { + + @Resource + private IMapmoduleBService mapmoduleBService; + + /** + * 条件过滤数据列表(Kendo UI 数据源) + */ + @Operation(summary = "条件过滤数据列表") + @PostMapping("/GetKendoList") + public ResponseResult getKendoList(@RequestBody DataSourceRequest dataSourceRequest) { + // 构建查询条件 + QueryWrapper wrapper = DataSourceRequestUtil.buildQueryWrapper( + dataSourceRequest, MsMapmoduleB.class); + + // 执行分页查询 + Page page = DataSourceRequestUtil.getPage(dataSourceRequest); + Page resultPage; + if (page != null) { + resultPage = mapmoduleBService.page(page, wrapper); + } else { + List list = mapmoduleBService.list(wrapper); + resultPage = new Page<>(); + resultPage.setRecords(list); + resultPage.setTotal(list.size()); + } + + // 构建 Kendo 数据源结果 + DataSourceResult dataSourceResult = new DataSourceResult<>(); + List dataList = resultPage.getRecords(); + dataSourceResult.setData(dataList); + dataSourceResult.setTotal(resultPage.getTotal()); + + // 翻译字典值(菜单名称) + if (dataList != null && !dataList.isEmpty()) { + mapmoduleBService.translateDict(dataList); + } + + return ResponseResult.successData(dataSourceResult); + } + + /** + * 地图图例关联系统及菜单 + */ + @Operation(summary = "地图图例关联系统及菜单") + @PostMapping("/save") + public ResponseResult saveOrUpdate(@RequestBody MsMapmoduleB mapmoduleB) { + if (mapmoduleB == null) { + throw new BizException("对象不能为空."); + } + if (StrUtil.isBlank(mapmoduleB.getModuleId())) { + throw new BizException("关联菜单(moduleId)不能为空."); + } + if (StrUtil.isBlank(mapmoduleB.getSystemId())) { + throw new BizException("关联系统(systemId)不能为空."); + } + if (StrUtil.isBlank(mapmoduleB.getResType())) { + throw new BizException("资源类型(resType: layer=图层,legend=图例,mapbox=地图)不能为空"); + } + if (StrUtil.isBlank(mapmoduleB.getResId())) { + throw new BizException("资源(resId)不能为空."); + } + return ResponseResult.successData(mapmoduleBService.saveOrUpdate(mapmoduleB)); + } + + /** + * 图例与系统菜单关联关系删除 + */ + @Operation(summary = "图例与系统菜单关联关系删除") + @PostMapping("/delete") + public ResponseResult deleteData(@RequestBody List ids) { + mapmoduleBService.delelteByIds(ids); + return ResponseResult.success("删除成功."); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java new file mode 100644 index 00000000..26c34a34 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java @@ -0,0 +1,36 @@ +package com.yfd.platform.qgc_sys.mapcfg.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; + +import java.util.List; + +/** + * 地图菜单配置服务接口 + * + * @author migration + */ +public interface IMapmoduleBService extends IService { + + /** + * 新增或修改 + * + * @param entity 实体 + * @return 是否成功 + */ + boolean saveOrUpdate(MsMapmoduleB entity); + + /** + * 翻译字典值(菜单名称) + * + * @param list 数据列表 + */ + void translateDict(List list); + + /** + * 根据ID列表删除关联关系 + * + * @param ids ID列表 + */ + void delelteByIds(List ids); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java new file mode 100644 index 00000000..d650bb50 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java @@ -0,0 +1,92 @@ +package com.yfd.platform.qgc_sys.mapcfg.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; +import com.yfd.platform.qgc_sys.mapcfg.service.IMapmoduleBService; +import com.yfd.platform.system.domain.SysMenu; +import com.yfd.platform.system.mapper.SysMenuMapper; +import com.yfd.platform.utils.SecurityUtils; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 地图菜单配置服务实现类 + * + * @author migration + */ +@Service +public class MapmoduleBServiceImpl extends ServiceImpl + implements IMapmoduleBService { + + @Resource + private SysMenuMapper sysMenuMapper; + + + @Override + public boolean saveOrUpdate(MsMapmoduleB entity) { + if (StrUtil.isBlank(entity.getId())) { + // 新增 + entity.setRecordUser(SecurityUtils.getUserId()); + this.baseMapper.insert(entity); + } else { + // 修改 + this.baseMapper.updateById(entity); + } + return true; + } + + @Override + public void delelteByIds(List ids) { + if (ids != null) { + for (String id : ids) { + this.baseMapper.deleteById(id); + } + } + } + + @Override + public void translateDict(List list) { + if (list == null || list.isEmpty()) { + return; + } + // 收集所有 moduleId + List moduleIds = list.stream() + .filter(it -> StrUtil.isNotBlank(it.getModuleId())) + .map(MsMapmoduleB::getModuleId) + .distinct() + .collect(Collectors.toList()); + + if (moduleIds.isEmpty()) { + return; + } + + // 查询本地菜单表获取名称 + LambdaQueryWrapper menuWrapper = new LambdaQueryWrapper<>(); + menuWrapper.in(SysMenu::getId, moduleIds); + List menus = sysMenuMapper.selectList(menuWrapper); + + Map menuMap = new HashMap<>(); + menuMap.put("common", "通用菜单"); + for (SysMenu menu : menus) { + menuMap.put(menu.getId(), menu.getName()); + } + + // 设置菜单名称 + for (MsMapmoduleB item : list) { + if (StrUtil.isNotBlank(item.getModuleId())) { + String name = menuMap.get(item.getModuleId()); + if (name != null) { + item.setModuleName(name); + } + } + } + } +} \ No newline at end of file From 6e4ff0a33f29ef4e644d9c810ae9b714ce7686ec Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 09:30:40 +0800 Subject: [PATCH 02/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yfd/platform/config/SecurityConfig.java | 1 + .../main/java/com/yfd/platform/config/SwaggerConfig.java | 9 +++++++++ .../qgc_eng/eq/service/impl/EngEqDataServiceImpl.java | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 58ec8889..c8c7cb72 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -65,6 +65,7 @@ public class SecurityConfig { .requestMatchers("/eq/**").permitAll() .requestMatchers("/env/**").permitAll() .requestMatchers("/warn/**").permitAll() + .requestMatchers("/overview/**").permitAll() .requestMatchers("/wt/**").permitAll() .requestMatchers("/fb/**").permitAll() .requestMatchers("/zq/**").permitAll() diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index f46f9a63..5e695eed 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -151,6 +151,15 @@ public class SwaggerConfig { .build(); } + @Bean + public GroupedOpenApi groupEnvOverviewApi() { + return GroupedOpenApi.builder() + .group("3.10 全过程-生态环保数据服务-首页(overview)") + .packagesToScan("com.yfd.platform.qgc_env.overview.controller") + .build(); + } + + diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index 5a7a0cfc..d470ba6e 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -5746,7 +5746,8 @@ public class EngEqDataServiceImpl implements EngEqDataService { } return switch (field) { case "id" -> "t.id"; - case "stcd" -> "t.stcd"; + case "rstcd" -> "t.stcd"; +// case "rstcd" -> "t.rstcd"; case "stnm", "ennm" -> "t.ennm"; case "baseId" -> "t.baseId"; case "baseName" -> "t.baseName"; From e57a353376facea4b0d06fba755d6fb58f1043fe Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 09:41:19 +0800 Subject: [PATCH 03/65] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E8=AE=BE=E6=96=BD=E6=A6=82=E8=A7=88=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OverviewController.java | 29 + .../entity/vo/OverviewMsstbprptVo.java | 72 +++ .../overview/service/OverviewService.java | 10 + .../service/impl/OverviewServiceImpl.java | 599 ++++++++++++++++++ 4 files changed, 710 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewMsstbprptVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java new file mode 100644 index 00000000..5858db55 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java @@ -0,0 +1,29 @@ +package com.yfd.platform.qgc_env.overview.controller; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_env.overview.service.OverviewService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/overview") +@Tag(name = "首页概览") +@Validated +public class OverviewController { + + @Resource + private OverviewService overviewService; + + @PostMapping("/msstbprpt/GetKendoList") + @Operation(summary = "首页基础设施概览列表") + public ResponseResult getMsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(overviewService.getMsstbprptList(dataSourceRequest)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewMsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewMsstbprptVo.java new file mode 100644 index 00000000..effa1e33 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewMsstbprptVo.java @@ -0,0 +1,72 @@ +package com.yfd.platform.qgc_env.overview.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Schema(description = "首页基础设施概览列表") +public class OverviewMsstbprptVo implements Serializable { + + private static final long serialVersionUID = 1L; + + private String id; + private String stcd; + private String stnm; + private String sttp; + private String sttpCode; + private String sttpName; + private String sttpFullPath; + private Integer sttpTreeLevel; + private String blprdId; + private Double lgtd; + private Double lttd; + private Double dtmel; + private String stlc; + private Integer usfl; + private String rstcd; + private String ennm; + private String baseId; + private String baseName; + private String hbrvcd; + private String hbrvcdName; + private String rvcd; + private String rvcdName; + private String addvcd; + private String addvcdName; + private String country; + private String countryName; + private String stCode; + private String stName; + private Date stdsdt; + private Date pststdt; + private Date pesstdt; + private Date ststdt; + private Date jcdt; + private Date stwddt; + private String introduce; + private String precis; + private String logo; + private String inffile; + private Integer dtin; + private String dtinName; + private Date dtinTm; + private Integer bldsttCode; + private String bldsttCcode; + private String bldsttCcodeName; + private Double inv; + private Integer invinmn; + private String dsun; + private String jbtxcs; + private Integer dtfrqcy; + private String remark; + private String vlsr; + private Date vlsrTm; + private Integer orderIndex; + private Integer baseStepSort; + private Integer rvcdStepSort; + private Integer rstcdStepSort; + private Integer siteStepSort; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java new file mode 100644 index 00000000..c8be8692 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java @@ -0,0 +1,10 @@ +package com.yfd.platform.qgc_env.overview.service; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.qgc_env.overview.entity.vo.OverviewMsstbprptVo; + +public interface OverviewService { + + DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest); +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java new file mode 100644 index 00000000..f516c562 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java @@ -0,0 +1,599 @@ +package com.yfd.platform.qgc_env.overview.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceLoadOptionsBase; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.qgc_env.overview.entity.vo.OverviewMsstbprptVo; +import com.yfd.platform.qgc_env.overview.service.OverviewService; +import com.yfd.platform.utils.QgcQueryWrapperUtil; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; + +@Service +public class OverviewServiceImpl implements OverviewService { + + @Resource + private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + + @Override + public DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + List selectFields = resolveSelectFields(dataSourceRequest == null ? null : dataSourceRequest.getSelect()); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildSelectSql(selectFields)) + .append(" FROM (") + .append(buildBaseSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql); + } + sql.append(buildOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, OverviewMsstbprptVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page == null ? list.size() : page.getTotal()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildBaseSql() { + return buildFbSql() + " UNION ALL " + buildDwSql() + " UNION ALL " + buildFpSql(); + } + + private String buildFbSql() { + return "SELECT " + + "fb.STCD AS id, " + + "fb.STCD AS stcd, " + + "fb.STNM AS stnm, " + + "fb.STTP AS sttp, " + + "fb.STTP AS sttpCode, " + + "sttp.STTP_NAME AS sttpName, " + + "sttp.FULL_PATH AS sttpFullPath, " + + "sttp.TREE_LEVEL AS sttpTreeLevel, " + + "CAST(fb.BLPRD AS VARCHAR2(64)) AS blprdId, " + + "fb.LGTD AS lgtd, " + + "fb.LTTD AS lttd, " + + "fb.ELEV AS dtmel, " + + "fb.STLC AS stlc, " + + "fb.USFL AS usfl, " + + "fb.RSTCD AS rstcd, " + + "eng.ENNM AS ennm, " + + "NVL(fb.BASE_ID, eng.BASE_ID) AS baseId, " + + "hb.BASENAME AS baseName, " + + "NVL(fb.HBRVCD, eng.HBRVCD) AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName, " + + "eng.RVCD AS rvcd, " + + "rv.RVNM AS rvcdName, " + + "eng.ADDVCD AS addvcd, " + + "addv.ADDVNM AS addvcdName, " + + "eng.COUNTRY AS country, " + + "country.COUNTRY_NAME AS countryName, " + + "CAST(NULL AS VARCHAR2(64)) AS stCode, " + + "CAST(NULL AS VARCHAR2(200)) AS stName, " + + "fb.STDSDT AS stdsdt, " + + "fb.PSTSTDT AS pststdt, " + + "fb.PESSTDT AS pesstdt, " + + "fb.SWDT AS ststdt, " + + "fb.JCDT AS jcdt, " + + "fb.WDDT AS stwddt, " + + "fb.INTRODUCE AS introduce, " + + "fb.INTRODUCE AS precis, " + + "fb.LOGO AS logo, " + + "fb.INFFILE AS inffile, " + + "fb.DTIN AS dtin, " + + "CASE WHEN NVL(fb.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END AS dtinName, " + + "fb.DTIN_TM AS dtinTm, " + + "fb.BLDSTT_CODE AS bldsttCode, " + + "CASE fb.BLDSTT_CODE WHEN 0 THEN '0' WHEN 1 THEN '1' WHEN 2 THEN '2' ELSE NULL END AS bldsttCcode, " + + "CASE fb.BLDSTT_CODE WHEN 0 THEN '未建/规划' WHEN 1 THEN '在建' WHEN 2 THEN '已建' ELSE NULL END AS bldsttCcodeName, " + + "fb.INV AS inv, " + + "fb.INVINMN AS invinmn, " + + "fb.DSUN AS dsun, " + + "fb.JBTXCS AS jbtxcs, " + + "fb.DTFRQCY AS dtfrqcy, " + + "fb.REMARK AS remark, " + + "fb.VLSR AS vlsr, " + + "fb.VLSR_TM AS vlsrTm, " + + "fb.ORDER_INDEX AS orderIndex, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(hbrv.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "NVL(fb.ORDER_INDEX, 999999) AS siteStepSort " + + "FROM SD_FBRD_B_H fb " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fb.STTP AND NVL(sttp.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fb.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fb.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(fb.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(fb.BASE_ID, eng.BASE_ID) " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " + + "LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " + + "LEFT JOIN SD_COUNTRY_B country ON country.COUNTRY_ID = eng.COUNTRY AND NVL(country.ENABLED, 1) = 1 "; + } + + private String buildDwSql() { + return "SELECT " + + "dw.STCD AS id, " + + "dw.STCD AS stcd, " + + "dw.STNM AS stnm, " + + "dw.STTP AS sttp, " + + "dw.STTP AS sttpCode, " + + "sttp.STTP_NAME AS sttpName, " + + "sttp.FULL_PATH AS sttpFullPath, " + + "sttp.TREE_LEVEL AS sttpTreeLevel, " + + "CAST(NULL AS VARCHAR2(64)) AS blprdId, " + + "dw.LGTD AS lgtd, " + + "dw.LTTD AS lttd, " + + "dw.ELEV AS dtmel, " + + "dw.STLC AS stlc, " + + "dw.USFL AS usfl, " + + "dw.RSTCD AS rstcd, " + + "eng.ENNM AS ennm, " + + "NVL(dw.BASE_ID, eng.BASE_ID) AS baseId, " + + "hb.BASENAME AS baseName, " + + "NVL(dw.HBRVCD, eng.HBRVCD) AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName, " + + "eng.RVCD AS rvcd, " + + "rv.RVNM AS rvcdName, " + + "eng.ADDVCD AS addvcd, " + + "addv.ADDVNM AS addvcdName, " + + "eng.COUNTRY AS country, " + + "country.COUNTRY_NAME AS countryName, " + + "CAST(NULL AS VARCHAR2(64)) AS stCode, " + + "CAST(NULL AS VARCHAR2(200)) AS stName, " + + "dw.STDSDT AS stdsdt, " + + "dw.PSTSTDT AS pststdt, " + + "dw.PESSTDT AS pesstdt, " + + "dw.SWDT AS ststdt, " + + "dw.JCDT AS jcdt, " + + "dw.WDDT AS stwddt, " + + "dw.INTRODUCE AS introduce, " + + "dw.INTRODUCE AS precis, " + + "dw.LOGO AS logo, " + + "dw.INFFILE AS inffile, " + + "dw.DTIN AS dtin, " + + "CASE WHEN NVL(dw.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END AS dtinName, " + + "dw.DTIN_TM AS dtinTm, " + + "dw.BLDSTT_CODE AS bldsttCode, " + + "CASE dw.BLDSTT_CODE WHEN 0 THEN '0' WHEN 1 THEN '1' WHEN 2 THEN '2' ELSE NULL END AS bldsttCcode, " + + "CASE dw.BLDSTT_CODE WHEN 0 THEN '未建/规划' WHEN 1 THEN '在建' WHEN 2 THEN '已建' ELSE NULL END AS bldsttCcodeName, " + + "dw.INV AS inv, " + + "dw.INVINMN AS invinmn, " + + "CAST(NULL AS VARCHAR2(500)) AS dsun, " + + "dw.QTSSJBTX AS jbtxcs, " + + "dw.DTFRQCY AS dtfrqcy, " + + "dw.REMARK AS remark, " + + "dw.VLSR AS vlsr, " + + "dw.VLSR_TM AS vlsrTm, " + + "dw.ORDER_INDEX AS orderIndex, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(hbrv.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "NVL(dw.ORDER_INDEX, 999999) AS siteStepSort " + + "FROM SD_DW_B_H dw " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = dw.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = dw.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(dw.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(dw.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(dw.BASE_ID, eng.BASE_ID) " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " + + "LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " + + "LEFT JOIN SD_COUNTRY_B country ON country.COUNTRY_ID = eng.COUNTRY AND NVL(country.ENABLED, 1) = 1 " + + "WHERE NVL(dw.IS_DELETED, 0) = 0 "; + } + + private String buildFpSql() { + return "SELECT " + + "fp.STCD AS id, " + + "fp.STCD AS stcd, " + + "fp.STNM AS stnm, " + + "fp.STTP AS sttp, " + + "fp.STTP AS sttpCode, " + + "sttp.STTP_NAME AS sttpName, " + + "sttp.FULL_PATH AS sttpFullPath, " + + "sttp.TREE_LEVEL AS sttpTreeLevel, " + + "CAST(fp.BLPRD AS VARCHAR2(64)) AS blprdId, " + + "fp.LGTD AS lgtd, " + + "fp.LTTD AS lttd, " + + "fp.ELEV AS dtmel, " + + "fp.STLC AS stlc, " + + "fp.USFL AS usfl, " + + "fp.RSTCD AS rstcd, " + + "eng.ENNM AS ennm, " + + "eng.BASE_ID AS baseId, " + + "hb.BASENAME AS baseName, " + + "eng.HBRVCD AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName, " + + "eng.RVCD AS rvcd, " + + "rv.RVNM AS rvcdName, " + + "eng.ADDVCD AS addvcd, " + + "addv.ADDVNM AS addvcdName, " + + "eng.COUNTRY AS country, " + + "country.COUNTRY_NAME AS countryName, " + + "CAST(NULL AS VARCHAR2(64)) AS stCode, " + + "CAST(NULL AS VARCHAR2(200)) AS stName, " + + "fp.STDSDT AS stdsdt, " + + "fp.PSTSTDT AS pststdt, " + + "fp.PESSTDT AS pesstdt, " + + "fp.SWDT AS ststdt, " + + "fp.JCDT AS jcdt, " + + "fp.WDDT AS stwddt, " + + "fp.INTRODUCE AS introduce, " + + "fp.INTRODUCE AS precis, " + + "fp.LOGO AS logo, " + + "fp.INFFILE AS inffile, " + + "fp.DTIN AS dtin, " + + "CASE WHEN NVL(fp.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END AS dtinName, " + + "fp.DTIN_TM AS dtinTm, " + + "fp.BLDSTT_CODE AS bldsttCode, " + + "CASE fp.BLDSTT_CODE WHEN 0 THEN '0' WHEN 1 THEN '1' WHEN 2 THEN '2' ELSE NULL END AS bldsttCcode, " + + "CASE fp.BLDSTT_CODE WHEN 0 THEN '未建/规划' WHEN 1 THEN '在建' WHEN 2 THEN '已建' ELSE NULL END AS bldsttCcodeName, " + + "fp.INV AS inv, " + + "fp.INVINMN AS invinmn, " + + "CAST(NULL AS VARCHAR2(500)) AS dsun, " + + "fp.JBTXCS AS jbtxcs, " + + "fp.DTFRQCY AS dtfrqcy, " + + "fp.REMARK AS remark, " + + "fp.VLSR AS vlsr, " + + "fp.VLSR_TM AS vlsrTm, " + + "fp.ORDER_INDEX AS orderIndex, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(hbrv.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "NVL(fp.ORDER_INDEX, 999999) AS siteStepSort " + + "FROM SD_FPSS_B_H fp " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + "LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " + + "LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " + + "LEFT JOIN SD_COUNTRY_B country ON country.COUNTRY_ID = eng.COUNTRY AND NVL(country.ENABLED, 1) = 1 "; + } + + private List resolveSelectFields(List select) { + List fields = CollUtil.isEmpty(select) + ? new ArrayList<>(buildSelectMap().keySet()) + : new ArrayList<>(select); + LinkedHashSet uniqueFields = new LinkedHashSet<>(); + for (String field : fields) { + if (StrUtil.isNotBlank(field)) { + uniqueFields.add(field.trim()); + } + } + if (uniqueFields.isEmpty()) { + uniqueFields.add("stcd"); + } + return new ArrayList<>(uniqueFields); + } + + private String buildSelectSql(List selectFields) { + Map columnMap = buildSelectMap(); + List selectParts = new ArrayList<>(); + for (String field : selectFields) { + String column = columnMap.get(field); + if (StrUtil.isNotBlank(column)) { + selectParts.add(column); + } else { + selectParts.add("NULL AS \"" + field + "\""); + } + } + if (selectParts.isEmpty()) { + selectParts.add("t.stcd AS \"stcd\""); + } + return String.join(", ", selectParts); + } + + private Map buildSelectMap() { + Map columnMap = new LinkedHashMap<>(); + columnMap.put("id", "t.id AS \"id\""); + columnMap.put("stcd", "t.stcd AS \"stcd\""); + columnMap.put("stnm", "t.stnm AS \"stnm\""); + columnMap.put("sttp", "t.sttp AS \"sttp\""); + columnMap.put("sttpCode", "t.sttpCode AS \"sttpCode\""); + columnMap.put("sttpName", "t.sttpName AS \"sttpName\""); + columnMap.put("sttpFullPath", "t.sttpFullPath AS \"sttpFullPath\""); + columnMap.put("sttpTreeLevel", "t.sttpTreeLevel AS \"sttpTreeLevel\""); + columnMap.put("blprdId", "t.blprdId AS \"blprdId\""); + columnMap.put("lgtd", "t.lgtd AS \"lgtd\""); + columnMap.put("lttd", "t.lttd AS \"lttd\""); + columnMap.put("dtmel", "t.dtmel AS \"dtmel\""); + columnMap.put("stlc", "t.stlc AS \"stlc\""); + columnMap.put("usfl", "t.usfl AS \"usfl\""); + columnMap.put("rstcd", "t.rstcd AS \"rstcd\""); + columnMap.put("ennm", "t.ennm AS \"ennm\""); + columnMap.put("baseId", "t.baseId AS \"baseId\""); + columnMap.put("baseName", "t.baseName AS \"baseName\""); + columnMap.put("hbrvcd", "t.hbrvcd AS \"hbrvcd\""); + columnMap.put("hbrvcdName", "t.hbrvcdName AS \"hbrvcdName\""); + columnMap.put("rvcd", "t.rvcd AS \"rvcd\""); + columnMap.put("rvcdName", "t.rvcdName AS \"rvcdName\""); + columnMap.put("addvcd", "t.addvcd AS \"addvcd\""); + columnMap.put("addvcdName", "t.addvcdName AS \"addvcdName\""); + columnMap.put("country", "t.country AS \"country\""); + columnMap.put("countryName", "t.countryName AS \"countryName\""); + columnMap.put("stCode", "t.stCode AS \"stCode\""); + columnMap.put("stName", "t.stName AS \"stName\""); + columnMap.put("stdsdt", "t.stdsdt AS \"stdsdt\""); + columnMap.put("pststdt", "t.pststdt AS \"pststdt\""); + columnMap.put("pesstdt", "t.pesstdt AS \"pesstdt\""); + columnMap.put("ststdt", "t.ststdt AS \"ststdt\""); + columnMap.put("jcdt", "t.jcdt AS \"jcdt\""); + columnMap.put("stwddt", "t.stwddt AS \"stwddt\""); + columnMap.put("introduce", "t.introduce AS \"introduce\""); + columnMap.put("precis", "t.precis AS \"precis\""); + columnMap.put("logo", "t.logo AS \"logo\""); + columnMap.put("inffile", "t.inffile AS \"inffile\""); + columnMap.put("dtin", "t.dtin AS \"dtin\""); + columnMap.put("dtinName", "t.dtinName AS \"dtinName\""); + columnMap.put("dtinTm", "t.dtinTm AS \"dtinTm\""); + columnMap.put("bldsttCode", "t.bldsttCode AS \"bldsttCode\""); + columnMap.put("bldsttCcode", "t.bldsttCcode AS \"bldsttCcode\""); + columnMap.put("bldsttCcodeName", "t.bldsttCcodeName AS \"bldsttCcodeName\""); + columnMap.put("inv", "t.inv AS \"inv\""); + columnMap.put("invinmn", "t.invinmn AS \"invinmn\""); + columnMap.put("dsun", "t.dsun AS \"dsun\""); + columnMap.put("jbtxcs", "t.jbtxcs AS \"jbtxcs\""); + columnMap.put("dtfrqcy", "t.dtfrqcy AS \"dtfrqcy\""); + columnMap.put("remark", "t.remark AS \"remark\""); + columnMap.put("vlsr", "t.vlsr AS \"vlsr\""); + columnMap.put("vlsrTm", "t.vlsrTm AS \"vlsrTm\""); + columnMap.put("orderIndex", "t.orderIndex AS \"orderIndex\""); + columnMap.put("baseStepSort", "t.baseStepSort AS \"baseStepSort\""); + columnMap.put("rvcdStepSort", "t.rvcdStepSort AS \"rvcdStepSort\""); + columnMap.put("rstcdStepSort", "t.rstcdStepSort AS \"rstcdStepSort\""); + columnMap.put("siteStepSort", "t.siteStepSort AS \"siteStepSort\""); + return columnMap; + } + + private String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + if (StrUtil.isBlank(field)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + String column = mapFilterColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "overviewP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add("#{map." + key + "}"); + } + if (placeholders.isEmpty()) { + return ""; + } + return column + ("ni".equals(operator) ? " NOT IN (" : " IN (") + String.join(", ", placeholders) + ")"; + } + Object value = filter.getValue(); + if (value == null) { + return ""; + } + String key = "overviewP" + indexHolder[0]++; + return switch (operator) { + case "eq" -> { + paramMap.put(key, value); + yield column + " = #{map." + key + "}"; + } + case "neq" -> { + paramMap.put(key, value); + yield column + " <> #{map." + key + "}"; + } + case "contains" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " NOT LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + value); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, value); + yield column + " > #{map." + key + "}"; + } + case "gte" -> { + paramMap.put(key, value); + yield column + " >= #{map." + key + "}"; + } + case "lt" -> { + paramMap.put(key, value); + yield column + " < #{map." + key + "}"; + } + case "lte" -> { + paramMap.put(key, value); + yield column + " <= #{map." + key + "}"; + } + default -> ""; + }; + } + + private String mapFilterColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "id" -> "t.id"; + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "sttp" -> "t.sttp"; + case "sttpCode" -> "t.sttpCode"; + case "sttpName" -> "t.sttpName"; + case "sttpFullPath" -> "t.sttpFullPath"; + case "sttpTreeLevel" -> "t.sttpTreeLevel"; + case "blprdId" -> "t.blprdId"; + case "lgtd" -> "t.lgtd"; + case "lttd" -> "t.lttd"; + case "dtmel" -> "t.dtmel"; + case "stlc" -> "t.stlc"; + case "usfl" -> "t.usfl"; + case "rstcd" -> "t.rstcd"; + case "ennm" -> "t.ennm"; + case "baseId" -> "t.baseId"; + case "baseName" -> "t.baseName"; + case "hbrvcd" -> "t.hbrvcd"; + case "hbrvcdName" -> "t.hbrvcdName"; + case "rvcd" -> "t.rvcd"; + case "rvcdName" -> "t.rvcdName"; + case "addvcd" -> "t.addvcd"; + case "addvcdName" -> "t.addvcdName"; + case "country" -> "t.country"; + case "countryName" -> "t.countryName"; + case "stCode" -> "t.stCode"; + case "stName" -> "t.stName"; + case "introduce" -> "t.introduce"; + case "precis" -> "t.precis"; + case "logo" -> "t.logo"; + case "inffile" -> "t.inffile"; + case "dtin" -> "t.dtin"; + case "dtinName" -> "t.dtinName"; + case "dtinTm" -> "t.dtinTm"; + case "bldsttCode" -> "t.bldsttCode"; + case "bldsttCcode" -> "t.bldsttCcode"; + case "bldsttCcodeName" -> "t.bldsttCcodeName"; + case "inv" -> "t.inv"; + case "invinmn" -> "t.invinmn"; + case "dsun" -> "t.dsun"; + case "jbtxcs" -> "t.jbtxcs"; + case "dtfrqcy" -> "t.dtfrqcy"; + case "remark" -> "t.remark"; + case "vlsr" -> "t.vlsr"; + case "vlsrTm" -> "t.vlsrTm"; + case "orderIndex" -> "t.orderIndex"; + case "baseStepSort" -> "t.baseStepSort"; + case "rvcdStepSort" -> "t.rvcdStepSort"; + case "rstcdStepSort" -> "t.rstcdStepSort"; + case "siteStepSort" -> "t.siteStepSort"; + case "stdsdt" -> "t.stdsdt"; + case "pststdt" -> "t.pststdt"; + case "pesstdt" -> "t.pesstdt"; + case "ststdt" -> "t.ststdt"; + case "jcdt" -> "t.jcdt"; + case "stwddt" -> "t.stwddt"; + default -> null; + }; + } + + private String buildOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY t.baseStepSort ASC, t.rvcdStepSort ASC, t.rstcdStepSort ASC, t.siteStepSort ASC, t.stnm ASC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapFilterColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir + " NULLS LAST"); + } + if (orderItems.isEmpty()) { + return " ORDER BY t.baseStepSort ASC, t.rvcdStepSort ASC, t.rstcdStepSort ASC, t.siteStepSort ASC, t.stnm ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private List normalizeValues(Object value) { + List values = new ArrayList<>(); + collectValues(value, values); + return values; + } + + private void collectValues(Object value, List values) { + if (value == null) { + return; + } + if (value instanceof List list) { + for (Object item : list) { + collectValues(item, values); + } + return; + } + if (value instanceof Object[] array) { + for (Object item : array) { + collectValues(item, values); + } + return; + } + values.add(value); + } +} From 156e4492679571c4685575aaed10cd0ae2776a93 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 10:17:27 +0800 Subject: [PATCH 04/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=9B=91?= =?UTF-8?q?=E6=B5=8B=E6=95=B0=E6=8D=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_env/wq/controller/EnvWqDataController.java | 5 +++-- .../qgc_env/wq/entity/vo/WqOperateRequest.java | 13 +++++++++++++ .../wt/controller/SdWTMonitorController.java | 5 +++-- .../qgc_env/wt/entity/vo/WtOperateRequest.java | 13 +++++++++++++ .../qgc_env/zq/controller/ZqMonitorController.java | 5 +++-- .../qgc_env/zq/entity/vo/ZqOperateRequest.java | 13 +++++++++++++ 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wq/entity/vo/WqOperateRequest.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wt/entity/vo/WtOperateRequest.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/zq/entity/vo/ZqOperateRequest.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java index 6d0a35b7..f944ba50 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_env.wq.controller; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; 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.service.EnvWqDataService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -59,8 +60,8 @@ public class EnvWqDataController { @PostMapping("/updateWqRsData") @Operation(summary = "修改水质小时数据") - public ResponseResult updateWqRsData(@RequestBody Map updateData) { - envWqDataService.updateWqRsData(updateData); + public ResponseResult updateWqRsData(@RequestBody WqOperateRequest wqOperateRequest) { + envWqDataService.updateWqRsData(wqOperateRequest.getUpdateData()); return ResponseResult.success(); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/entity/vo/WqOperateRequest.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/entity/vo/WqOperateRequest.java new file mode 100644 index 00000000..4b7d5050 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/entity/vo/WqOperateRequest.java @@ -0,0 +1,13 @@ +package com.yfd.platform.qgc_env.wq.entity.vo; + +import lombok.Data; + +import java.util.Map; + +@Data +public class WqOperateRequest { + + private String source; + + private Map updateData; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java index 6dccdf94..f72e1270 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java @@ -8,6 +8,7 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.exception.BizException; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo; +import com.yfd.platform.qgc_env.wt.entity.vo.WtOperateRequest; import com.yfd.platform.qgc_env.wt.entity.vo.WtrvInfo; import com.yfd.platform.qgc_env.wt.entity.vo.WtrvAmendSaveVo; import com.yfd.platform.qgc_env.wt.service.*; @@ -245,8 +246,8 @@ public class SdWTMonitorController { @PostMapping("/cxDetail/updateWtvtRData") @Operation(summary = "修改垂向水温数据") - public ResponseResult updateWtvtRData(@RequestBody Map updateData) { - sdWtvtRService.updateWtvtRData(updateData); + public ResponseResult updateWtvtRData(@RequestBody WtOperateRequest wtOperateRequest) { + sdWtvtRService.updateWtvtRData(wtOperateRequest.getUpdateData()); return ResponseResult.success(); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/entity/vo/WtOperateRequest.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/entity/vo/WtOperateRequest.java new file mode 100644 index 00000000..cdddcf9b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/entity/vo/WtOperateRequest.java @@ -0,0 +1,13 @@ +package com.yfd.platform.qgc_env.wt.entity.vo; + +import lombok.Data; + +import java.util.Map; + +@Data +public class WtOperateRequest { + + private String source; + + private Map updateData; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/zq/controller/ZqMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/zq/controller/ZqMonitorController.java index 91cd4c78..2e378585 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/zq/controller/ZqMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/zq/controller/ZqMonitorController.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_env.zq.controller; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo; +import com.yfd.platform.qgc_env.zq.entity.vo.ZqOperateRequest; import com.yfd.platform.qgc_env.zq.service.ZqMonitorService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -65,8 +66,8 @@ public class ZqMonitorController { @PostMapping("/river/updateRiverRData") @Operation(summary = "修改流量站小时数据") - public ResponseResult updateRiverRData(@RequestBody Map updateData) { - zqMonitorService.updateRiverRData(updateData); + public ResponseResult updateRiverRData(@RequestBody ZqOperateRequest zqOperateRequest) { + zqMonitorService.updateRiverRData(zqOperateRequest.getUpdateData()); return ResponseResult.success(); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/zq/entity/vo/ZqOperateRequest.java b/backend/src/main/java/com/yfd/platform/qgc_env/zq/entity/vo/ZqOperateRequest.java new file mode 100644 index 00000000..5073c1e7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/zq/entity/vo/ZqOperateRequest.java @@ -0,0 +1,13 @@ +package com.yfd.platform.qgc_env.zq.entity.vo; + +import lombok.Data; + +import java.util.Map; + +@Data +public class ZqOperateRequest { + + private String source; + + private Map updateData; +} From 23005d7cfcea3cf43d41893a002d7c50e06415db Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 11:07:18 +0800 Subject: [PATCH 05/65] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E7=8E=AF?= =?UTF-8?q?=E4=BF=9D=E8=AE=BE=E6=96=BD=E8=BF=90=E8=A1=8C=E7=8A=B6=E5=86=B5?= =?UTF-8?q?=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_base/entity/vo/BatchDeleteAo.java | 3 + .../controller/OverviewController.java | 6 + .../overview/entity/vo/OverviewOpedVo.java | 44 ++ .../overview/service/OverviewService.java | 3 + .../service/impl/OverviewServiceImpl.java | 526 ++++++++++++++++++ 5 files changed, 582 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/entity/vo/BatchDeleteAo.java b/backend/src/main/java/com/yfd/platform/qgc_base/entity/vo/BatchDeleteAo.java index 2fbb7069..f9bab6ca 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/entity/vo/BatchDeleteAo.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/entity/vo/BatchDeleteAo.java @@ -12,6 +12,9 @@ public class BatchDeleteAo implements Serializable { private static final long serialVersionUID = 1L; + @Schema(description = "数据来源") + private String source; + @Schema(description = "数据类型") private String dataType; diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java index 5858db55..a3ed0a61 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/controller/OverviewController.java @@ -26,4 +26,10 @@ public class OverviewController { public ResponseResult getMsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(overviewService.getMsstbprptList(dataSourceRequest)); } + + @PostMapping("/oped/GetKendoListCust") + @Operation(summary = "首页环保设施运行状况明细") + public ResponseResult getOpedList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(overviewService.getOpedList(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java new file mode 100644 index 00000000..32fb39d7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java @@ -0,0 +1,44 @@ +package com.yfd.platform.qgc_env.overview.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Schema(description = "首页环保设施运行状况明细") +public class OverviewOpedVo implements Serializable { + + private static final long serialVersionUID = 1L; + + private String sttpName; + private String baseId; + private String stcd; + private String stnm; + private String sttpCode; + private String baseName; + private String rstcd; + private String ennm; + private String bldsttCcode; + private String bldsttCcodeName; + private Date dtinTm; + private Integer dtin; + private String dtinName; + private Integer runState; + private String runStateName; + private Integer stdState; + private String stdStateName; + private Integer stdSstate; + private String stdSstateName; + private Integer mway; + private String mwayName; + private String hbrvcd; + private String hbrvcdName; + private Integer baseStepSort; + private Integer baseStepsort; + private Integer rvcdStepSort; + private Integer rstcdStepSort; + private Integer rstcdStepsort; + private Integer siteStepSort; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java index c8be8692..481e665f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/OverviewService.java @@ -3,8 +3,11 @@ package com.yfd.platform.qgc_env.overview.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.overview.entity.vo.OverviewMsstbprptVo; +import com.yfd.platform.qgc_env.overview.entity.vo.OverviewOpedVo; public interface OverviewService { DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest); + + DataSourceResult getOpedList(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java index f516c562..a33c4f14 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java @@ -6,19 +6,24 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.GroupHelper; +import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.qgc_env.overview.entity.vo.OverviewMsstbprptVo; +import com.yfd.platform.qgc_env.overview.entity.vo.OverviewOpedVo; import com.yfd.platform.qgc_env.overview.service.OverviewService; import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.time.Year; @Service public class OverviewServiceImpl implements OverviewService { @@ -58,6 +63,49 @@ public class OverviewServiceImpl implements OverviewService { return result; } + @Override + @SuppressWarnings("unchecked") + public DataSourceResult getOpedList(DataSourceRequest dataSourceRequest) { + DataSourceResult result = new DataSourceResult<>(); + result.setAggregates(new HashMap<>()); + if (dataSourceRequest == null) { + result.setData(new ArrayList<>()); + result.setTotal(0L); + return result; + } + + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + Map paramMap = new HashMap<>(); + paramMap.put("stateYear", resolveOpedStateYear()); + + String filterSql = buildOpedFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (CollUtil.isNotEmpty(dataSourceRequest.getGroup())) { + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + String groupSql = buildOpedGroupSql(buildOpedDetailSql(null, filterSql), groupInfos); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List> rows = microservicDynamicSQLMapper.pageAllList(page, groupSql, paramMap); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal(0L); + return result; + } + + String sql = buildOpedDetailSql(dataSourceRequest.getSelect(), filterSql) + + buildOpedOrderBySql(dataSourceRequest.getSort()); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql, paramMap, OverviewOpedVo.class + ); + result.setData(list); + result.setTotal(page == null ? list.size() : page.getTotal()); + return result; + } + private String buildBaseSql() { return buildFbSql() + " UNION ALL " + buildDwSql() + " UNION ALL " + buildFpSql(); } @@ -572,6 +620,484 @@ public class OverviewServiceImpl implements OverviewService { return " ORDER BY " + String.join(", ", orderItems); } + private Integer resolveOpedStateYear() { + return Year.now().getValue(); + } + + private String buildOpedDetailSql(List selectFields, String filterSql) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildOpedSelectSql(selectFields)) + .append(" FROM (") + .append(buildOpedBaseSql()) + .append(") t WHERE 1 = 1 "); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql); + } + return sql.toString(); + } + + private String buildOpedBaseSql() { + return "SELECT " + + "src.sttpName AS sttpName, " + + "src.baseId AS baseId, " + + "src.stcd AS stcd, " + + "src.stnm AS stnm, " + + "src.sttpCode AS sttpCode, " + + "src.baseName AS baseName, " + + "src.rstcd AS rstcd, " + + "src.ennm AS ennm, " + + "src.bldsttCcode AS bldsttCcode, " + + "src.bldsttCcodeName AS bldsttCcodeName, " + + "src.dtinTm AS dtinTm, " + + "src.dtin AS dtin, " + + "src.dtinName AS dtinName, " + + "state.RUN_STATE AS runState, " + + "CASE WHEN state.RUN_STATE = 1 THEN '运行中' " + + "WHEN state.RUN_STATE IN (0, 2) THEN '未运行' ELSE NULL END AS runStateName, " + + "state.STD_STATE AS stdState, " + + "CASE WHEN state.STD_STATE = 1 THEN '达标' " + + "WHEN state.STD_STATE = 2 THEN '无数据' " + + "WHEN state.STD_STATE IN (0, 3) THEN '未达标' ELSE NULL END AS stdStateName, " + + "state.STD_SSTATE AS stdSstate, " + + "CASE WHEN state.STD_SSTATE = 1 THEN '正常运行' " + + "WHEN state.STD_SSTATE IN (0, 2) THEN '暂无数据' " + + "WHEN state.STD_SSTATE = 3 THEN '未正常运行' ELSE NULL END AS stdSstateName, " + + "CAST(NULL AS NUMBER(10)) AS mway, " + + "CAST(NULL AS VARCHAR2(32)) AS mwayName, " + + "src.hbrvcd AS hbrvcd, " + + "src.hbrvcdName AS hbrvcdName, " + + "src.baseStepSort AS baseStepSort, " + +// "src.baseStepSort AS baseStepsort, " + + "src.rvcdStepSort AS rvcdStepSort, " + + "src.rstcdStepSort AS rstcdStepSort, " + +// "src.rstcdStepSort AS rstcdStepsort, " + + "src.siteStepSort AS siteStepSort " + +// "#{map.stateYear} AS yr " + + "FROM (" + buildOpedUnionSql() + ") src " + + "LEFT JOIN MS_STSTATE_T state ON state.STCD = src.stcd " + + "AND NVL(state.IS_DELETED, 0) = 0 " + + "AND state.YR = #{map.stateYear}"; + } + + private String buildOpedUnionSql() { + return buildOpedBranchSql( + "fb.STCD", "fb.STNM", "'FB'", "child.STTP_NAME", "NVL(fb.BASE_ID, eng.BASE_ID)", + "hb.BASENAME", "fb.RSTCD", "eng.ENNM", "NVL(fb.HBRVCD, eng.HBRVCD)", "hbrv.HBRVNM", + "CAST(fb.BLDSTT_CODE AS VARCHAR2(10))", buildBldsttNameExpr("fb.BLDSTT_CODE"), "fb.DTIN_TM", "fb.DTIN", + "CASE WHEN NVL(fb.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(fb.ORDER_INDEX, 999999)", + "SD_FBRD_B_H fb", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = fb.STTP AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fb.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fb.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(fb.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(fb.BASE_ID, eng.BASE_ID) " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "1 = 1" + ) + " UNION ALL " + + buildOpedBranchSql( + "vp.STCD", "vp.STNM", "'VP'", "child.STTP_NAME", "NVL(vp.BASE_ID, eng.BASE_ID)", + "hb.BASENAME", "vp.RSTCD", "eng.ENNM", "NVL(vp.HBRVCD, eng.HBRVCD)", "hbrv.HBRVNM", + "CAST(vp.BLDSTT_CODE AS VARCHAR2(10))", buildBldsttNameExpr("vp.BLDSTT_CODE"), "vp.DTIN_TM", "vp.DTIN", + "CASE WHEN NVL(vp.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(vp.ORDER_INDEX, 999999)", + "SD_VP_B_H vp", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = vp.STTP AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = vp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(vp.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(vp.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(vp.BASE_ID, eng.BASE_ID) " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "NVL(vp.IS_DELETED, 0) = 0" + ) + " UNION ALL " + + buildOpedBranchSql( + "va.STCD", "va.STNM", "'VA'", "child.STTP_NAME", "NVL(va.BASE_ID, eng.BASE_ID)", + "hb.BASENAME", "va.RSTCD", "eng.ENNM", "NVL(va.HBRVCD, eng.HBRVCD)", "hbrv.HBRVNM", + "CAST(va.BLDSTT_CODE AS VARCHAR2(10))", buildBldsttNameExpr("va.BLDSTT_CODE"), "va.DTIN_TM", "va.DTIN", + "CASE WHEN NVL(va.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(va.ORDER_INDEX, 999999)", + "SD_VA_B_H va", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = va.STTP AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = va.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(va.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(va.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(va.BASE_ID, eng.BASE_ID) " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "NVL(va.IS_DELETED, 0) = 0" + ) + " UNION ALL " + + buildOpedBranchSql( + "fh.STCD", "fh.STNM", "'FH'", "child.STTP_NAME", "NVL(fh.BASE_ID, eng.BASE_ID)", + "hb.BASENAME", "fh.RSTCD", "eng.ENNM", "NVL(fh.HBRVCD, eng.HBRVCD)", "hbrv.HBRVNM", + "CAST(NULL AS VARCHAR2(10))", "CAST(NULL AS VARCHAR2(32))", "fh.DTIN_TM", "fh.DTIN", + "CASE WHEN NVL(fh.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(fh.ORDER_INDEX, 999999)", + "SD_FHBT_B_H fh", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = 'FH' AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fh.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(fh.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "NVL(fh.IS_DELETED, 0) = 0" + ) + " UNION ALL " + + buildOpedBranchSql( + "dw.STCD", "dw.STNM", "'DW'", "child.STTP_NAME", "NVL(dw.BASE_ID, eng.BASE_ID)", + "hb.BASENAME", "dw.RSTCD", "eng.ENNM", "NVL(dw.HBRVCD, eng.HBRVCD)", "hbrv.HBRVNM", + "CAST(dw.BLDSTT_CODE AS VARCHAR2(10))", buildBldsttNameExpr("dw.BLDSTT_CODE"), "dw.DTIN_TM", "dw.DTIN", + "CASE WHEN NVL(dw.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(dw.ORDER_INDEX, 999999)", + "SD_DW_B_H dw", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = dw.STTP AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = dw.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(dw.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(dw.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(dw.BASE_ID, eng.BASE_ID) " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "NVL(dw.IS_DELETED, 0) = 0" + ) + " UNION ALL " + + buildOpedBranchSql( + "fp.STCD", "fp.STNM", "'FP'", "child.STTP_NAME", "eng.BASE_ID", + "hb.BASENAME", "fp.RSTCD", "eng.ENNM", "eng.HBRVCD", "hbrv.HBRVNM", + "CAST(fp.BLDSTT_CODE AS VARCHAR2(10))", buildBldsttNameExpr("fp.BLDSTT_CODE"), "fp.DTIN_TM", "fp.DTIN", + "CASE WHEN NVL(fp.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(fp.ORDER_INDEX, 999999)", + "SD_FPSS_B_H fp", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = fp.STTP AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "1 = 1 AND fp.STTP LIKE 'FP\\_%' ESCAPE '\\' " + ) + " UNION ALL " + + buildOpedBranchSql( + "eq.STCD", "eq.STNM", "'EQ'", "child.STTP_NAME", "NVL(eq.BASE_ID, eng.BASE_ID)", + "hb.BASENAME", "eq.RSTCD", "eng.ENNM", "NVL(eq.HBRVCD, eng.HBRVCD)", "hbrv.HBRVNM", + "CAST(eq.BLDSTT_CODE AS VARCHAR2(10))", buildBldsttNameExpr("eq.BLDSTT_CODE"), "eq.DTIN_TM", "eq.DTIN", + "CASE WHEN NVL(eq.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END", + "NVL(hb.ORDER_INDEX, 999999)", "NVL(hbrv.ORDER_INDEX, 999999)", "NVL(eng.ORDER_INDEX, 999999)", "NVL(eq.ORDER_INDEX, 999999)", + "SD_EQ_B_H eq", + "LEFT JOIN SD_STTP_B child ON child.STTP_CODE = eq.STTP AND NVL(child.IS_DELETED, 0) = 0 AND NVL(child.ENABLE, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = eq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(eq.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(eq.HBRVCD, eng.HBRVCD) AND hbrv.BASEID = NVL(eq.BASE_ID, eng.BASE_ID) " + + "AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1", + "NVL(eq.IS_DELETED, 0) = 0" + ); + } + + private String buildOpedBranchSql(String stcdExpr, + String stnmExpr, + String sttpCodeExpr, + String sttpNameExpr, + String baseIdExpr, + String baseNameExpr, + String rstcdExpr, + String ennmExpr, + String hbrvcdExpr, + String hbrvcdNameExpr, + String bldsttExpr, + String bldsttNameExpr, + String dtinTmExpr, + String dtinExpr, + String dtinNameExpr, + String baseStepSortExpr, + String rvcdStepSortExpr, + String rstcdStepSortExpr, + String siteStepSortExpr, + String fromSql, + String joinSql, + String whereSql) { + return "SELECT " + + sttpNameExpr + " AS sttpName, " + + baseIdExpr + " AS baseId, " + + stcdExpr + " AS stcd, " + + stnmExpr + " AS stnm, " + + sttpCodeExpr + " AS sttpCode, " + + baseNameExpr + " AS baseName, " + + rstcdExpr + " AS rstcd, " + + ennmExpr + " AS ennm, " + + bldsttExpr + " AS bldsttCcode, " + + bldsttNameExpr + " AS bldsttCcodeName, " + + dtinTmExpr + " AS dtinTm, " + + dtinExpr + " AS dtin, " + + dtinNameExpr + " AS dtinName, " + + hbrvcdExpr + " AS hbrvcd, " + + hbrvcdNameExpr + " AS hbrvcdName, " + + baseStepSortExpr + " AS baseStepSort, " + + rvcdStepSortExpr + " AS rvcdStepSort, " + + rstcdStepSortExpr + " AS rstcdStepSort, " + + siteStepSortExpr + " AS siteStepSort " + + "FROM " + fromSql + " " + joinSql + " WHERE " + whereSql; + } + + private String buildBldsttNameExpr(String column) { + return "CASE " + column + " WHEN 0 THEN '未建/规划' WHEN 1 THEN '在建' WHEN 2 THEN '已建' ELSE NULL END"; + } + + private List resolveOpedSelectFields(List select) { + List fields = CollUtil.isEmpty(select) + ? new ArrayList<>(buildOpedSelectMap().keySet()) + : new ArrayList<>(select); + LinkedHashSet uniqueFields = new LinkedHashSet<>(); + for (String field : fields) { + if (StrUtil.isNotBlank(field)) { + uniqueFields.add(field.trim()); + } + } + if (uniqueFields.isEmpty()) { + uniqueFields.add("stcd"); + } + return new ArrayList<>(uniqueFields); + } + + private String buildOpedSelectSql(List selectFields) { + Map columnMap = buildOpedSelectMap(); + List selectParts = new ArrayList<>(); + for (String field : resolveOpedSelectFields(selectFields)) { + String column = columnMap.get(field); + if (StrUtil.isNotBlank(column)) { + selectParts.add(column); + } else { + selectParts.add("NULL AS \"" + field + "\""); + } + } + return String.join(", ", selectParts); + } + + private Map buildOpedSelectMap() { + Map columnMap = new LinkedHashMap<>(); + columnMap.put("sttpName", "t.sttpName AS \"sttpName\""); + columnMap.put("baseId", "t.baseId AS \"baseId\""); + columnMap.put("stcd", "t.stcd AS \"stcd\""); + columnMap.put("stnm", "t.stnm AS \"stnm\""); + columnMap.put("sttpCode", "t.sttpCode AS \"sttpCode\""); + columnMap.put("baseName", "t.baseName AS \"baseName\""); + columnMap.put("rstcd", "t.rstcd AS \"rstcd\""); + columnMap.put("ennm", "t.ennm AS \"ennm\""); + columnMap.put("bldsttCcode", "t.bldsttCcode AS \"bldsttCcode\""); + columnMap.put("bldsttCcodeName", "t.bldsttCcodeName AS \"bldsttCcodeName\""); + columnMap.put("dtinTm", "t.dtinTm AS \"dtinTm\""); + columnMap.put("dtin", "t.dtin AS \"dtin\""); + columnMap.put("dtinName", "t.dtinName AS \"dtinName\""); + columnMap.put("runState", "t.runState AS \"runState\""); + columnMap.put("runStateName", "t.runStateName AS \"runStateName\""); + columnMap.put("stdState", "t.stdState AS \"stdState\""); + columnMap.put("stdStateName", "t.stdStateName AS \"stdStateName\""); + columnMap.put("stdSstate", "t.stdSstate AS \"stdSstate\""); + columnMap.put("stdSstateName", "t.stdSstateName AS \"stdSstateName\""); + columnMap.put("mway", "t.mway AS \"mway\""); + columnMap.put("mwayName", "t.mwayName AS \"mwayName\""); + columnMap.put("hbrvcd", "t.hbrvcd AS \"hbrvcd\""); + columnMap.put("hbrvcdName", "t.hbrvcdName AS \"hbrvcdName\""); + columnMap.put("baseStepSort", "t.baseStepSort AS \"baseStepSort\""); +// columnMap.put("baseStepsort", "t.baseStepsort AS \"baseStepsort\""); + columnMap.put("rvcdStepSort", "t.rvcdStepSort AS \"rvcdStepSort\""); + columnMap.put("rstcdStepSort", "t.rstcdStepSort AS \"rstcdStepSort\""); +// columnMap.put("rstcdStepsort", "t.rstcdStepsort AS \"rstcdStepsort\""); + columnMap.put("siteStepSort", "t.siteStepSort AS \"siteStepSort\""); +// columnMap.put("yr", "t.yr AS \"yr\""); + return columnMap; + } + + private String buildOpedFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildOpedLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildOpedFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildOpedLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + if (StrUtil.isBlank(field) || "yr".equals(field)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + String column = mapOpedColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "opedP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add("#{map." + key + "}"); + } + return column + ("ni".equals(operator) ? " NOT IN (" : " IN (") + String.join(", ", placeholders) + ")"; + } + + Object value = filter.getValue(); + if (value == null) { + return ""; + } + String key = "opedP" + indexHolder[0]++; + boolean dateField = isOpedDateField(field); + String placeholder = dateField + ? "TO_DATE(#{map." + key + "}, 'YYYY-MM-DD HH24:MI:SS')" + : "#{map." + key + "}"; + paramMap.put(key, value); + return switch (operator) { + case "eq" -> column + " = " + placeholder; + case "neq" -> column + " <> " + placeholder; + case "contains" -> { + paramMap.put(key, "%" + value + "%"); + yield dateField + ? "TO_CHAR(" + column + ", 'YYYY-MM-DD HH24:MI:SS') LIKE #{map." + key + "}" + : column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + value + "%"); + yield dateField + ? "TO_CHAR(" + column + ", 'YYYY-MM-DD HH24:MI:SS') NOT LIKE #{map." + key + "}" + : column + " NOT LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, value + "%"); + yield dateField + ? "TO_CHAR(" + column + ", 'YYYY-MM-DD HH24:MI:SS') LIKE #{map." + key + "}" + : column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + value); + yield dateField + ? "TO_CHAR(" + column + ", 'YYYY-MM-DD HH24:MI:SS') LIKE #{map." + key + "}" + : column + " LIKE #{map." + key + "}"; + } + case "gt" -> column + " > " + placeholder; + case "gte" -> column + " >= " + placeholder; + case "lt" -> column + " < " + placeholder; + case "lte" -> column + " <= " + placeholder; + default -> ""; + }; + } + + private boolean isOpedDateField(String field) { + return "dtinTm".equals(field); + } + + private String mapOpedColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "sttpName" -> "t.sttpName"; + case "baseId" -> "t.baseId"; + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "sttpCode" -> "t.sttpCode"; + case "baseName" -> "t.baseName"; + case "rstcd" -> "t.rstcd"; + case "ennm" -> "t.ennm"; + case "bldsttCcode" -> "t.bldsttCcode"; + case "bldsttCcodeName" -> "t.bldsttCcodeName"; + case "dtinTm" -> "t.dtinTm"; + case "dtin" -> "t.dtin"; + case "dtinName" -> "t.dtinName"; + case "runState" -> "t.runState"; + case "runStateName" -> "t.runStateName"; + case "stdState" -> "t.stdState"; + case "stdStateName" -> "t.stdStateName"; + case "stdSstate" -> "t.stdSstate"; + case "stdSstateName" -> "t.stdSstateName"; + case "mway" -> "t.mway"; + case "mwayName" -> "t.mwayName"; + case "hbrvcd" -> "t.hbrvcd"; + case "hbrvcdName" -> "t.hbrvcdName"; + case "baseStepSort", "baseStepsort" -> "t.baseStepSort"; + case "rvcdStepSort" -> "t.rvcdStepSort"; + case "rstcdStepSort", "rstcdStepsort" -> "t.rstcdStepSort"; + case "siteStepSort" -> "t.siteStepSort"; + case "yr" -> "t.yr"; + default -> null; + }; + } + + private String buildOpedOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY t.baseStepSort ASC NULLS LAST, t.rvcdStepSort ASC NULLS LAST, " + + "t.rstcdStepSort ASC NULLS LAST, t.siteStepSort ASC NULLS LAST, t.stnm ASC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapOpedColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir + " NULLS LAST"); + } + if (orderItems.isEmpty()) { + return " ORDER BY t.baseStepSort ASC NULLS LAST, t.rvcdStepSort ASC NULLS LAST, " + + "t.rstcdStepSort ASC NULLS LAST, t.siteStepSort ASC NULLS LAST, t.stnm ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildOpedGroupSql(String detailSql, GroupingInfo[] groupInfos) { + if (groupInfos == null || groupInfos.length == 0) { + return detailSql; + } + List groupFields = new ArrayList<>(); + List selectItems = new ArrayList<>(); + List orderItems = new ArrayList<>(); + for (GroupingInfo item : groupInfos) { + if (item == null || StrUtil.isBlank(item.getSelector())) { + continue; + } + String selector = item.getSelector(); + String column = mapOpedColumn(selector); + if (StrUtil.isBlank(column)) { + continue; + } + groupFields.add(column); + selectItems.add(column + " AS " + selector); + selectItems.add("COUNT(*) AS count_" + selector); + orderItems.add(column + (item.getDesc() ? " DESC" : " ASC")); + } + if (groupFields.isEmpty()) { + return "SELECT * FROM (" + detailSql + ") t WHERE 1 = 0"; + } + return "SELECT " + String.join(", ", selectItems) + + " FROM (" + detailSql + ") t GROUP BY " + String.join(", ", groupFields) + + " ORDER BY " + String.join(", ", orderItems); + } + private List normalizeValues(Object value) { List values = new ArrayList<>(); collectValues(value, values); From dcbe70f5f90c5814a35ee716b1f6918021f6c87e Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 11:15:43 +0800 Subject: [PATCH 06/65] =?UTF-8?q?fix:=20=E9=A6=96=E9=A1=B5=E7=8E=AF?= =?UTF-8?q?=E4=BF=9D=E8=AE=BE=E6=96=BD=E8=BF=90=E8=A1=8C=E7=8A=B6=E5=86=B5?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../overview/entity/vo/OverviewOpedVo.java | 21 ++ .../service/impl/OverviewServiceImpl.java | 218 ++++++++++++++++++ 2 files changed, 239 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java index 32fb39d7..67a71e8a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/entity/vo/OverviewOpedVo.java @@ -5,6 +5,8 @@ import lombok.Data; import java.io.Serializable; import java.util.Date; +import java.util.HashMap; +import java.util.Map; @Data @Schema(description = "首页环保设施运行状况明细") @@ -12,6 +14,17 @@ public class OverviewOpedVo implements Serializable { private static final long serialVersionUID = 1L; + private Map _tls = new HashMap<>(); + + private String id; + private String recordUser; + private Date recordTime; + private Date modifyTime; + private String displayRecordUser; + private String repCode; + private String pcode; + private String pname; + private String psttpName; private String sttpName; private String baseId; private String stcd; @@ -31,14 +44,22 @@ public class OverviewOpedVo implements Serializable { private String stdStateName; private Integer stdSstate; private String stdSstateName; + private Integer runSstate; + private String runSstateName; private Integer mway; private String mwayName; private String hbrvcd; private String hbrvcdName; + private String addvcdName; + private String rvcdName; private Integer baseStepSort; private Integer baseStepsort; private Integer rvcdStepSort; private Integer rstcdStepSort; private Integer rstcdStepsort; private Integer siteStepSort; + private Integer count; + private Date jcdt; + private String departmentId; + private String displayDepartment; } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java index a33c4f14..79ec09ab 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/overview/service/impl/OverviewServiceImpl.java @@ -77,6 +77,9 @@ public class OverviewServiceImpl implements OverviewService { DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); Map paramMap = new HashMap<>(); paramMap.put("stateYear", resolveOpedStateYear()); + if (shouldQueryOpedSummary(dataSourceRequest)) { + return queryOpedSummaryList(dataSourceRequest, loadOptions, paramMap); + } String filterSql = buildOpedFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); if (CollUtil.isNotEmpty(dataSourceRequest.getGroup())) { @@ -106,6 +109,39 @@ public class OverviewServiceImpl implements OverviewService { return result; } + private DataSourceResult queryOpedSummaryList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions, + Map paramMap) { + String effectiveFilterSql = buildOpedEffectiveFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildOpedSummarySelectSql(dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildOpedCategorySql()) + .append(") cat ") + .append("LEFT JOIN (SELECT * FROM (") + .append(buildOpedBaseSql()) + .append(") t WHERE 1 = 1 "); + if (StrUtil.isNotBlank(effectiveFilterSql)) { + sql.append(" AND ").append(effectiveFilterSql); + } + sql.append(") src ON cat.repCode = src.repCode ") + .append("GROUP BY cat.repCode, cat.sttpName, cat.orderIndex ") + .append(buildOpedSummaryOrderBySql(dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, OverviewOpedVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page == null ? list.size() : page.getTotal()); + result.setAggregates(new HashMap<>()); + return result; + } + private String buildBaseSql() { return buildFbSql() + " UNION ALL " + buildDwSql() + " UNION ALL " + buildFpSql(); } @@ -639,6 +675,7 @@ public class OverviewServiceImpl implements OverviewService { private String buildOpedBaseSql() { return "SELECT " + + "src.sttpCode AS repCode, " + "src.sttpName AS sttpName, " + "src.baseId AS baseId, " + "src.stcd AS stcd, " + @@ -647,6 +684,8 @@ public class OverviewServiceImpl implements OverviewService { "src.baseName AS baseName, " + "src.rstcd AS rstcd, " + "src.ennm AS ennm, " + + "CAST(NULL AS VARCHAR2(255)) AS addvcdName, " + + "CAST(NULL AS VARCHAR2(255)) AS rvcdName, " + "src.bldsttCcode AS bldsttCcode, " + "src.bldsttCcodeName AS bldsttCcodeName, " + "src.dtinTm AS dtinTm, " + @@ -663,6 +702,10 @@ public class OverviewServiceImpl implements OverviewService { "CASE WHEN state.STD_SSTATE = 1 THEN '正常运行' " + "WHEN state.STD_SSTATE IN (0, 2) THEN '暂无数据' " + "WHEN state.STD_SSTATE = 3 THEN '未正常运行' ELSE NULL END AS stdSstateName, " + + "state.STD_SSTATE AS runSstate, " + + "CASE WHEN state.STD_SSTATE = 1 THEN '正常运行' " + + "WHEN state.STD_SSTATE IN (0, 2) THEN '暂无数据' " + + "WHEN state.STD_SSTATE = 3 THEN '未正常运行' ELSE NULL END AS runSstateName, " + "CAST(NULL AS NUMBER(10)) AS mway, " + "CAST(NULL AS VARCHAR2(32)) AS mwayName, " + "src.hbrvcd AS hbrvcd, " + @@ -862,6 +905,7 @@ public class OverviewServiceImpl implements OverviewService { private Map buildOpedSelectMap() { Map columnMap = new LinkedHashMap<>(); + columnMap.put("repCode", "t.repCode AS \"repCode\""); columnMap.put("sttpName", "t.sttpName AS \"sttpName\""); columnMap.put("baseId", "t.baseId AS \"baseId\""); columnMap.put("stcd", "t.stcd AS \"stcd\""); @@ -870,6 +914,8 @@ public class OverviewServiceImpl implements OverviewService { columnMap.put("baseName", "t.baseName AS \"baseName\""); columnMap.put("rstcd", "t.rstcd AS \"rstcd\""); columnMap.put("ennm", "t.ennm AS \"ennm\""); + columnMap.put("addvcdName", "t.addvcdName AS \"addvcdName\""); + columnMap.put("rvcdName", "t.rvcdName AS \"rvcdName\""); columnMap.put("bldsttCcode", "t.bldsttCcode AS \"bldsttCcode\""); columnMap.put("bldsttCcodeName", "t.bldsttCcodeName AS \"bldsttCcodeName\""); columnMap.put("dtinTm", "t.dtinTm AS \"dtinTm\""); @@ -881,6 +927,8 @@ public class OverviewServiceImpl implements OverviewService { columnMap.put("stdStateName", "t.stdStateName AS \"stdStateName\""); columnMap.put("stdSstate", "t.stdSstate AS \"stdSstate\""); columnMap.put("stdSstateName", "t.stdSstateName AS \"stdSstateName\""); + columnMap.put("runSstate", "t.runSstate AS \"runSstate\""); + columnMap.put("runSstateName", "t.runSstateName AS \"runSstateName\""); columnMap.put("mway", "t.mway AS \"mway\""); columnMap.put("mwayName", "t.mwayName AS \"mwayName\""); columnMap.put("hbrvcd", "t.hbrvcd AS \"hbrvcd\""); @@ -921,6 +969,35 @@ public class OverviewServiceImpl implements OverviewService { return String.join(logic, conditions); } + private String buildOpedEffectiveFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + if ("1".equals(StrUtil.trim(filter.getField()))) { + return ""; + } + return buildOpedLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildOpedEffectiveFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + private String buildOpedLeafCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -1098,6 +1175,147 @@ public class OverviewServiceImpl implements OverviewService { " ORDER BY " + String.join(", ", orderItems); } + private boolean shouldQueryOpedSummary(DataSourceRequest dataSourceRequest) { + return dataSourceRequest != null + && CollUtil.isEmpty(dataSourceRequest.getGroup()) + && hasOnlyDummyFilter(dataSourceRequest.getFilter()); + } + + private boolean hasOnlyDummyFilter(DataSourceRequest.FilterDescriptor filter) { + return hasDummyField(filter) && !hasRealField(filter); + } + + private boolean hasDummyField(DataSourceRequest.FilterDescriptor filter) { + if (filter == null) { + return false; + } + if ("1".equals(StrUtil.trim(filter.getField()))) { + return true; + } + if (CollUtil.isEmpty(filter.getFilters())) { + return false; + } + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + if (hasDummyField(child)) { + return true; + } + } + return false; + } + + private boolean hasRealField(DataSourceRequest.FilterDescriptor filter) { + if (filter == null) { + return false; + } + String field = StrUtil.trim(filter.getField()); + if (StrUtil.isNotBlank(field) && !"1".equals(field)) { + return true; + } + if (CollUtil.isEmpty(filter.getFilters())) { + return false; + } + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + if (hasRealField(child)) { + return true; + } + } + return false; + } + + private String buildOpedCategorySql() { + return "SELECT 'VA' AS repCode, '动物救助站' AS sttpName, 1 AS orderIndex FROM dual " + + "UNION ALL SELECT 'FP' AS repCode, '过鱼设施' AS sttpName, 2 AS orderIndex FROM dual " + + "UNION ALL SELECT 'FB' AS repCode, '鱼类增殖站' AS sttpName, 3 AS orderIndex FROM dual " + + "UNION ALL SELECT 'DW' AS repCode, '低温水减缓设施' AS sttpName, 4 AS orderIndex FROM dual " + + "UNION ALL SELECT 'VP' AS repCode, '珍稀植物园' AS sttpName, 5 AS orderIndex FROM dual " + + "UNION ALL SELECT 'FH' AS repCode, '鱼类栖息地' AS sttpName, 6 AS orderIndex FROM dual " + + "UNION ALL SELECT 'EQ' AS repCode, '生态流量泄放设施' AS sttpName, 7 AS orderIndex FROM dual"; + } + + private String buildOpedSummarySelectSql(List selectFields) { + Map columnMap = buildOpedSummarySelectMap(); + List fields = CollUtil.isEmpty(selectFields) + ? new ArrayList<>(columnMap.keySet()) + : new ArrayList<>(selectFields); + List selectItems = new ArrayList<>(); + for (String field : fields) { + if (StrUtil.isBlank(field)) { + continue; + } + String column = columnMap.get(field.trim()); + if (StrUtil.isNotBlank(column)) { + selectItems.add(column); + } + } + if (selectItems.isEmpty()) { + selectItems.addAll(columnMap.values()); + } + return String.join(", ", selectItems); + } + + private Map buildOpedSummarySelectMap() { + Map columnMap = new LinkedHashMap<>(); + columnMap.put("id", "CAST(NULL AS VARCHAR2(64)) AS \"id\""); + columnMap.put("recordUser", "CAST(NULL AS VARCHAR2(64)) AS \"recordUser\""); + columnMap.put("recordTime", "CAST(NULL AS DATE) AS \"recordTime\""); + columnMap.put("modifyTime", "CAST(NULL AS DATE) AS \"modifyTime\""); + columnMap.put("displayRecordUser", "CAST(NULL AS VARCHAR2(128)) AS \"displayRecordUser\""); + columnMap.put("repCode", "cat.repCode AS \"repCode\""); + columnMap.put("sttpCode", "CAST(NULL AS VARCHAR2(64)) AS \"sttpCode\""); + columnMap.put("pcode", "CAST(NULL AS VARCHAR2(64)) AS \"pcode\""); + columnMap.put("pname", "CAST(NULL AS VARCHAR2(128)) AS \"pname\""); + columnMap.put("psttpName", "CAST(NULL AS VARCHAR2(128)) AS \"psttpName\""); + columnMap.put("stcd", "CAST(NULL AS VARCHAR2(64)) AS \"stcd\""); + columnMap.put("ennm", "CAST(NULL AS VARCHAR2(255)) AS \"ennm\""); + columnMap.put("stnm", "CAST(NULL AS VARCHAR2(255)) AS \"stnm\""); + columnMap.put("addvcdName", "CAST(NULL AS VARCHAR2(255)) AS \"addvcdName\""); + columnMap.put("rvcdName", "CAST(NULL AS VARCHAR2(255)) AS \"rvcdName\""); + columnMap.put("sttpName", "cat.sttpName AS \"sttpName\""); + columnMap.put("baseId", "CAST(NULL AS VARCHAR2(64)) AS \"baseId\""); + columnMap.put("dtin", "CAST(NULL AS NUMBER(10)) AS \"dtin\""); + columnMap.put("dtinName", "CAST(NULL AS VARCHAR2(32)) AS \"dtinName\""); + columnMap.put("runState", "CAST(NULL AS NUMBER(10)) AS \"runState\""); + columnMap.put("runStateName", "CAST(NULL AS VARCHAR2(32)) AS \"runStateName\""); + columnMap.put("stdState", "CAST(NULL AS NUMBER(10)) AS \"stdState\""); + columnMap.put("stdStateName", "CAST(NULL AS VARCHAR2(32)) AS \"stdStateName\""); + columnMap.put("bldsttCcode", "CAST(NULL AS VARCHAR2(10)) AS \"bldsttCcode\""); + columnMap.put("bldsttCcodeName", "CAST(NULL AS VARCHAR2(32)) AS \"bldsttCcodeName\""); + columnMap.put("count", "COUNT(src.repCode) AS \"count\""); + columnMap.put("jcdt", "CAST(NULL AS DATE) AS \"jcdt\""); + columnMap.put("runSstate", "CAST(NULL AS NUMBER(10)) AS \"runSstate\""); + columnMap.put("runSstateName", "CAST(NULL AS VARCHAR2(32)) AS \"runSstateName\""); + columnMap.put("departmentId", "CAST(NULL AS VARCHAR2(64)) AS \"departmentId\""); + columnMap.put("displayDepartment", "CAST(NULL AS VARCHAR2(255)) AS \"displayDepartment\""); + return columnMap; + } + + private String buildOpedSummaryOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY cat.orderIndex ASC, cat.repCode ASC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = switch (sort.getField()) { + case "repCode" -> "cat.repCode"; + case "sttpName" -> "cat.sttpName"; + case "count" -> "COUNT(src.repCode)"; + default -> null; + }; + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (orderItems.isEmpty()) { + return " ORDER BY cat.orderIndex ASC, cat.repCode ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + private List normalizeValues(Object value) { List values = new ArrayList<>(); collectValues(value, values); From fae68975d49984aa7c9ffce84b7b374398392f35 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 11:41:09 +0800 Subject: [PATCH 07/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E6=B0=B4?= =?UTF-8?q?=E8=B4=A8=E5=88=A0=E9=99=A4=E4=BF=AE=E6=94=B9=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wq/controller/EnvWqDataController.java | 8 +- .../qgc_env/wq/service/EnvWqDataService.java | 2 +- .../wq/service/impl/EnvWqDataServiceImpl.java | 469 ++++++++++++++++-- 3 files changed, 431 insertions(+), 48 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java index f944ba50..9a6709aa 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/controller/EnvWqDataController.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.wq.controller; import com.yfd.platform.common.DataSourceRequest; 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_env.wq.entity.vo.WqOperateRequest; import com.yfd.platform.qgc_env.wq.service.EnvWqDataService; @@ -58,13 +59,18 @@ public class EnvWqDataController { return ResponseResult.successData(envWqDataService.getDrtpKendoListCust(dataSourceRequest)); } + @Log(module = "水质统计分析", value = "修改水质小时数据") @PostMapping("/updateWqRsData") @Operation(summary = "修改水质小时数据") 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(); } + @Log(module = "水质统计分析", value = "删除水质小时/日/月数据") @PostMapping("/removeKendoByIds") @Operation(summary = "删除水质小时/日/月数据") public ResponseResult removeKendoByIds(@RequestBody BatchDeleteAo batchDeleteAo) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/EnvWqDataService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/EnvWqDataService.java index f23a3931..6a55e1da 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/EnvWqDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/EnvWqDataService.java @@ -39,7 +39,7 @@ public interface EnvWqDataService { DataSourceResult getStTbYsBVoKendoListCust(DataSourceRequest dataSourceRequest); - boolean updateWqRsData(Map updateData); + boolean updateWqRsData(Map updateData, String source); boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java index 32f2c970..7ac6d0b1 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java @@ -1,12 +1,17 @@ package com.yfd.platform.qgc_env.wq.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.*; 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.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.service.EnvWqDataService; import com.yfd.platform.qgc_env.wt.entity.vo.WbsbVo; @@ -36,12 +41,125 @@ import java.util.stream.Collectors; @Service 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 WQ_UPDATE_COLUMN_MAP = new LinkedHashMap<>(); + private static final Map WQ_FIELD_MEANING_MAP = new LinkedHashMap<>(); + private static final List 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 private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; @Resource private JdbcTemplate jdbcTemplate; + @Resource + private MsOperationLogMapper msOperationLogMapper; + + @Resource + private MsOperationLogDetailMapper msOperationLogDetailMapper; + @Override public DataSourceResult processKendoList(DataSourceRequest dataSourceRequest) { boolean calculated = CommonConstant.CALCULATE_SUCCESS.equals( @@ -3671,15 +3789,18 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { @Override @Transactional(rollbackFor = Exception.class) - public boolean updateWqRsData(Map updateData) { + public boolean updateWqRsData(Map updateData, String source) { if (updateData == null || updateData.isEmpty()) { return true; } - updateWqHourData(updateData); - updateWqTargetIfNeeded(updateData); - String stcd = asString(updateData.get("stcd")); String tm = asString(updateData.get("tm")); + Map beforeHour = queryWqHourRow(stcd, tm); + Map beforeStation = queryWqStationRow(stcd); + updateWqHourData(updateData); + updateWqTargetIfNeeded(updateData); + recordWqUpdateLog(beforeHour, beforeStation, updateData, source); + if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm) && tm.length() >= 10) { String dateStr = tm.substring(0, 10); statisticsDayDataFromHour(stcd, dateStr, dateStr); @@ -3704,17 +3825,24 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { return true; } String dataType = StrUtil.blankToDefault(batchDeleteAo.getDataType(), "").toUpperCase(); + String source = batchDeleteAo == null ? null : batchDeleteAo.getSource(); int batchSize = 500; for (int i = 0; i < dataList.size(); i += batchSize) { List subList = dataList.subList(i, Math.min(i + batchSize, dataList.size())); if ("MON".equals(dataType)) { + List> beforeRows = queryWqMonthRows(subList); softDeleteWqMonthData(subList); + recordWqDeleteLog(beforeRows, WQ_MONTH_TABLE_NAME, "删除水质月数据", source); } if ("DATE".equals(dataType)) { + List> beforeRows = queryWqDayRows(subList); softDeleteWqDayData(subList); + recordWqDeleteLog(beforeRows, WQ_DAY_TABLE_NAME, "删除水质日数据", source); } if ("TIME".equals(dataType)) { + List> beforeRows = queryWqHourRows(subList); deleteWqHourData(subList); + recordWqDeleteLog(beforeRows, WQ_HOUR_TABLE_NAME, "删除水质小时数据", source); Map dateRangeMap = new HashMap<>(); Map monthRangeMap = new HashMap<>(); @@ -3765,50 +3893,9 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { } private void updateWqHourData(Map updateData) { - LinkedHashMap 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 setClauses = new ArrayList<>(); List params = new ArrayList<>(); - for (Map.Entry entry : columnMap.entrySet()) { + for (Map.Entry entry : WQ_UPDATE_COLUMN_MAP.entrySet()) { if (updateData.containsKey(entry.getKey())) { setClauses.add(entry.getValue() + " = ?"); params.add(updateData.get(entry.getKey())); @@ -3909,6 +3996,296 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { jdbcTemplate.update(sql.toString(), params.toArray()); } + private Map 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> rows = jdbcTemplate.queryForList(sql, stcd, tm); + return rows.isEmpty() ? new HashMap<>() : normalizeLogRow(rows.getFirst()); + } + + private Map 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> rows = jdbcTemplate.queryForList(sql, stcd); + return rows.isEmpty() ? new HashMap<>() : normalizeLogRow(rows.getFirst()); + } + + private List> queryWqHourRows(List dataParamList) { + if (CollUtil.isEmpty(dataParamList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ") + .append(buildWqHourLogSelectColumns()) + .append(" FROM SD_WQ_R WHERE "); + List params = new ArrayList<>(); + appendHourRowConditions(sql, params, dataParamList); + return normalizeLogRows(jdbcTemplate.queryForList(sql.toString(), params.toArray())); + } + + private List> queryWqDayRows(List dataParamList) { + if (CollUtil.isEmpty(dataParamList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ") + .append(buildWqDayLogSelectColumns()) + .append(" FROM SD_WQDAY_S WHERE "); + List 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> queryWqMonthRows(List dataParamList) { + if (CollUtil.isEmpty(dataParamList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ") + .append(buildWqMonthLogSelectColumns()) + .append(" FROM SD_WQDRTP_S WHERE "); + List 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 params, List 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> normalizeLogRows(List> rows) { + List> result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + result.add(normalizeLogRow(row)); + } + return result; + } + + private Map normalizeLogRow(Map row) { + Map normalized = new LinkedHashMap<>(); + if (row == null || row.isEmpty()) { + return normalized; + } + for (Map.Entry entry : row.entrySet()) { + normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue()); + } + return normalized; + } + + private void recordWqUpdateLog(Map beforeHour, + Map beforeStation, + Map updateData, + String source) { + if (updateData == null || updateData.isEmpty()) { + return; + } + String stcd = asString(updateData.get("stcd")); + List details = new ArrayList<>(); + for (Map.Entry 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> rows, String tableName, String remark, String source) { + if (CollUtil.isEmpty(rows)) { + return; + } + MsOperationLog mainLog = buildWqMainLog(remark, source); + msOperationLogMapper.insert(mainLog); + List details = new ArrayList<>(); + for (Map 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 details) { + if (CollUtil.isEmpty(details)) { + return; + } + msOperationLogDetailMapper.insert(details); + } + + private String buildWqRowKey(String tableName, Map 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 row) { + if (row == null || row.isEmpty()) { + return null; + } + List 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) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month - 1, 1); From fc09d69302a6d38b5fcd0309ed88111fb781417f Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 13:47:11 +0800 Subject: [PATCH 08/65] =?UTF-8?q?feat:=20=E7=94=B5=E7=AB=99=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E5=AE=9E=E6=97=B6=E7=9B=91=E6=B5=8B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SdEngInfoBHController.java | 8 + .../qgc_base/domain/vo/EngStbprpDataVo.java | 24 ++ .../qgc_base/service/ISdEngInfoBHService.java | 2 + .../service/impl/SdEngInfoBHServiceImpl.java | 371 +++++++++++++++++- 4 files changed, 396 insertions(+), 9 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java index b5c994ee..798ab6d7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java @@ -93,6 +93,14 @@ public class SdEngInfoBHController { return ResponseResult.successData(engInfoBHService.getVmsstbprptKendoList(dataSourceRequest)); } + @PostMapping("/stbprpData/GetKendoListCust") + @Operation(summary = "电站通用实时监测数据查询") + public ResponseResult getStbprpDataKendoListCust(@RequestBody DataSourceRequest dataSourceRequest, + @RequestParam("tbCode") String tbCode, + @RequestParam(value = "ignorePageLimit", required = false) Boolean ignorePageLimit) { + return ResponseResult.successData(engInfoBHService.getStbprpDataKendoListCust(dataSourceRequest, tbCode, ignorePageLimit)); + } + @Log(module = "电站管理", value = "新增电站") @PostMapping("/add") @Operation(summary = "新增电站") diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java new file mode 100644 index 00000000..afd9546c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java @@ -0,0 +1,24 @@ +package com.yfd.platform.qgc_base.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +@Schema(description = "电站通用监测数据动态行") +public class EngStbprpDataVo extends LinkedHashMap implements Serializable { + + private static final long serialVersionUID = 1L; + + public EngStbprpDataVo() { + super(); + } + + public EngStbprpDataVo(Map source) { + super(); + if (source != null && !source.isEmpty()) { + putAll(source); + } + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java index e9128874..7d034512 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java @@ -84,4 +84,6 @@ public interface ISdEngInfoBHService extends IService { DataSourceResult getVmsstbprptKendoList(DataSourceRequest dataSourceRequest); DataSourceResult getOperatKendoList(DataSourceRequest dataSourceRequest); + + DataSourceResult getStbprpDataKendoListCust(DataSourceRequest dataSourceRequest, String tbCode, Boolean ignorePageLimit); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java index 315005fd..e860aa8b 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java @@ -27,6 +27,7 @@ import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest; import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo; import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo; import com.yfd.platform.qgc_base.domain.vo.EngOperatVo; +import com.yfd.platform.qgc_base.domain.vo.EngStbprpDataVo; import com.yfd.platform.qgc_base.domain.vo.EngStBaseInfoVo; import com.yfd.platform.qgc_base.domain.vo.EngStInfoResultVo; import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo; @@ -41,15 +42,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -709,6 +702,59 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl result = new DataSourceResult<>(); + result.setAggregates(new HashMap<>()); + if (StrUtil.isBlank(tbCode)) { + result.setData(new ArrayList<>()); + result.setTotal(0L); + return result; + } + DataSourceRequest request = dataSourceRequest == null ? new DataSourceRequest() : dataSourceRequest; + if (!Boolean.TRUE.equals(ignorePageLimit) && request.getTake() == 0) { + request.setTake(2000); + } + + DataSourceLoadOptionsBase loadOptions = request.toDevRequest(); + List tableMetaList = queryStbprpTableMeta(tbCode); + if (CollUtil.isEmpty(tableMetaList)) { + return result; + } + + String firstTableName = tableMetaList.getFirst().tableName(); + String detailSql = buildStbprpDataDetailSql(request, tableMetaList); + Map paramMap = new HashMap<>(); + String filterSql = buildStbprpDataFilterCondition(request.getFilter(), paramMap, new int[]{0}, tableMetaList); + if (StrUtil.isNotBlank(filterSql)) { + detailSql = detailSql + " AND " + filterSql; + } + + if (CollUtil.isEmpty(request.getGroup())) { + String sql = detailSql + buildStbprpDataOrderBySql(request.getSort(), tableMetaList); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List> rows = microservicDynamicSQLMapper.pageAllList(page, sql, paramMap); + List list = new ArrayList<>(); + for (Map row : rows) { + list.add(new EngStbprpDataVo(row)); + } + result.setData(list); + result.setTotal(page == null ? list.size() : page.getTotal()); + return result; + } + + GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup(); + String groupSql = buildStbprpDataGroupSql(detailSql, request.getGroup(), tableMetaList); + List> rows = microservicDynamicSQLMapper.pageAllList(null, groupSql, paramMap); + if (Boolean.TRUE.equals(request.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal((long) rows.size()); + return result; + } + private DataSourceResult queryOperatSummaryList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -2303,4 +2349,311 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl null; }; } + + private List queryStbprpTableMeta(String tbCode) { + // 1. 解析参数 + List tbCodes = StrUtil.split(tbCode, ',') + .stream() + .map(StrUtil::trim) + .filter(StrUtil::isNotBlank) + .distinct() + .toList(); + + if (tbCodes.isEmpty()) { + return Collections.emptyList(); + } + + // 2. 构建 SQL 和参数 + Map paramMap = new HashMap<>(); + List placeholders = new ArrayList<>(); + for (int i = 0; i < tbCodes.size(); i++) { + String key = "tbCode" + i; + paramMap.put(key, tbCodes.get(i)); + placeholders.add("#{map." + key + "}"); + } + + String sql = "SELECT ID, TB, TB_CODE, STCD_MAPPING, TM_MAPPING " + + "FROM ST_TB_B " + + "WHERE NVL(IS_DELETED, 0) = 0 " + + "AND TB_CODE IN (" + StrUtil.join(", ", placeholders) + ") " + + "ORDER BY TB_CODE"; + + // 3. 执行查询 + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql, paramMap); + + // 4. 转换结果 + List result = new ArrayList<>(); + for (Map row : rows) { + result.add(new StbprpTableMeta( + asString(row.get("ID")), + asString(row.get("TB")), + asString(row.get("TB_CODE")), + StrUtil.blankToDefault(asString(row.get("STCD_MAPPING")), "STCD"), + StrUtil.blankToDefault(asString(row.get("TM_MAPPING")), "TM") + )); + } + return result; + } + + /** + * 安全转为字符串 + */ + private String asString(Object obj) { + return obj == null ? null : obj.toString(); + } + + private String buildStbprpDataDetailSql(DataSourceRequest request, List tableMetaList) { + List selectItems = resolveStbprpSelectItems(request == null ? null : request.getSelect(), tableMetaList); + StringBuilder sql = new StringBuilder("SELECT "); + sql.append(String.join(", ", selectItems)).append(" FROM "); + for (int i = 0; i < tableMetaList.size(); i++) { + StbprpTableMeta meta = tableMetaList.get(i); + String alias = "t" + (i + 1); + if (i == 0) { + sql.append(meta.tableName()).append(" ").append(alias).append(" "); + } else { + StbprpTableMeta first = tableMetaList.getFirst(); + sql.append(" LEFT JOIN ").append(meta.tableName()).append(" ").append(alias) + .append(" ON t1.").append(first.stcdMapping()).append(" = ").append(alias).append(".").append(meta.stcdMapping()) + .append(" AND t1.").append(first.tmMapping()).append(" = ").append(alias).append(".").append(meta.tmMapping()).append(" "); + } + } + sql.append(" WHERE 1 = 1"); + return sql.toString(); + } + + private List resolveStbprpSelectItems(List selectFields, List tableMetaList) { + if (CollUtil.isEmpty(selectFields)) { + return List.of("t1.*"); + } + List items = new ArrayList<>(); + for (String field : selectFields) { + if (StrUtil.isBlank(field)) { + continue; + } + String mapped = mapStbprpField(field, tableMetaList); + if (StrUtil.isNotBlank(mapped)) { + items.add(mapped + " AS \"" + field.trim() + "\""); + } + } + if (items.isEmpty()) { + items.add("t1.*"); + } + return items; + } + + private String buildStbprpDataFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + List tableMetaList) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildStbprpDataLeafCondition(filter, paramMap, indexHolder, tableMetaList); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List childConditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildStbprpDataFilterCondition(child, paramMap, indexHolder, tableMetaList); + if (StrUtil.isNotBlank(childSql)) { + childConditions.add("(" + childSql + ")"); + } + } + if (childConditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, childConditions); + } + + private String buildStbprpDataLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + List tableMetaList) { + String column = mapStbprpField(filter.getField(), tableMetaList); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + boolean dateField = isStbprpDateField(filter); + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeFilterValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "stbprpParam" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add(buildStbprpDataValueExpr(key, dateField, item)); + } + return column + ("ni".equals(operator) ? " NOT IN (" : " IN (") + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "stbprpParam" + indexHolder[0]++; + String expr = buildStbprpDataValueExpr(key, dateField, value); + return switch (operator) { + case "eq" -> { + paramMap.put(key, value); + yield column + " = " + expr; + } + case "neq" -> { + paramMap.put(key, value); + yield column + " <> " + expr; + } + case "contains" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " NOT LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + value); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, value); + yield column + " > " + expr; + } + case "gte" -> { + paramMap.put(key, value); + yield column + " >= " + expr; + } + case "lt" -> { + paramMap.put(key, value); + yield column + " < " + expr; + } + case "lte" -> { + paramMap.put(key, value); + yield column + " <= " + expr; + } + default -> ""; + }; + } + + private String buildStbprpDataValueExpr(String paramKey, boolean dateField, Object value) { + if (!dateField || value == null) { + return "#{map." + paramKey + "}"; + } + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + + private boolean isStbprpDateField(DataSourceRequest.FilterDescriptor filter) { + if (filter == null) { + return false; + } + if ("date".equalsIgnoreCase(filter.getDataType())) { + return true; + } + String field = StrUtil.blankToDefault(filter.getField(), "").trim().toLowerCase(); + if (field.contains(".")) { + field = field.substring(field.lastIndexOf('.') + 1); + } + return "tm".equals(field) || "dt".equals(field); + } + + private String buildStbprpDataOrderBySql(List sortList, List tableMetaList) { + if (CollUtil.isEmpty(sortList)) { + return ""; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapStbprpField(sort.getField(), tableMetaList); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (orderItems.isEmpty()) { + return ""; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildStbprpDataGroupSql(String detailSql, + List groups, + List tableMetaList) { + List selectItems = new ArrayList<>(); + List groupItems = new ArrayList<>(); + List orderItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapStbprpField(descriptor.getField(), tableMetaList); + if (StrUtil.isBlank(column)) { + continue; + } + String upperField = descriptor.getField().trim().toUpperCase(); + selectItems.add(column + " AS " + upperField); + selectItems.add("COUNT(*) AS COUNT_" + upperField); + groupItems.add(column); + String dir = "desc".equalsIgnoreCase(descriptor.getDir()) || "des".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (selectItems.isEmpty()) { + selectItems.add("t1.STCD AS STCD"); + selectItems.add("COUNT(*) AS COUNT_STCD"); + groupItems.add("t1.STCD"); + orderItems.add("t1.STCD ASC"); + } + return "SELECT " + String.join(", ", selectItems) + + " FROM (" + detailSql + ") t1 GROUP BY " + String.join(", ", groupItems) + + " ORDER BY " + String.join(", ", orderItems); + } + + private String mapStbprpField(String field, List tableMetaList) { + if (StrUtil.isBlank(field) || CollUtil.isEmpty(tableMetaList)) { + return null; + } + String normalized = field.trim(); + if (!normalized.contains(".")) { + return "t1." + normalized.toUpperCase(); + } + String[] parts = normalized.split("\\.", 2); + if (parts.length != 2) { + return null; + } + for (int i = 0; i < tableMetaList.size(); i++) { + if (StrUtil.equalsIgnoreCase(tableMetaList.get(i).tbCode(), parts[0])) { + return "t" + (i + 1) + "." + parts[1].toUpperCase(); + } + } + return null; + } + + private record StbprpTableMeta(String id, String tableName, String tbCode, String stcdMapping, String tmMapping) { + } } From d439191a9b2b1d14de0a545bdb8734529e3dcf48 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 14:17:37 +0800 Subject: [PATCH 09/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_base/domain/MsOperationLog.java | 3 + .../impl/MsOperationLogServiceImpl.java | 1 + .../wq/service/impl/EnvWqDataServiceImpl.java | 59 ++++++------------- 3 files changed, 21 insertions(+), 42 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java index 277171ac..55d64cc0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java @@ -29,4 +29,7 @@ public class MsOperationLog implements Serializable { @TableField("REMARK") private String remark; + + @TableField("TABLE_NAME") + private String tableName; } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java index 8e70e7fb..8efc9d86 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java @@ -382,6 +382,7 @@ public class MsOperationLogServiceImpl implements IMsOperationLogService { MsOperationLog log = new MsOperationLog(); log.setOperator(resolveOperator()); log.setOperateTime(new Date()); + log.setTableName(ENG_TABLE_NAME); log.setSource(StrUtil.trimToNull(source)); log.setRemark(remark); return log; diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java index 7ac6d0b1..6778bd2f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java @@ -48,15 +48,6 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { private static final LinkedHashMap WQ_UPDATE_COLUMN_MAP = new LinkedHashMap<>(); private static final Map WQ_FIELD_MEANING_MAP = new LinkedHashMap<>(); - private static final List 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"); @@ -144,8 +135,6 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { 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 @@ -4176,12 +4165,19 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { List details = new ArrayList<>(); for (Map 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, "删除记录")); + for (Map.Entry entry : row.entrySet()) { + String fieldCode = entry.getKey(); + if (StrUtil.isBlank(fieldCode)) { + continue; + } + Object oldValue = entry.getValue(); + if (oldValue == null) { + continue; + } + details.add(buildWqDetail(mainLog.getId(), tableName, stcd, fieldCode, + oldValue, resolveWqDisplayValue(fieldCode, oldValue), + null, null, "删除字段值")); + } } batchInsertWqLogDetails(details); } @@ -4190,6 +4186,7 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { MsOperationLog log = new MsOperationLog(); log.setOperator(resolveLogOperator()); log.setOperateTime(new Date()); + log.setTableName(WQ_HOUR_TABLE_NAME); log.setSource(StrUtil.trimToNull(source)); log.setRemark(remark); return log; @@ -4222,34 +4219,12 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { if (CollUtil.isEmpty(details)) { return; } - msOperationLogDetailMapper.insert(details); - } - - private String buildWqRowKey(String tableName, Map 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 row) { - if (row == null || row.isEmpty()) { - return null; - } - List parts = new ArrayList<>(); - for (String column : WQ_SNAPSHOT_COLUMNS) { - Object value = row.get(column); - String text = formatLogValue(value); - if (StrUtil.isBlank(text)) { + for (MsOperationLogDetail detail : details) { + if (detail == null) { continue; } - parts.add(column + "=" + text); + msOperationLogDetailMapper.insert(detail); } - return parts.isEmpty() ? null : String.join("; ", parts); } private Object resolveWqDisplayValue(String fieldCode, Object rawValue) { From e68500343e50dfc9237e0ead90fbb413441129bc Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 14:25:22 +0800 Subject: [PATCH 10/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=A1=A8?= =?UTF-8?q?=E5=B1=82=E6=B0=B4=E6=B8=A9=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wt/controller/SdWTMonitorController.java | 10 +- .../wt/service/AlongDetailService.java | 4 +- .../service/impl/AlongDetailServiceImpl.java | 240 +++++++++++++++++- 3 files changed, 246 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java index f72e1270..bd654d5d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.wt.controller; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.annotation.Log; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; @@ -55,10 +56,14 @@ public class SdWTMonitorController { return ResponseResult.successData(result); } + @Log(module = "水温监测", value = "修改表层水温日数据") @PostMapping("/alongDetail/updateWtrvRData") @Operation(summary = "修改表层水温日数据") - public ResponseResult updateWtrvRData(@RequestBody Map updateData) { - alongDetailService.updateWtrvRData(updateData); + public ResponseResult updateWtrvRData(@RequestBody WtOperateRequest wtOperateRequest) { + alongDetailService.updateWtrvRData( + wtOperateRequest == null ? null : wtOperateRequest.getUpdateData(), + wtOperateRequest == null ? null : wtOperateRequest.getSource() + ); return ResponseResult.success(); } @@ -76,6 +81,7 @@ public class SdWTMonitorController { return ResponseResult.successData(result); } + @Log(module = "水温监测", value = "删除出库水温周旬月季年数据") @PostMapping("/alongDetail/drtp/removeKendoByIds") @Operation(summary = "删除出库水温周旬月季年数据") public ResponseResult removeKendoByIds(@RequestBody BatchDeleteAo batchDeleteAo) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java index 5465ec79..a4de4324 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/AlongDetailService.java @@ -43,6 +43,6 @@ public interface AlongDetailService extends IService { boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); - void updateWtrvRData(Map updateData); + void updateWtrvRData(Map updateData, String source); -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java index 009f7cf6..12572375 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java @@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.common.*; 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_env.wt.mapper.AlongDetailMapper; import com.yfd.platform.qgc_env.wt.mapper.SdWtrvdrtpSMapper; import com.yfd.platform.qgc_env.wt.service.AlongDetailService; @@ -17,6 +19,8 @@ import com.yfd.platform.qgc_env.wt.entity.vo.SdAlongDrtpDetailVO; import com.yfd.platform.qgc_env.wt.entity.vo.WtrvInfo; import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo; 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.utils.CollectionExtUtils; import com.yfd.platform.utils.QgcQueryWrapperUtil; import com.yfd.platform.utils.SecurityUtils; @@ -37,6 +41,29 @@ import java.util.stream.Collectors; */ @Service public class AlongDetailServiceImpl extends ServiceImpl implements AlongDetailService { + private static final String WT_HOUR_TABLE_NAME = "SD_WTRV_R"; + private static final Map WT_UPDATE_COLUMN_MAP = new LinkedHashMap<>(); + private static final Map WT_FIELD_MEANING_MAP = new LinkedHashMap<>(); + + static { + WT_UPDATE_COLUMN_MAP.put("wt", "WT"); + + WT_FIELD_MEANING_MAP.put("ID", "主键ID"); + WT_FIELD_MEANING_MAP.put("STCD", "水温站编码"); + WT_FIELD_MEANING_MAP.put("TM", "数据时间"); + WT_FIELD_MEANING_MAP.put("WT", "水温"); + WT_FIELD_MEANING_MAP.put("REMARK", "备注"); + WT_FIELD_MEANING_MAP.put("FID", "附件ID"); + WT_FIELD_MEANING_MAP.put("WER_ID", "所属水生生态调查数据表ID"); + WT_FIELD_MEANING_MAP.put("RECORD_USER", "创建人"); + WT_FIELD_MEANING_MAP.put("RECORD_TIME", "创建时间"); + WT_FIELD_MEANING_MAP.put("MODIFY_USER", "更新人"); + WT_FIELD_MEANING_MAP.put("MODIFY_TIME", "更新时间"); + WT_FIELD_MEANING_MAP.put("IS_DELETED", "是否已删除"); + WT_FIELD_MEANING_MAP.put("DELETE_USER", "删除人"); + WT_FIELD_MEANING_MAP.put("DELETE_TIME", "删除时间"); + } + @Resource private DynamicSQLMapper dynamicSQLMapper; @Resource @@ -50,6 +77,12 @@ public class AlongDetailServiceImpl extends ServiceImpl filterResult, Page page) { DataSourceResult dataSourceResult = new DataSourceResult(); @@ -799,6 +832,7 @@ public class AlongDetailServiceImpl extends ServiceImpl dataList = batchDeleteAo.getDataList(); + String source = batchDeleteAo == null ? null : batchDeleteAo.getSource(); if(CollUtil.isEmpty(dataList)){ return true; } @@ -816,7 +850,9 @@ public class AlongDetailServiceImpl extends ServiceImpl> beforeRows = queryWtHourRows(subList); sdWtrvdrtpSMapper.deleteWtrvRData(subList, DateUtil.now(), SecurityUtils.getCurrentUsername()); + recordWtDeleteLog(beforeRows, "删除表层水温日数据", source); // 删除小时数据后,需要重新统计对应的日数据和月数据 Map dateRangeMap = new HashMap<>(); Map monthRangeMap = new HashMap<>(); @@ -1048,13 +1084,14 @@ public class AlongDetailServiceImpl extends ServiceImpl updateData) { + public void updateWtrvRData(Map updateData, String source) { + String stcd = asString(getValueIgnoreCase(updateData, "stcd")); + String tm = asString(getValueIgnoreCase(updateData, "dt")); + Map beforeRow = queryWtHourRow(stcd, tm); sdWtrvdrtpSMapper.updateWtrvRData(updateData); + recordWtUpdateLog(beforeRow, updateData, source); // 获取测站编码和时间 - String stcd = (String) updateData.get("stcd"); - String tm = (String) updateData.get("dt"); - if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm)) { // 提取日期部分(yyyy-MM-dd) String dateStr = tm.substring(0, 10); @@ -1074,4 +1111,199 @@ public class AlongDetailServiceImpl extends ServiceImpl queryWtHourRow(String stcd, String tm) { + if (StrUtil.isBlank(stcd) || StrUtil.isBlank(tm)) { + return new HashMap<>(); + } + String sql = "SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WT, REMARK, FID, WER_ID, " + + "RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME " + + "FROM SD_WTRV_R WHERE STCD = ? AND TM = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS')"; + List> rows = jdbcTemplate.queryForList(sql, stcd, tm); + return rows.isEmpty() ? new HashMap<>() : normalizeWtLogRow(rows.getFirst()); + } + + private List> queryWtHourRows(List dataParamList) { + if (CollUtil.isEmpty(dataParamList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WT, REMARK, FID, WER_ID, ") + .append("RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME ") + .append("FROM SD_WTRV_R WHERE "); + List params = new ArrayList<>(); + 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.getDt()); + } + return normalizeWtLogRows(jdbcTemplate.queryForList(sql.toString(), params.toArray())); + } + + private List> normalizeWtLogRows(List> rows) { + List> result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + result.add(normalizeWtLogRow(row)); + } + return result; + } + + private Map normalizeWtLogRow(Map row) { + Map normalized = new LinkedHashMap<>(); + if (row == null || row.isEmpty()) { + return normalized; + } + for (Map.Entry entry : row.entrySet()) { + normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue()); + } + return normalized; + } + + private void recordWtUpdateLog(Map beforeRow, Map updateData, String source) { + if (updateData == null || updateData.isEmpty()) { + return; + } + String stcd = asString(getValueIgnoreCase(updateData, "stcd")); + List details = new ArrayList<>(); + for (Map.Entry entry : WT_UPDATE_COLUMN_MAP.entrySet()) { + if (!containsKeyIgnoreCase(updateData, entry.getKey())) { + continue; + } + String column = entry.getValue(); + Object oldValue = beforeRow == null ? null : beforeRow.get(column); + Object newValue = getValueIgnoreCase(updateData, entry.getKey()); + if (StrUtil.equals(formatWtLogValue(oldValue), formatWtLogValue(newValue))) { + continue; + } + details.add(buildWtDetail(null, stcd, column, + oldValue, resolveWtDisplayValue(column, oldValue), + newValue, resolveWtDisplayValue(column, newValue), "修改字段值")); + } + if (details.isEmpty()) { + return; + } + MsOperationLog mainLog = buildWtMainLog("修改表层水温日数据", source); + msOperationLogMapper.insert(mainLog); + for (MsOperationLogDetail detail : details) { + detail.setMainId(mainLog.getId()); + } + batchInsertWtLogDetails(details); + } + + private void recordWtDeleteLog(List> rows, String remark, String source) { + if (CollUtil.isEmpty(rows)) { + return; + } + MsOperationLog mainLog = buildWtMainLog(remark, source); + msOperationLogMapper.insert(mainLog); + List details = new ArrayList<>(); + for (Map row : rows) { + String stcd = asString(row.get("STCD")); + for (Map.Entry entry : row.entrySet()) { + String fieldCode = entry.getKey(); + Object oldValue = entry.getValue(); + if (StrUtil.isBlank(fieldCode) || oldValue == null) { + continue; + } + details.add(buildWtDetail(mainLog.getId(), stcd, fieldCode, + oldValue, resolveWtDisplayValue(fieldCode, oldValue), + null, null, "删除字段值")); + } + } + batchInsertWtLogDetails(details); + } + + private MsOperationLog buildWtMainLog(String remark, String source) { + MsOperationLog log = new MsOperationLog(); + log.setOperator(resolveWtLogOperator()); + log.setOperateTime(new Date()); + log.setSource(StrUtil.trimToNull(source)); + log.setRemark(remark); + return log; + } + + private MsOperationLogDetail buildWtDetail(String mainId, + String stationCode, + String fieldCode, + Object oldValueCode, + Object oldValueName, + Object newValueCode, + Object newValueName, + String remark) { + MsOperationLogDetail detail = new MsOperationLogDetail(); + detail.setMainId(mainId); + detail.setTableName(WT_HOUR_TABLE_NAME); + detail.setStationCode(stationCode); + detail.setFieldCode(fieldCode); + detail.setFieldMeaning(WT_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode)); + detail.setOldValueCode(formatWtLogValue(oldValueCode)); + detail.setOldValueName(formatWtLogValue(oldValueName)); + detail.setNewValueCode(formatWtLogValue(newValueCode)); + detail.setNewValueName(formatWtLogValue(newValueName)); + detail.setRemark(remark); + return detail; + } + + private void batchInsertWtLogDetails(List details) { + if (CollUtil.isEmpty(details)) { + return; + } + for (MsOperationLogDetail detail : details) { + if (detail == null) { + continue; + } + msOperationLogDetailMapper.insert(detail); + } + } + + private Object resolveWtDisplayValue(String fieldCode, Object rawValue) { + return formatWtLogValue(rawValue); + } + + private String resolveWtLogOperator() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception ignored) { + try { + return SecurityUtils.getUserId(); + } catch (Exception ex) { + return null; + } + } + } + + private String formatWtLogValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return DateUtil.formatDateTime(date); + } + return String.valueOf(value); + } + + private String asString(Object value) { + return value == null ? null : String.valueOf(value); + } + + private boolean containsKeyIgnoreCase(Map data, String key) { + if (data == null || StrUtil.isBlank(key)) { + return false; + } + if (data.containsKey(key)) { + return true; + } + for (String mapKey : data.keySet()) { + if (StrUtil.equalsIgnoreCase(mapKey, key)) { + return true; + } + } + return false; + } } From 2149d7c4e8f17df1989a483cbde19ed91ee90b49 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 15:35:39 +0800 Subject: [PATCH 11/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_base/domain/MsOperationLog.java | 4 + .../impl/MsOperationLogServiceImpl.java | 9 +- .../wq/service/impl/EnvWqDataServiceImpl.java | 15 +- .../service/impl/AlongDetailServiceImpl.java | 13 +- .../zq/controller/ZqMonitorController.java | 8 +- .../qgc_env/zq/service/ZqMonitorService.java | 2 +- .../zq/service/impl/ZqMonitorServiceImpl.java | 329 +++++++++++++++++- 7 files changed, 361 insertions(+), 19 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java index 55d64cc0..04d9e34a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsOperationLog.java @@ -32,4 +32,8 @@ public class MsOperationLog implements Serializable { @TableField("TABLE_NAME") private String tableName; + + @TableField("RECORD_ID") + private String recordId; + } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java index 8efc9d86..a915ff1d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsOperationLogServiceImpl.java @@ -275,7 +275,7 @@ public class MsOperationLogServiceImpl implements IMsOperationLogService { if (engInfo == null) { return; } - MsOperationLog mainLog = buildMainLog("新增电站", source); + MsOperationLog mainLog = buildMainLog(null,"新增电站", source); msOperationLogMapper.insert(mainLog); List details = new ArrayList<>(); @@ -311,7 +311,7 @@ public class MsOperationLogServiceImpl implements IMsOperationLogService { return; } - MsOperationLog mainLog = buildMainLog("修改电站", source); + MsOperationLog mainLog = buildMainLog(before.getStcd(),"修改电站", source); msOperationLogMapper.insert(mainLog); List details = new ArrayList<>(); @@ -348,7 +348,7 @@ public class MsOperationLogServiceImpl implements IMsOperationLogService { if (engInfo == null) { return; } - MsOperationLog mainLog = buildMainLog("删除电站", source); + MsOperationLog mainLog = buildMainLog(engInfo.getStcd(),"删除电站", source); msOperationLogMapper.insert(mainLog); List details = new ArrayList<>(); @@ -378,11 +378,12 @@ public class MsOperationLogServiceImpl implements IMsOperationLogService { batchInsertDetails(details); } - private MsOperationLog buildMainLog(String remark, String source) { + private MsOperationLog buildMainLog(String recordId,String remark, String source) { MsOperationLog log = new MsOperationLog(); log.setOperator(resolveOperator()); log.setOperateTime(new Date()); log.setTableName(ENG_TABLE_NAME); + log.setRecordId(recordId); log.setSource(StrUtil.trimToNull(source)); log.setRemark(remark); return log; diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java index 6778bd2f..e041cf54 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wq/service/impl/EnvWqDataServiceImpl.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.wq.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.*; @@ -4071,7 +4072,7 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { } private String buildWqHourLogSelectColumns() { - return "STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, " + + return "ID,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"; @@ -4148,7 +4149,9 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { if (details.isEmpty()) { return; } - MsOperationLog mainLog = buildWqMainLog("修改水质小时数据", source); + String recordId = ObjectUtil.isNotEmpty(beforeHour) && ObjectUtil.isNotEmpty(beforeHour.get("ID")) + ? beforeHour.get("ID").toString() + : null; MsOperationLog mainLog = buildWqMainLog(recordId,"修改水质小时数据", source); msOperationLogMapper.insert(mainLog); for (MsOperationLogDetail detail : details) { detail.setMainId(mainLog.getId()); @@ -4160,11 +4163,12 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { if (CollUtil.isEmpty(rows)) { return; } - MsOperationLog mainLog = buildWqMainLog(remark, source); - msOperationLogMapper.insert(mainLog); List details = new ArrayList<>(); for (Map row : rows) { String stcd = asString(row.get("STCD")); + String recordId = asString(row.get("ID")); + MsOperationLog mainLog = buildWqMainLog(recordId,remark, source); + msOperationLogMapper.insert(mainLog); for (Map.Entry entry : row.entrySet()) { String fieldCode = entry.getKey(); if (StrUtil.isBlank(fieldCode)) { @@ -4182,9 +4186,10 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { batchInsertWqLogDetails(details); } - private MsOperationLog buildWqMainLog(String remark, String source) { + private MsOperationLog buildWqMainLog(String recordId,String remark, String source) { MsOperationLog log = new MsOperationLog(); log.setOperator(resolveLogOperator()); + log.setRecordId(recordId); log.setOperateTime(new Date()); log.setTableName(WQ_HOUR_TABLE_NAME); log.setSource(StrUtil.trimToNull(source)); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java index 12572375..13596442 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/AlongDetailServiceImpl.java @@ -1170,6 +1170,7 @@ public class AlongDetailServiceImpl extends ServiceImpl details = new ArrayList<>(); for (Map.Entry entry : WT_UPDATE_COLUMN_MAP.entrySet()) { if (!containsKeyIgnoreCase(updateData, entry.getKey())) { @@ -1188,7 +1189,7 @@ public class AlongDetailServiceImpl extends ServiceImpl details = new ArrayList<>(); for (Map row : rows) { String stcd = asString(row.get("STCD")); + String recordId = asString(row.get("ID")); + MsOperationLog mainLog = buildWtMainLog(recordId,remark, source); + msOperationLogMapper.insert(mainLog); for (Map.Entry entry : row.entrySet()) { String fieldCode = entry.getKey(); Object oldValue = entry.getValue(); @@ -1219,10 +1222,12 @@ public class AlongDetailServiceImpl extends ServiceImpl updateData); + boolean updateRiverRData(java.util.Map updateData, String source); ZqBaseInfoVo getStcdInfo(String stcd); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/zq/service/impl/ZqMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/zq/service/impl/ZqMonitorServiceImpl.java index 1bd2c665..923af1cd 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/zq/service/impl/ZqMonitorServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/zq/service/impl/ZqMonitorServiceImpl.java @@ -10,8 +10,12 @@ import com.yfd.platform.common.GroupHelper; import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; 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.DataParam; +import com.yfd.platform.qgc_base.mapper.MsOperationLogDetailMapper; +import com.yfd.platform.qgc_base.mapper.MsOperationLogMapper; import com.yfd.platform.qgc_env.fh.entity.vo.HabitatVo; import com.yfd.platform.qgc_env.zq.entity.vo.ZqBaseInfoVo; import com.yfd.platform.qgc_env.zq.entity.vo.ZqRiverDayDataVo; @@ -19,23 +23,58 @@ import com.yfd.platform.qgc_env.zq.entity.vo.ZqRiverDrtpDataVo; import com.yfd.platform.qgc_env.zq.entity.vo.ZqRiverDataVo; import com.yfd.platform.qgc_env.zq.service.ZqMonitorService; import com.yfd.platform.utils.QgcQueryWrapperUtil; +import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.jdbc.core.JdbcTemplate; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Date; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @Service public class ZqMonitorServiceImpl implements ZqMonitorService { + private static final String ZQ_HOUR_TABLE_NAME = "SD_RIVER_R"; + private static final String ZQ_DAY_TABLE_NAME = "SD_RIVERDAY_S"; + private static final String ZQ_MONTH_TABLE_NAME = "SD_RIVERDRTP_S"; + private static final Map ZQ_UPDATE_COLUMN_MAP = new LinkedHashMap<>(); + private static final Map ZQ_FIELD_MEANING_MAP = new LinkedHashMap<>(); + + static { + ZQ_UPDATE_COLUMN_MAP.put("z", "Z"); + ZQ_UPDATE_COLUMN_MAP.put("q", "Q"); + ZQ_UPDATE_COLUMN_MAP.put("v", "V"); + + ZQ_FIELD_MEANING_MAP.put("ID", "主键ID"); + ZQ_FIELD_MEANING_MAP.put("STCD", "站码"); + ZQ_FIELD_MEANING_MAP.put("TM", "时间"); + ZQ_FIELD_MEANING_MAP.put("DT", "时间"); + ZQ_FIELD_MEANING_MAP.put("DRTP", "维度类型"); + ZQ_FIELD_MEANING_MAP.put("YEAR", "年"); + ZQ_FIELD_MEANING_MAP.put("MONTH", "月"); + ZQ_FIELD_MEANING_MAP.put("DR", "时段类型"); + ZQ_FIELD_MEANING_MAP.put("Z", "水位"); + ZQ_FIELD_MEANING_MAP.put("Q", "流量"); + ZQ_FIELD_MEANING_MAP.put("V", "流速"); + ZQ_FIELD_MEANING_MAP.put("MSQMT", "测流方法"); + ZQ_FIELD_MEANING_MAP.put("RECORD_USER", "创建人"); + ZQ_FIELD_MEANING_MAP.put("RECORD_TIME", "创建时间"); + ZQ_FIELD_MEANING_MAP.put("MODIFY_USER", "更新人"); + ZQ_FIELD_MEANING_MAP.put("MODIFY_TIME", "更新时间"); + ZQ_FIELD_MEANING_MAP.put("IS_DELETED", "是否已删除"); + ZQ_FIELD_MEANING_MAP.put("DELETE_USER", "删除人"); + ZQ_FIELD_MEANING_MAP.put("DELETE_TIME", "删除时间"); + ZQ_FIELD_MEANING_MAP.put("FID", "附件ID"); + ZQ_FIELD_MEANING_MAP.put("REMARK", "备注"); + } @Resource private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; @@ -43,6 +82,12 @@ public class ZqMonitorServiceImpl implements ZqMonitorService { @Resource private JdbcTemplate jdbcTemplate; + @Resource + private MsOperationLogMapper msOperationLogMapper; + + @Resource + private MsOperationLogDetailMapper msOperationLogDetailMapper; + @Override public DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest) { return getMsstbprptListInternal(dataSourceRequest, false); @@ -170,11 +215,14 @@ public class ZqMonitorServiceImpl implements ZqMonitorService { } String dataType = batchDeleteAo.getDataType(); List dataList = batchDeleteAo.getDataList(); + String source = batchDeleteAo.getSource(); int batchSize = 500; for (int i = 0; i < dataList.size(); i += batchSize) { List subList = dataList.subList(i, Math.min(i + batchSize, dataList.size())); if ("TIME".equals(dataType)) { + List> beforeRows = queryRiverHourRows(subList); deleteRiverRData(subList); + recordRiverDeleteLog(beforeRows, ZQ_HOUR_TABLE_NAME, "删除流量站小时数据", source); Map dateRangeMap = new HashMap<>(); Map monthRangeMap = new HashMap<>(); for (DataParam param : subList) { @@ -209,10 +257,14 @@ public class ZqMonitorServiceImpl implements ZqMonitorService { } } if ("DATE".equals(dataType)) { + List> beforeRows = queryRiverDayRows(subList); deleteRiverDayData(subList); + recordRiverDeleteLog(beforeRows, ZQ_DAY_TABLE_NAME, "删除流量站日数据", source); } if ("MON".equals(dataType)) { + List> beforeRows = queryRiverMonthRows(subList); deleteRiverMonthData(subList); + recordRiverDeleteLog(beforeRows, ZQ_MONTH_TABLE_NAME, "删除流量站月数据", source); } } return true; @@ -220,10 +272,12 @@ public class ZqMonitorServiceImpl implements ZqMonitorService { @Override @Transactional(rollbackFor = Exception.class) - public boolean updateRiverRData(Map updateData) { - updateRiverHourData(updateData); + public boolean updateRiverRData(Map updateData, String source) { String stcd = updateData == null ? null : asString(updateData.get("stcd")); String tm = updateData == null ? null : asString(updateData.get("tm")); + Map beforeRow = queryRiverHourRow(stcd, tm); + updateRiverHourData(updateData); + recordRiverUpdateLog(beforeRow, updateData, source); if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm) && tm.length() >= 10) { String dateStr = tm.substring(0, 10); statisticsDayDataFromHour(stcd, dateStr, dateStr); @@ -1612,6 +1666,273 @@ public class ZqMonitorServiceImpl implements ZqMonitorService { return value == null ? null : String.valueOf(value); } + private Map queryRiverHourRow(String stcd, String tm) { + if (StrUtil.isBlank(stcd) || StrUtil.isBlank(tm)) { + return new HashMap<>(); + } + String sql = "SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, Z, Q, V, MSQMT, RECORD_USER, " + + "RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME, FID, REMARK " + + "FROM SD_RIVER_R WHERE STCD = ? AND TM = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS')"; + List> rows = jdbcTemplate.queryForList(sql, stcd, tm); + return rows.isEmpty() ? new HashMap<>() : normalizeRiverLogRow(rows.getFirst()); + } + + private List> queryRiverHourRows(List dataList) { + if (CollUtil.isEmpty(dataList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, Z, Q, V, MSQMT, RECORD_USER, ") + .append("RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME, FID, REMARK ") + .append("FROM SD_RIVER_R WHERE "); + List args = new ArrayList<>(); + List conditions = new ArrayList<>(); + for (DataParam item : dataList) { + if (item == null || StrUtil.isBlank(item.getId()) || StrUtil.isBlank(item.getTm())) { + continue; + } + conditions.add("(STCD = ? AND TM = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'))"); + args.add(item.getId()); + args.add(item.getTm()); + } + if (conditions.isEmpty()) { + return new ArrayList<>(); + } + sql.append(String.join(" OR ", conditions)); + return normalizeRiverLogRows(jdbcTemplate.queryForList(sql.toString(), args.toArray())); + } + + private List> queryRiverDayRows(List dataList) { + if (CollUtil.isEmpty(dataList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ID, STCD, TO_CHAR(DT, 'YYYY-MM-DD HH24:MI:SS') AS DT, Z, Q, V, MSQMT, RECORD_USER, ") + .append("RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME ") + .append("FROM SD_RIVERDAY_S WHERE "); + List args = new ArrayList<>(); + List conditions = new ArrayList<>(); + for (DataParam item : dataList) { + if (item == null || StrUtil.isBlank(item.getId()) || StrUtil.isBlank(item.getDt())) { + continue; + } + conditions.add("(STCD = ? AND DT = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'))"); + args.add(item.getId()); + args.add(item.getDt()); + } + if (conditions.isEmpty()) { + return new ArrayList<>(); + } + sql.append(String.join(" OR ", conditions)); + return normalizeRiverLogRows(jdbcTemplate.queryForList(sql.toString(), args.toArray())); + } + + private List> queryRiverMonthRows(List dataList) { + if (CollUtil.isEmpty(dataList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, DRTP, YEAR, MONTH, DR, Z, Q, V, MSQMT, ") + .append("RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME ") + .append("FROM SD_RIVERDRTP_S WHERE "); + List args = new ArrayList<>(); + List conditions = new ArrayList<>(); + for (DataParam item : dataList) { + if (item == null || StrUtil.isBlank(item.getId()) || StrUtil.isBlank(item.getDrtp()) + || StrUtil.isBlank(item.getYear()) || StrUtil.isBlank(item.getMonth())) { + continue; + } + conditions.add("(STCD = ? AND DRTP = ? AND YEAR = ? AND MONTH = ?)"); + args.add(item.getId()); + args.add(item.getDrtp()); + args.add(Integer.parseInt(item.getYear())); + args.add(Integer.parseInt(item.getMonth())); + } + if (conditions.isEmpty()) { + return new ArrayList<>(); + } + sql.append(String.join(" OR ", conditions)); + return normalizeRiverLogRows(jdbcTemplate.queryForList(sql.toString(), args.toArray())); + } + + private List> normalizeRiverLogRows(List> rows) { + List> result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + result.add(normalizeRiverLogRow(row)); + } + return result; + } + + private Map normalizeRiverLogRow(Map row) { + Map normalized = new LinkedHashMap<>(); + if (row == null || row.isEmpty()) { + return normalized; + } + for (Map.Entry entry : row.entrySet()) { + normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue()); + } + return normalized; + } + + private void recordRiverUpdateLog(Map beforeRow, Map updateData, String source) { + if (updateData == null || updateData.isEmpty()) { + return; + } + String stcd = asString(updateData.get("stcd")); + String recordId = asString(beforeRow.get("ID")); + List details = new ArrayList<>(); + for (Map.Entry entry : ZQ_UPDATE_COLUMN_MAP.entrySet()) { + if (!containsKeyIgnoreCase(updateData, entry.getKey())) { + continue; + } + String column = entry.getValue(); + Object oldValue = beforeRow == null ? null : beforeRow.get(column); + Object newValue = getValueIgnoreCase(updateData, entry.getKey()); + if (StrUtil.equals(formatRiverLogValue(oldValue), formatRiverLogValue(newValue))) { + continue; + } + details.add(buildRiverLogDetail(null, ZQ_HOUR_TABLE_NAME, stcd, column, + oldValue, resolveRiverDisplayValue(column, oldValue), + newValue, resolveRiverDisplayValue(column, newValue), "修改字段值")); + } + if (details.isEmpty()) { + return; + } + MsOperationLog mainLog = buildRiverMainLog(recordId,"修改流量站小时数据", source); + msOperationLogMapper.insert(mainLog); + for (MsOperationLogDetail detail : details) { + detail.setMainId(mainLog.getId()); + } + batchInsertRiverLogDetails(details); + } + + private void recordRiverDeleteLog(List> rows, String tableName, String remark, String source) { + if (CollUtil.isEmpty(rows)) { + return; + } + + List details = new ArrayList<>(); + for (Map row : rows) { + String stcd = asString(row.get("STCD")); + String recordId = asString(row.get("ID")); + MsOperationLog mainLog = buildRiverMainLog(recordId,remark, source); + msOperationLogMapper.insert(mainLog); + for (Map.Entry entry : row.entrySet()) { + String fieldCode = entry.getKey(); + Object oldValue = entry.getValue(); + if (StrUtil.isBlank(fieldCode) || oldValue == null) { + continue; + } + details.add(buildRiverLogDetail(mainLog.getId(), tableName, stcd, fieldCode, + oldValue, resolveRiverDisplayValue(fieldCode, oldValue), + null, null, "删除字段值")); + } + } + batchInsertRiverLogDetails(details); + } + + private MsOperationLog buildRiverMainLog(String recordId,String remark, String source) { + MsOperationLog log = new MsOperationLog(); + log.setOperator(resolveRiverLogOperator()); + log.setOperateTime(new Date()); + log.setRecordId(recordId); + log.setTableName(ZQ_HOUR_TABLE_NAME); + log.setSource(StrUtil.trimToNull(source)); + log.setRemark(remark); + return log; + } + + private MsOperationLogDetail buildRiverLogDetail(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(ZQ_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode)); + detail.setOldValueCode(formatRiverLogValue(oldValueCode)); + detail.setOldValueName(formatRiverLogValue(oldValueName)); + detail.setNewValueCode(formatRiverLogValue(newValueCode)); + detail.setNewValueName(formatRiverLogValue(newValueName)); + detail.setRemark(remark); + return detail; + } + + private void batchInsertRiverLogDetails(List details) { + if (CollUtil.isEmpty(details)) { + return; + } + for (MsOperationLogDetail detail : details) { + if (detail == null) { + continue; + } + msOperationLogDetailMapper.insert(detail); + } + } + + private Object resolveRiverDisplayValue(String fieldCode, Object rawValue) { + return formatRiverLogValue(rawValue); + } + + private Object getValueIgnoreCase(Map data, String key) { + if (data == null || StrUtil.isBlank(key)) { + return null; + } + if (data.containsKey(key)) { + return data.get(key); + } + for (Map.Entry entry : data.entrySet()) { + if (StrUtil.equalsIgnoreCase(entry.getKey(), key)) { + return entry.getValue(); + } + } + return null; + } + + private boolean containsKeyIgnoreCase(Map data, String key) { + if (data == null || StrUtil.isBlank(key)) { + return false; + } + if (data.containsKey(key)) { + return true; + } + for (String mapKey : data.keySet()) { + if (StrUtil.equalsIgnoreCase(mapKey, key)) { + return true; + } + } + return false; + } + + private String resolveRiverLogOperator() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception ignored) { + try { + return SecurityUtils.getUserId(); + } catch (Exception ex) { + return null; + } + } + } + + private String formatRiverLogValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return cn.hutool.core.date.DateUtil.formatDateTime(date); + } + return String.valueOf(value); + } + private void statisticsDayDataFromHour(String stcd, String startDate, String endDate) { String deleteSql = "DELETE FROM SD_RIVERDAY_S T " + "WHERE T.STCD = ? " + From 329343c371652a6f1460047a212dfb71f9973433 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:09:50 +0800 Subject: [PATCH 12/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=9E=82=E5=90=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wt/controller/SdWTMonitorController.java | 7 +- .../qgc_env/wt/service/SdWtvtRService.java | 2 +- .../wt/service/impl/SdWtvtRServiceImpl.java | 221 +++++++++++++++++- 3 files changed, 227 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java index bd654d5d..8212bef8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/controller/SdWTMonitorController.java @@ -243,6 +243,7 @@ public class SdWTMonitorController { return ResponseResult.successData(sdWtMonitorService.getCxDetailList(dataSourceRequest)); } + @Log(module = "水温监测", value = "删除垂向水温数据") @PostMapping("/cxDetail/removeKendoByIds") @Operation(summary = "删除垂向水温数据") public ResponseResult removeCxDetailByIds(@RequestBody BatchDeleteAo batchDeleteAo) { @@ -250,10 +251,14 @@ public class SdWTMonitorController { return ResponseResult.success(); } + @Log(module = "水温监测", value = "修改垂向水温数据") @PostMapping("/cxDetail/updateWtvtRData") @Operation(summary = "修改垂向水温数据") public ResponseResult updateWtvtRData(@RequestBody WtOperateRequest wtOperateRequest) { - sdWtvtRService.updateWtvtRData(wtOperateRequest.getUpdateData()); + sdWtvtRService.updateWtvtRData( + wtOperateRequest == null ? null : wtOperateRequest.getUpdateData(), + wtOperateRequest == null ? null : wtOperateRequest.getSource() + ); return ResponseResult.success(); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java index 2b62f2b3..43c165a0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/SdWtvtRService.java @@ -24,5 +24,5 @@ public interface SdWtvtRService { boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); - void updateWtvtRData(Map updateData); + void updateWtvtRData(Map updateData, String source); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java index c91fcda6..80a91b5a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wt/service/impl/SdWtvtRServiceImpl.java @@ -1,13 +1,18 @@ package com.yfd.platform.qgc_env.wt.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; 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.entity.vo.BatchDeleteAo; 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.wt.entity.vo.SdWtvtYearVo; import com.yfd.platform.qgc_env.wt.mapper.SdWtvtRMapper; import com.yfd.platform.qgc_env.wt.service.SdWtvtRService; @@ -22,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import java.util.HashSet; import java.util.HashMap; import java.util.List; @@ -37,6 +43,28 @@ import java.util.Set; */ @Service public class SdWtvtRServiceImpl extends ServiceImpl implements SdWtvtRService { + private static final String WT_CX_TABLE_NAME = "SD_WTVT_R"; + private static final Map WT_CX_FIELD_MEANING_MAP = new LinkedHashMap<>(); + + static { + WT_CX_FIELD_MEANING_MAP.put("ID", "主键ID"); + WT_CX_FIELD_MEANING_MAP.put("STCD", "垂向水温站编码"); + WT_CX_FIELD_MEANING_MAP.put("TM", "时间"); + WT_CX_FIELD_MEANING_MAP.put("WTHG", "水温深度"); + WT_CX_FIELD_MEANING_MAP.put("VWT", "水温"); + WT_CX_FIELD_MEANING_MAP.put("FID", "附件ID"); + WT_CX_FIELD_MEANING_MAP.put("RECORD_USER", "创建人"); + WT_CX_FIELD_MEANING_MAP.put("RECORD_TIME", "创建时间"); + WT_CX_FIELD_MEANING_MAP.put("MODIFY_USER", "更新人"); + WT_CX_FIELD_MEANING_MAP.put("MODIFY_TIME", "更新时间"); + WT_CX_FIELD_MEANING_MAP.put("IS_DELETED", "是否已删除"); + WT_CX_FIELD_MEANING_MAP.put("DELETE_USER", "删除人"); + WT_CX_FIELD_MEANING_MAP.put("DELETE_TIME", "删除时间"); + WT_CX_FIELD_MEANING_MAP.put("RZ", "坝前水位"); + WT_CX_FIELD_MEANING_MAP.put("HGT", "测点高程"); + WT_CX_FIELD_MEANING_MAP.put("REMARK", "备注"); + WT_CX_FIELD_MEANING_MAP.put("WER_ID", "所属水生生态调查数据表ID"); + } @Resource private SdWtvtRMapper sdWtvtRMapper; @@ -47,6 +75,12 @@ public class SdWtvtRServiceImpl extends ServiceImpl @Resource private JdbcTemplate jdbcTemplate; + @Resource + private MsOperationLogMapper msOperationLogMapper; + + @Resource + private MsOperationLogDetailMapper msOperationLogDetailMapper; + @Override public DataSourceResult getWtrvDefaultYear(DataSourceRequest dataSourceRequest) { DataSourceResult dataSourceResult = new DataSourceResult<>(); @@ -91,6 +125,7 @@ public class SdWtvtRServiceImpl extends ServiceImpl public boolean removeKendoByIds(BatchDeleteAo batchDeleteAo) { String dataType = batchDeleteAo == null ? null : batchDeleteAo.getDataType(); List dataList = batchDeleteAo == null ? null : batchDeleteAo.getDataList(); + String source = batchDeleteAo == null ? null : batchDeleteAo.getSource(); if (CollUtil.isEmpty(dataList)) { return true; } @@ -104,7 +139,9 @@ public class SdWtvtRServiceImpl extends ServiceImpl continue; } if ("TIME".equalsIgnoreCase(dataType)) { + List> beforeRows = queryWtvtRows(subList); deleteWtvtRData(subList); + recordWtvtDeleteLog(beforeRows, "删除垂向水温数据", source); Map dateRangeMap = new HashMap<>(); Map monthRangeMap = new HashMap<>(); for (DataParam param : subList) { @@ -160,7 +197,7 @@ public class SdWtvtRServiceImpl extends ServiceImpl @Override @Transactional(rollbackFor = Exception.class) - public void updateWtvtRData(Map updateData) { + public void updateWtvtRData(Map updateData, String source) { if (updateData == null || updateData.isEmpty()) { return; } @@ -171,7 +208,10 @@ public class SdWtvtRServiceImpl extends ServiceImpl return; } + Map> beforeRowMap = buildWtvtBeforeRowMap(stcd, dt); + List> dataList = new ArrayList<>(); + List logDetails = new ArrayList<>(); rawMap.forEach((wthgObj, vwtObj) -> { if (wthgObj == null) { return; @@ -192,12 +232,32 @@ public class SdWtvtRServiceImpl extends ServiceImpl // item.put("recordUser", "admin"); item.put("recordUser", SecurityUtils.getUserId()); dataList.add(item); + + String depthKey = buildWtvtDepthKey(item.get("wthg")); + Map beforeRow = beforeRowMap.get(depthKey); + Object oldValue = beforeRow == null ? null : beforeRow.get("VWT"); + Object newValue = item.get("vwt"); + if (StringUtils.equals(formatWtvtLogValue(oldValue), formatWtvtLogValue(newValue))) { + return; + } + logDetails.add(buildWtvtDetail(null, stcd, "VWT", + oldValue, resolveWtvtDisplayValue("VWT", oldValue), + newValue, resolveWtvtDisplayValue("VWT", newValue), + buildWtvtDepthRemark("修改字段值", item.get("wthg")))); }); if (dataList.isEmpty()) { return; } batchUpdateWtvtRData(dataList); + if (CollUtil.isNotEmpty(logDetails)) { + MsOperationLog mainLog = buildWtvtMainLog(null,"修改垂向水温数据", source); + msOperationLogMapper.insert(mainLog); + for (MsOperationLogDetail detail : logDetails) { + detail.setMainId(mainLog.getId()); + } + batchInsertWtvtLogDetails(logDetails); + } String dateStr = dt.substring(0, 10); statisticsDayDataFromHour(stcd, dateStr, dateStr); @@ -363,4 +423,163 @@ public class SdWtvtRServiceImpl extends ServiceImpl private String asString(Object value) { return value == null ? null : String.valueOf(value); } + + private List> queryWtvtRows(List dataParamList) { + if (CollUtil.isEmpty(dataParamList)) { + return new ArrayList<>(); + } + StringBuilder sql = new StringBuilder("SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WTHG, VWT, FID, ") + .append("RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME, RZ, HGT, REMARK, WER_ID ") + .append("FROM SD_WTVT_R WHERE "); + List params = new ArrayList<>(); + List conditions = new ArrayList<>(); + for (DataParam item : dataParamList) { + if (item == null || StringUtils.isBlank(item.getId()) || StringUtils.isBlank(item.getDt())) { + continue; + } + conditions.add("(STCD = ? AND TM = TO_DATE(SUBSTR(?, 1, 19), 'YYYY-MM-DD HH24:MI:SS'))"); + params.add(item.getId()); + params.add(item.getDt()); + } + if (conditions.isEmpty()) { + return new ArrayList<>(); + } + sql.append(String.join(" OR ", conditions)); + return normalizeWtvtRows(jdbcTemplate.queryForList(sql.toString(), params.toArray())); + } + + private Map> buildWtvtBeforeRowMap(String stcd, String dt) { + Map> result = new HashMap<>(); + if (StringUtils.isBlank(stcd) || StringUtils.isBlank(dt)) { + return result; + } + String sql = "SELECT ID, STCD, TO_CHAR(TM, 'YYYY-MM-DD HH24:MI:SS') AS TM, WTHG, VWT, FID, " + + "RECORD_USER, RECORD_TIME, MODIFY_USER, MODIFY_TIME, IS_DELETED, DELETE_USER, DELETE_TIME, RZ, HGT, REMARK, WER_ID " + + "FROM SD_WTVT_R WHERE WTHG IS NOT NULL AND VWT IS NOT NULL AND STCD = ? AND TM = TO_DATE(SUBSTR(?, 1, 19), 'YYYY-MM-DD HH24:MI:SS')"; + List> rows = normalizeWtvtRows(jdbcTemplate.queryForList(sql, stcd, dt)); + for (Map row : rows) { + + result.put(String.valueOf(Double.parseDouble(row.get("WTHG").toString())), row); + } + return result; + } + + private List> normalizeWtvtRows(List> rows) { + List> result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + Map normalized = new LinkedHashMap<>(); + for (Map.Entry entry : row.entrySet()) { + normalized.put(entry.getKey() == null ? null : entry.getKey().toUpperCase(), entry.getValue()); + } + result.add(normalized); + } + return result; + } + + private void recordWtvtDeleteLog(List> rows, String remark, String source) { + if (CollUtil.isEmpty(rows)) { + return; + } + MsOperationLog mainLog = buildWtvtMainLog(null,remark, source); + msOperationLogMapper.insert(mainLog); + List details = new ArrayList<>(); + for (Map row : rows) { + String stcd = asString(row.get("STCD")); + Object depth = row.get("WTHG"); + for (Map.Entry entry : row.entrySet()) { + String fieldCode = entry.getKey(); + Object oldValue = entry.getValue(); + if (StringUtils.isBlank(fieldCode) || oldValue == null) { + continue; + } + details.add(buildWtvtDetail(mainLog.getId(), stcd, fieldCode, + oldValue, resolveWtvtDisplayValue(fieldCode, oldValue), + null, null, buildWtvtDepthRemark("删除字段值", depth))); + } + } + batchInsertWtvtLogDetails(details); + } + + private MsOperationLog buildWtvtMainLog(String recordId,String remark, String source) { + MsOperationLog log = new MsOperationLog(); + log.setOperator(resolveWtvtLogOperator()); + log.setOperateTime(new Date()); + log.setTableName(WT_CX_TABLE_NAME); + log.setRecordId(remark); + log.setSource(StringUtils.trimToNull(source)); + log.setRemark(remark); + return log; + } + + private MsOperationLogDetail buildWtvtDetail(String mainId, + String stationCode, + String fieldCode, + Object oldValueCode, + Object oldValueName, + Object newValueCode, + Object newValueName, + String remark) { + MsOperationLogDetail detail = new MsOperationLogDetail(); + detail.setMainId(mainId); + detail.setTableName(WT_CX_TABLE_NAME); + detail.setStationCode(stationCode); + detail.setFieldCode(fieldCode); + detail.setFieldMeaning(WT_CX_FIELD_MEANING_MAP.getOrDefault(fieldCode, fieldCode)); + detail.setOldValueCode(formatWtvtLogValue(oldValueCode)); + detail.setOldValueName(formatWtvtLogValue(oldValueName)); + detail.setNewValueCode(formatWtvtLogValue(newValueCode)); + detail.setNewValueName(formatWtvtLogValue(newValueName)); + detail.setRemark(remark); + return detail; + } + + private void batchInsertWtvtLogDetails(List details) { + if (CollUtil.isEmpty(details)) { + return; + } + for (MsOperationLogDetail detail : details) { + if (detail == null) { + continue; + } + msOperationLogDetailMapper.insert(detail); + } + } + + private Object resolveWtvtDisplayValue(String fieldCode, Object rawValue) { + return formatWtvtLogValue(rawValue); + } + + private String resolveWtvtLogOperator() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception ignored) { + try { + return SecurityUtils.getUserId(); + } catch (Exception ex) { + return null; + } + } + } + + private String formatWtvtLogValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return DateUtil.formatDateTime(date); + } + return String.valueOf(value); + } + + private String buildWtvtDepthKey(Object depth) { + return formatWtvtLogValue(depth); + } + + private String buildWtvtDepthRemark(String action, Object depth) { + String depthText = formatWtvtLogValue(depth); + return depthText == null ? action : action + "(深度:" + depthText + ")"; + } } From b1b7cacef75e886c0a03e85568a3df6c2ca57c0a Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:23:47 +0800 Subject: [PATCH 13/65] =?UTF-8?q?feat:=20=E6=B0=B4=E7=94=9F=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5=E6=A6=82=E5=86=B5=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 ++ .../qgc_env/wte/entity/vo/WeStaticsVo.java | 26 ++++++ .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 82 +++++++++++++++++++ 4 files changed, 116 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index d9456491..bef8858a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -69,6 +69,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getQgcWeFishStatics(dataSourceRequest)); } + @PostMapping("/we/fisht/statics/getWeStaticsSecond") + @Operation(summary = "水生生态调查概况二级页面") + public ResponseResult getWeStaticsSecond(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeStaticsSecond(dataSourceRequest)); + } + @PostMapping("/we/fisht/stat/qgc/GetKendoListCust") @Operation(summary = "环保部-沿程鱼类变化情况柱状图") public ResponseResult getQgcWeFishStatList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeStaticsVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeStaticsVo.java index 2dd0928e..83a2e442 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeStaticsVo.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeStaticsVo.java @@ -4,11 +4,37 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; +import java.util.Date; + @Data @Accessors(chain = true) @Schema(description = "水生生态调查概况") public class WeStaticsVo { + @Schema(description = "断面编码") + private String stcd; + + @Schema(description = "断面名称") + private String stnm; + + @Schema(description = "调查批次") + private String dcpc; + + @Schema(description = "调查鱼类") + private String ftp; + + @Schema(description = "调查鱼类名称") + private String ftpName; + + @Schema(description = "鱼类数量") + private Long fcnt; + + @Schema(description = "附件ID") + private String fid; + + @Schema(description = "调查时间") + private Date tm; + @Schema(description = "调查批次数量") private Long dcpcCount; diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 9cf1c024..cbf58e14 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -35,6 +35,8 @@ public interface WeFishService { DataSourceResult getQgcWeFishStatics(DataSourceRequest dataSourceRequest); + DataSourceResult getWeStaticsSecond(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcWeFishStatList(DataSourceRequest dataSourceRequest); DataSourceResult getQgcFishListStat(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index fbaaf40c..078f1167 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -372,6 +372,58 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getWeStaticsSecond(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + String filterSql = buildWeFishQgcFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildWeStaticsSecondSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildWeFishQgcDetailSql()) + .append(") r WHERE 1 = 1 "); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + DataSourceResult result = new DataSourceResult<>(); + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + String groupedSql = buildWeFishQgcGroupSql(sql.toString(), groupInfos); + List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + sql.append(buildWeFishQgcOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql.toString(), + paramMap, + WeStaticsVo.class + ); + + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getQgcWeFishStatList(DataSourceRequest dataSourceRequest) { Map paramMap = new HashMap<>(); @@ -2084,9 +2136,11 @@ public class WeFishServiceImpl implements WeFishService { case "hbrvcdName" -> "r.hbrvcdName"; case "dcpc" -> "r.dcpc"; case "tm" -> "r.tm"; + case "year" -> "r.yr"; case "werFid" -> "r.werFid"; case "werId" -> "r.werId"; case "ftp" -> "r.ftp"; + case "ftpName" -> "r.name"; case "fsz" -> "r.fsz"; case "fcnt" -> "r.fcnt"; case "fwgh" -> "r.fwgh"; @@ -2142,6 +2196,34 @@ public class WeFishServiceImpl implements WeFishService { return " ORDER BY " + String.join(", ", orderByParts); } + private String buildWeStaticsSecondSelectSql(List selectFields) { + Map columns = new LinkedHashMap<>(); + columns.put("stcd", "r.stcd AS stcd"); + columns.put("stnm", "r.stnm AS stnm"); + columns.put("ftp", "r.ftp AS ftp"); + columns.put("ftpName", "r.name AS ftpName"); + columns.put("dcpc", "r.dcpc AS dcpc"); + columns.put("tm", "r.tm AS tm"); + columns.put("fcnt", "r.fcnt AS fcnt"); + columns.put("fid", "r.werFid AS fid"); + + List 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 Object normalizeWeFishQgcValue(String field, Object value) { if (value == null) { return null; From 435452a79c339834d16b0b05ab47756a28d9b9a2 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:27:50 +0800 Subject: [PATCH 14/65] =?UTF-8?q?feat:=20=E6=B2=BF=E7=A8=8B=E9=B1=BC?= =?UTF-8?q?=E7=B1=BB=E5=8F=98=E5=8C=96=E6=83=85=E5=86=B5=E6=9F=B1=E7=8A=B6?= =?UTF-8?q?=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 130 ++++++++++++++++++ 3 files changed, 138 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index bef8858a..4d36f326 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -81,6 +81,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getQgcWeFishStatList(dataSourceRequest)); } + @PostMapping("/we/fisht/stat/GetKendoListCust") + @Operation(summary = "沿程鱼类变化情况柱状图") + public ResponseResult getWeFishStatList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeFishStatList(dataSourceRequest)); + } + @PostMapping("/we/fishList/stat/qgc/GetKendoListCust") @Operation(summary = "环保部-水生生态调查-水生生态面板") public ResponseResult getQgcFishListStat(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index cbf58e14..c84beeba 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -39,6 +39,8 @@ public interface WeFishService { DataSourceResult getQgcWeFishStatList(DataSourceRequest dataSourceRequest); + DataSourceResult getWeFishStatList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcFishListStat(DataSourceRequest dataSourceRequest); DataSourceResult getQgcWeFishPoint(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 078f1167..e332cf1e 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -424,6 +424,21 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getWeFishStatList(DataSourceRequest dataSourceRequest) { + Map paramMap = new HashMap<>(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String baseId = getFirstWeFishFilterText(filter, "baseId"); + String hbrvcd = getFirstWeFishFilterText(filter, "hbrvcd"); + String yr = getFirstWeFishFilterText(filter, "yr"); + List rstcdList = getWeFishFilterTexts(filter, "rstcd"); + + String sql = buildWeFishStatSql(baseId, hbrvcd, yr, rstcdList, paramMap); + List> rows = microservicDynamicSQLMapper.getAllList(sql, paramMap); + return buildWeFishStatResult(rows); + } + @Override public DataSourceResult getQgcWeFishStatList(DataSourceRequest dataSourceRequest) { Map paramMap = new HashMap<>(); @@ -792,6 +807,121 @@ public class WeFishServiceImpl implements WeFishService { return sql.toString(); } + private String buildWeFishStatSql(String baseId, + String hbrvcd, + String yr, + List rstcdList, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.STCD AS stcd, t.STNM AS stnm, t.NUM AS num, t.TY AS ty, t2.SORT AS sort ") + .append("FROM (") + .append("SELECT section.RSTCD AS STCD, ") + .append("eng.ENNM AS STNM, ") + .append("COUNT(DISTINCT fish.FTP) AS NUM, ") + .append("CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END AS TY, ") + .append("TO_CHAR(we.TM, 'yyyy') AS YR ") + .append("FROM SD_WE_B_H section ") + .append("INNER JOIN SD_WE_R we ON section.STCD = we.STCD ") + .append(" AND NVL(we.IS_DELETED, 0) = 0 ") + .append(" AND NVL(we.STATUS, 1) = 1 ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = section.RSTCD ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_FISHDICTORY_B dict ON fish.FTP = dict.ID ") + .append(" AND NVL(dict.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(section.USFL, 0) = 1 "); + + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("weFishStatBaseId", baseId); + sql.append("AND section.BASE_ID = #{map.weFishStatBaseId} "); + } + if (StrUtil.isNotBlank(hbrvcd)) { + paramMap.put("weFishStatHbrvcd", hbrvcd); + sql.append("AND section.HBRVCD = #{map.weFishStatHbrvcd} "); + } + sql.append("AND section.RSTCD IS NOT NULL ") + .append("AND dict.SPEC_ORIGIN IS NOT NULL ") + .append("GROUP BY section.RSTCD, eng.ENNM, ") + .append("CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END, ") + .append("TO_CHAR(we.TM, 'yyyy') ") + .append(") t ") + .append("INNER JOIN (") + .append("SELECT det.STCD, det.SORT ") + .append("FROM MS_ALONG_B cfg ") + .append("INNER JOIN MS_ALONGDET_B det ON cfg.ID = det.ALONG_ID ") + .append("WHERE det.STTP = 'ENG' ") + .append(" AND cfg.CODE = 'common' ") + .append(" AND NVL(det.IS_DELETED, 0) = 0 ") + .append(" AND NVL(cfg.IS_DELETED, 0) = 0") + .append(") t2 ON t.STCD = t2.STCD ") + .append("WHERE t.TY IS NOT NULL "); + + if (StrUtil.isNotBlank(yr)) { + paramMap.put("weFishStatYr", yr); + sql.append("AND t.YR = #{map.weFishStatYr} "); + } + if (CollUtil.isNotEmpty(rstcdList)) { + List placeholders = new ArrayList<>(); + int index = 0; + for (String rstcd : rstcdList) { + if (StrUtil.isBlank(rstcd)) { + continue; + } + String key = "weFishStatRstcd" + index++; + paramMap.put(key, rstcd); + placeholders.add("#{map." + key + "}"); + } + if (CollUtil.isNotEmpty(placeholders)) { + sql.append("AND t.STCD IN (").append(String.join(", ", placeholders)).append(") "); + } + } + sql.append("ORDER BY t2.SORT ASC NULLS LAST"); + return sql.toString(); + } + + private DataSourceResult buildWeFishStatResult(List> rows) { + LinkedHashMap resultMap = new LinkedHashMap<>(); + for (Map row : rows) { + String stcd = safeWeFishString(firstPresentWeFishValue(row, "STCD", "stcd")); + if (StrUtil.isBlank(stcd)) { + continue; + } + WeFishStatQgcVo vo = resultMap.computeIfAbsent(stcd, key -> { + WeFishStatQgcVo item = new WeFishStatQgcVo(); + item.setStcd(key); + item.setStnm(safeWeFishString(firstPresentWeFishValue(row, "STNM", "stnm"))); + item.setSort(toWeFishIntegerValue(firstPresentWeFishValue(row, "SORT", "sort"))); + item.setTotal(0L); + item.setDetail(new LinkedHashMap<>()); + return item; + }); + Long num = toWeFishLongValue(firstPresentWeFishValue(row, "NUM", "num")); + if (num == null) { + num = 0L; + } + String ty = safeWeFishString(firstPresentWeFishValue(row, "TY", "ty")); + if (StrUtil.isNotBlank(ty)) { + vo.getDetail().put(ty, num); + } + vo.setTotal((vo.getTotal() == null ? 0L : vo.getTotal()) + num); + } + + DataSourceResult result = new DataSourceResult<>(); + result.setData(new ArrayList<>(resultMap.values())); + result.setTotal((long) resultMap.size()); + result.setAggregates(new HashMap<>()); + return result; + } + private String buildWeFishListStatQgcDetailSql() { return "SELECT " + "dict.FISH_ID AS id, " + From 6865cf73177397f2b522ccdfbce9308e51f9cfd3 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:32:38 +0800 Subject: [PATCH 15/65] =?UTF-8?q?feat:=20=E6=B2=BF=E7=A8=8B=E9=B1=BC?= =?UTF-8?q?=E7=B1=BB=E5=8F=98=E5=8C=96=E6=83=85=E5=86=B5=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/entity/vo/WeFishDetailVo.java | 36 +++++ .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 148 ++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishDetailVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 4d36f326..ee809112 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -87,6 +87,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWeFishStatList(dataSourceRequest)); } + @PostMapping("/we/fisht/detail/GetKendoListCust") + @Operation(summary = "沿程鱼类变化情况二级弹窗") + public ResponseResult getWeFishDetailList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeFishDetailList(dataSourceRequest)); + } + @PostMapping("/we/fishList/stat/qgc/GetKendoListCust") @Operation(summary = "环保部-水生生态调查-水生生态面板") public ResponseResult getQgcFishListStat(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishDetailVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishDetailVo.java new file mode 100644 index 00000000..cae4f59b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishDetailVo.java @@ -0,0 +1,36 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +@Schema(description = "沿程鱼类变化情况二级弹窗") +public class WeFishDetailVo { + + @Schema(description = "电站编码") + private String rsctd; + + @Schema(description = "电站名称") + private String rsctdName; + + @Schema(description = "鱼类列表") + private List fishList; + + @Schema(description = "断面列表") + private List stcdList; + + @Data + @Accessors(chain = true) + @Schema(description = "断面信息") + public static class StationItem { + @Schema(description = "断面编码") + private String stcd; + + @Schema(description = "断面名称") + private String stnm; + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index c84beeba..22a3f189 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -4,6 +4,7 @@ import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; @@ -41,6 +42,8 @@ public interface WeFishService { DataSourceResult getWeFishStatList(DataSourceRequest dataSourceRequest); + DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcFishListStat(DataSourceRequest dataSourceRequest); DataSourceResult getQgcWeFishPoint(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index e332cf1e..8e7cd3c9 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -12,6 +12,7 @@ import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; @@ -439,6 +440,30 @@ public class WeFishServiceImpl implements WeFishService { return buildWeFishStatResult(rows); } + @Override + public DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + Map paramMap = new HashMap<>(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String baseId = firstNonBlankWeFishFilter(filter, "baseId", "base_id"); + String rstcd = getFirstWeFishFilterText(filter, "stcd"); + String rvcd = firstNonBlankWeFishFilter(filter, "rvcd", "hbrvcd"); + String yr = getFirstWeFishFilterText(filter, "yr"); + String ty = getFirstWeFishFilterText(filter, "ty"); + + String sql = buildWeFishDetailSql(baseId, rstcd, rvcd, yr, ty, paramMap); + List> rows = microservicDynamicSQLMapper.pageAllList(page, sql, paramMap); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(buildWeFishDetailResult(rows)); + result.setTotal(page != null ? page.getTotal() : (long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getQgcWeFishStatList(DataSourceRequest dataSourceRequest) { Map paramMap = new HashMap<>(); @@ -922,6 +947,129 @@ public class WeFishServiceImpl implements WeFishService { return result; } + private String buildWeFishDetailSql(String baseId, + String rstcd, + String rvcd, + String yr, + String ty, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("section.RSTCD AS rstcd, ") + .append("eng.ENNM AS rstcdName, ") + .append("TO_CHAR(WM_CONCAT(DISTINCT section.STCD)) AS stcd, ") + .append("TO_CHAR(WM_CONCAT(DISTINCT section.STNM)) AS stnm, ") + .append("TO_CHAR(WM_CONCAT(DISTINCT dict.NAME)) AS name ") + .append("FROM SD_WE_B_H section ") + .append("INNER JOIN SD_WE_R we ON section.STCD = we.STCD ") + .append(" AND NVL(we.IS_DELETED, 0) = 0 ") + .append(" AND NVL(we.STATUS, 1) = 1 ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON section.RSTCD = eng.STCD ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_FISHDICTORY_B dict ON fish.FTP = dict.ID ") + .append(" AND NVL(dict.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(section.USFL, 0) = 1 ") + .append("AND section.RSTCD IS NOT NULL ") + .append("AND dict.NAME IS NOT NULL "); + + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("weFishDetailBaseId", baseId); + sql.append("AND section.BASE_ID = #{map.weFishDetailBaseId} "); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("weFishDetailRstcd", rstcd); + sql.append("AND section.RSTCD = #{map.weFishDetailRstcd} "); + } + if (StrUtil.isNotBlank(rvcd)) { + paramMap.put("weFishDetailRvcd", rvcd); + sql.append("AND section.HBRVCD = #{map.weFishDetailRvcd} "); + } + if (StrUtil.isNotBlank(yr)) { + paramMap.put("weFishDetailYr", yr); + sql.append("AND TO_CHAR(we.TM, 'yyyy') = #{map.weFishDetailYr} "); + } + if (StrUtil.isNotBlank(ty)) { + paramMap.put("weFishDetailTy", ty); + sql.append("AND CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END = #{map.weFishDetailTy} "); + } + + sql.append("GROUP BY section.RSTCD, eng.ENNM ") + .append("ORDER BY eng.ENNM ASC NULLS LAST"); + return sql.toString(); + } + + private List buildWeFishDetailResult(List> rows) { + List result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + for (Map row : rows) { + String stcd = safeWeFishString(firstPresentWeFishValue(row, "STCD", "stcd")); + String stnm = safeWeFishString(firstPresentWeFishValue(row, "STNM", "stnm")); + String fishNames = safeWeFishString(firstPresentWeFishValue(row, "NAME", "name")); + + WeFishDetailVo vo = new WeFishDetailVo() + .setRsctd(safeWeFishString(firstPresentWeFishValue(row, "RSTCD", "rstcd"))) + .setRsctdName(safeWeFishString(firstPresentWeFishValue(row, "RSTCDNAME", "rstcdName"))) + .setFishList(splitWeFishText(fishNames)) + .setStcdList(buildWeFishStationItems(stcd, stnm)); + result.add(vo); + } + return result; + } + + private List buildWeFishStationItems(String stcdText, String stnmText) { + List result = new ArrayList<>(); + if (StrUtil.isBlank(stcdText) || StrUtil.isBlank(stnmText)) { + return result; + } + List stcdList = splitWeFishText(stcdText); + List stnmList = splitWeFishText(stnmText); + int size = Math.min(stcdList.size(), stnmList.size()); + for (int i = 0; i < size; i++) { + result.add(new WeFishDetailVo.StationItem() + .setStcd(stcdList.get(i)) + .setStnm(stnmList.get(i))); + } + return result; + } + + private List splitWeFishText(String text) { + if (StrUtil.isBlank(text)) { + return new ArrayList<>(); + } + String[] parts = text.split(","); + List result = new ArrayList<>(); + Set seen = new HashSet<>(); + for (String part : parts) { + String value = StrUtil.trim(part); + if (StrUtil.isBlank(value) || !seen.add(value)) { + continue; + } + result.add(value); + } + return result; + } + + private String firstNonBlankWeFishFilter(DataSourceRequest.FilterDescriptor filter, String... fields) { + if (fields == null) { + return null; + } + for (String field : fields) { + String value = getFirstWeFishFilterText(filter, field); + if (StrUtil.isNotBlank(value)) { + return value; + } + } + return null; + } + private String buildWeFishListStatQgcDetailSql() { return "SELECT " + "dict.FISH_ID AS id, " + From 7e89aefe6a3f7cc8032bfd9b9ea7b45e4f3504ea Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:42:37 +0800 Subject: [PATCH 16/65] =?UTF-8?q?feat:=20=E6=B2=BF=E7=A8=8B=E9=B1=BC?= =?UTF-8?q?=E7=B1=BB=E5=8F=98=E5=8C=96=E6=83=85=E5=86=B5=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2tab=E9=A1=B5=E7=AD=BE=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 ++ .../wte/entity/vo/WeFishStatTabVo.java | 20 +++++ .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 83 +++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishStatTabVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index ee809112..961199d1 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -93,6 +93,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWeFishDetailList(dataSourceRequest)); } + @PostMapping("/we/fisht/statTab/GetKendoListCust") + @Operation(summary = "沿程鱼类变化情况二级页面tab页签数据") + public ResponseResult getWeFishStatTabList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeFishStatTabList(dataSourceRequest)); + } + @PostMapping("/we/fishList/stat/qgc/GetKendoListCust") @Operation(summary = "环保部-水生生态调查-水生生态面板") public ResponseResult getQgcFishListStat(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishStatTabVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishStatTabVo.java new file mode 100644 index 00000000..e5961f0e --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishStatTabVo.java @@ -0,0 +1,20 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +@Schema(description = "沿程鱼类变化情况二级页面tab页签数据") +public class WeFishStatTabVo { + + @Schema(description = "鱼类类型") + private String ty; + + @Schema(description = "鱼类类型名称") + private String tyName; + + @Schema(description = "鱼类数量") + private Long num; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 22a3f189..3c24883c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -8,6 +8,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatTabVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishTQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeStaticsVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeTeSpecialAnimalVo; @@ -44,6 +45,8 @@ public interface WeFishService { DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest); + DataSourceResult getWeFishStatTabList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcFishListStat(DataSourceRequest dataSourceRequest); DataSourceResult getQgcWeFishPoint(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 8e7cd3c9..c471e68c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -16,6 +16,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatTabVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishTQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeRvcdYearVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeStaticsVo; @@ -464,6 +465,35 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getWeFishStatTabList(DataSourceRequest dataSourceRequest) { + Map paramMap = new HashMap<>(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String baseId = firstNonBlankWeFishFilter(filter, "baseId", "base_id"); + String rstcd = getFirstWeFishFilterText(filter, "stcd"); + String rvcd = firstNonBlankWeFishFilter(filter, "rvcd", "hbrvcd"); + String yr = getFirstWeFishFilterText(filter, "yr"); + + String sql = buildWeFishStatTabSql(baseId, rstcd, rvcd, yr, paramMap); + List list = microservicDynamicSQLMapper.getAllListWithResultType( + sql, + paramMap, + WeFishStatTabVo.class + ); + if (CollUtil.isNotEmpty(list)) { + for (WeFishStatTabVo item : list) { + item.setTyName(resolveTyName(toWeFishIntegerValue(item.getTy()))); + } + } + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(list == null ? 0L : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getQgcWeFishStatList(DataSourceRequest dataSourceRequest) { Map paramMap = new HashMap<>(); @@ -1004,6 +1034,59 @@ public class WeFishServiceImpl implements WeFishService { return sql.toString(); } + private String buildWeFishStatTabSql(String baseId, + String rstcd, + String rvcd, + String yr, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT COUNT(DISTINCT fish.FTP) AS num, ") + .append("CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END AS ty ") + .append("FROM SD_WE_B_H section ") + .append("INNER JOIN SD_WE_R we ON section.STCD = we.STCD ") + .append(" AND NVL(we.IS_DELETED, 0) = 0 ") + .append(" AND NVL(we.STATUS, 1) = 1 ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_FISHDICTORY_B dict ON fish.FTP = dict.ID ") + .append(" AND NVL(dict.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(section.USFL, 0) = 1 "); + + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("weFishStatTabBaseId", baseId); + sql.append("AND section.BASE_ID = #{map.weFishStatTabBaseId} "); + } + if (StrUtil.isNotBlank(rvcd)) { + paramMap.put("weFishStatTabRvcd", rvcd); + sql.append("AND section.HBRVCD = #{map.weFishStatTabRvcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("weFishStatTabRstcd", rstcd); + sql.append("AND section.RSTCD = #{map.weFishStatTabRstcd} "); + } + if (StrUtil.isNotBlank(yr)) { + paramMap.put("weFishStatTabYr", yr); + sql.append("AND TO_CHAR(we.TM, 'yyyy') = #{map.weFishStatTabYr} "); + } + + sql.append("AND CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END IS NOT NULL ") + .append("GROUP BY CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END ") + .append("ORDER BY ty ASC"); + return sql.toString(); + } + private List buildWeFishDetailResult(List> rows) { List result = new ArrayList<>(); if (CollUtil.isEmpty(rows)) { From a5eb2496c691de67cb56c7c44b52dd43a802220e Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:47:59 +0800 Subject: [PATCH 17/65] =?UTF-8?q?feat:=20=E6=B2=BF=E7=A8=8B=E9=B1=BC?= =?UTF-8?q?=E7=B1=BB=E5=8F=98=E5=8C=96=E6=83=85=E5=86=B5=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E5=BC=B9=E7=AA=97-=E6=8C=89=E7=85=A7=E6=96=B0=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 107 ++++++++++++++++++ 3 files changed, 115 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 961199d1..89d05114 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -87,6 +87,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWeFishStatList(dataSourceRequest)); } + @PostMapping("/we/fisht/qgcDetail/GetKendoListCust") + @Operation(summary = "沿程鱼类变化情况二级弹窗-按照新逻辑重写") + public ResponseResult getQgcWeFishDetailList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getQgcWeFishDetailList(dataSourceRequest)); + } + @PostMapping("/we/fisht/detail/GetKendoListCust") @Operation(summary = "沿程鱼类变化情况二级弹窗") public ResponseResult getWeFishDetailList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 3c24883c..cc4a62cc 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -43,6 +43,8 @@ public interface WeFishService { DataSourceResult getWeFishStatList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcWeFishDetailList(DataSourceRequest dataSourceRequest); + DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest); DataSourceResult getWeFishStatTabList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index c471e68c..aef4ac7e 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -441,6 +441,30 @@ public class WeFishServiceImpl implements WeFishService { return buildWeFishStatResult(rows); } + @Override + public DataSourceResult getQgcWeFishDetailList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + Map paramMap = new HashMap<>(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String baseId = firstNonBlankWeFishFilter(filter, "baseId", "base_id"); + String rstcd = getFirstWeFishFilterText(filter, "stcd"); + String rvcd = firstNonBlankWeFishFilter(filter, "rvcd", "hbrvcd"); + String yr = getFirstWeFishFilterText(filter, "yr"); + String ty = getFirstWeFishFilterText(filter, "ty"); + + String sql = buildQgcWeFishDetailSql(baseId, rstcd, rvcd, yr, ty, paramMap); + List> rows = microservicDynamicSQLMapper.pageAllList(page, sql, paramMap); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(buildQgcWeFishDetailResult(rows)); + result.setTotal(page != null ? page.getTotal() : (long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -977,6 +1001,63 @@ public class WeFishServiceImpl implements WeFishService { return result; } + private String buildQgcWeFishDetailSql(String baseId, + String rstcd, + String rvcd, + String yr, + String ty, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("section.RSTCD AS rstcd, ") + .append("eng.ENNM AS rstcdName, ") + .append("TO_CHAR(WM_CONCAT(DISTINCT section.STCD)) AS stcd, ") + .append("TO_CHAR(WM_CONCAT(DISTINCT section.STNM)) AS stnm, ") + .append("TO_CHAR(WM_CONCAT(DISTINCT dict.ZY_FISH_ID)) AS id ") + .append("FROM SD_WE_B_H section ") + .append("INNER JOIN SD_WE_R we ON section.STCD = we.STCD ") + .append(" AND NVL(we.IS_DELETED, 0) = 0 ") + .append(" AND NVL(we.STATUS, 1) = 1 ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON section.RSTCD = eng.STCD ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN V_SD_FISHDICTORY_B dict ON fish.FTP = dict.FISH_ID ") + .append(" AND (section.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') ") + .append("WHERE NVL(section.USFL, 0) = 1 ") + .append("AND section.RSTCD IS NOT NULL ") + .append("AND dict.ZY_FISH_ID IS NOT NULL "); + + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("qgcWeFishDetailBaseId", baseId); + sql.append("AND section.BASE_ID = #{map.qgcWeFishDetailBaseId} "); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("qgcWeFishDetailRstcd", rstcd); + sql.append("AND section.RSTCD = #{map.qgcWeFishDetailRstcd} "); + } + if (StrUtil.isNotBlank(rvcd)) { + paramMap.put("qgcWeFishDetailRvcd", rvcd); + sql.append("AND section.HBRVCD = #{map.qgcWeFishDetailRvcd} "); + } + if (StrUtil.isNotBlank(yr)) { + paramMap.put("qgcWeFishDetailYr", yr); + sql.append("AND TO_CHAR(we.TM, 'yyyy') = #{map.qgcWeFishDetailYr} "); + } + if (StrUtil.isNotBlank(ty)) { + paramMap.put("qgcWeFishDetailTy", ty); + sql.append("AND CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END = #{map.qgcWeFishDetailTy} "); + } + + sql.append("GROUP BY section.RSTCD, eng.ENNM ") + .append("ORDER BY eng.ENNM ASC NULLS LAST"); + return sql.toString(); + } + private String buildWeFishDetailSql(String baseId, String rstcd, String rvcd, @@ -1107,6 +1188,27 @@ public class WeFishServiceImpl implements WeFishService { return result; } + private List buildQgcWeFishDetailResult(List> rows) { + List result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + Map fishNameMap = loadWeFishNameMap(); + for (Map row : rows) { + String stcd = safeWeFishString(firstPresentWeFishValue(row, "STCD", "stcd")); + String stnm = safeWeFishString(firstPresentWeFishValue(row, "STNM", "stnm")); + String fishIds = safeWeFishString(firstPresentWeFishValue(row, "ID", "id")); + + WeFishDetailVo vo = new WeFishDetailVo() + .setRsctd(safeWeFishString(firstPresentWeFishValue(row, "RSTCD", "rstcd"))) + .setRsctdName(safeWeFishString(firstPresentWeFishValue(row, "RSTCDNAME", "rstcdName"))) + .setFishList(resolveWeFishNameList(fishIds, fishNameMap)) + .setStcdList(buildWeFishStationItems(stcd, stnm)); + result.add(vo); + } + return result; + } + private List buildWeFishStationItems(String stcdText, String stnmText) { List result = new ArrayList<>(); if (StrUtil.isBlank(stcdText) || StrUtil.isBlank(stnmText)) { @@ -1140,6 +1242,11 @@ public class WeFishServiceImpl implements WeFishService { return result; } + private List resolveWeFishNameList(String idsText, Map fishNameMap) { + String names = resolveWeFishNames(idsText, fishNameMap); + return splitWeFishText(names); + } + private String firstNonBlankWeFishFilter(DataSourceRequest.FilterDescriptor filter, String... fields) { if (fields == null) { return null; From b566d7bacfe8af8d9d1f1115059549d6c2916064 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 17:52:46 +0800 Subject: [PATCH 18/65] =?UTF-8?q?feat:=20=E6=9D=A1=E4=BB=B6=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E6=95=B0=E6=8D=AE=E5=88=97=E8=A1=A8=E5=AE=9A=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 106 ++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 89d05114..1d6881fc 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -21,6 +21,12 @@ public class WeFishController { @Resource private WeFishService weFishService; + @PostMapping("/we/fisht/GetKendoListCust") + @Operation(summary = "条件过滤数据列表定制") + public ResponseResult getWeFishTKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeFishTKendoListCust(dataSourceRequest)); + } + @PostMapping("/we/fisht/qgc/GetKendoListCust") @Operation(summary = "全过程沿程鱼类变化情况") public ResponseResult getQgcWeFishTKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index cc4a62cc..9628eb31 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -21,6 +21,8 @@ import java.util.Map; public interface WeFishService { + DataSourceResult getWeFishTKendoListCust(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcWeFishTKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getQgcWeFishList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index aef4ac7e..4660e5ec 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -47,6 +47,57 @@ public class WeFishServiceImpl implements WeFishService { @Resource private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + @Override + public DataSourceResult getWeFishTKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + String filterSql = buildWeFishQgcFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT r.* FROM (") + .append(buildWeFishTDetailSql()) + .append(") r WHERE 1 = 1 "); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + DataSourceResult result = new DataSourceResult<>(); + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + String groupedSql = buildWeFishQgcGroupSql(sql.toString(), groupInfos); + List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + sql.append(buildWeFishQgcOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql.toString(), + paramMap, + WeFishTQgcVo.class + ); + fillWeFishDerivedFields(list); + + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getQgcWeFishTKendoListCust(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -2414,6 +2465,61 @@ public class WeFishServiceImpl implements WeFishService { return vo; } + private String buildWeFishTDetailSql() { + return "SELECT " + + "section.STCD AS stcd, " + + "section.STNM AS stnm, " + + "eng.BASE_ID AS baseId, " + + "eng.BASE_NAME AS baseName, " + + "eng.RVCD AS rvcd, " + + "eng.RVCD_NAME AS rvcdName, " + + "eng.ADDVCD AS addvcd, " + + "eng.ADDVCD_NAME AS addvcdName, " + + "eng.HBRVCD AS hbrvcd, " + + "eng.HBRVCD_NAME AS hbrvcdName, " + + "we.DCPC AS dcpc, " + + "we.TM AS tm, " + + "we.FID AS werFid, " + + "fish.WER_ID AS werId, " + + "fish.FTP AS ftp, " + + "fish.FSZ AS fsz, " + + "fish.FCNT AS fcnt, " + + "fish.FWGH AS fwgh, " + + "fish.ST AS st, " + + "fish.PS AS ps, " + + "fish.AVG_FWGT AS avgFwgt, " + + "fish.AVG_FSZ AS avgFsz, " + + "fish.FID AS fid, " + + "fish.FILE_ID AS fileId, " + + "dict.ID AS id, " + + "dict.NAME AS name, " + + "dict.ALIAS AS alias, " + + "dict.GENUS AS genus, " + + "dict.FAMILY AS family, " + + "dict.SPECIES AS species, " + + "dict.TYPE AS type, " + + "dict.RARE AS rare, " + + "dict.SPEC_ORIGIN AS specOrigin, " + + "dict.PTYPE AS ptype, " + + "TO_CHAR(we.TM, 'yyyy') AS yr, " + + "CASE " + + "WHEN dict.SPEC_ORIGIN = 2 THEN 1 " + + "WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN 2 " + + "WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN 3 " + + "END AS ty " + + "FROM SD_WE_R we " + + "INNER JOIN SD_WEFISH_R fish ON fish.WER_ID = we.ID " + + " AND NVL(fish.IS_DELETED, 0) = 0 " + + "INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD " + + " AND NVL(section.USFL, 0) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = section.RSTCD " + + " AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_FISHDICTORY_B dict ON dict.ID = fish.FTP " + + " AND NVL(dict.IS_DELETED, 0) = 0 " + + "WHERE NVL(we.IS_DELETED, 0) = 0 " + + "AND NVL(we.STATUS, 1) = 1 "; + } + private String buildWeFishQgcDetailSql() { return "SELECT " + "section.STCD AS stcd, " + From 4480109fb0b2e4787524b1ecd7ea75476f10766f Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 18:00:23 +0800 Subject: [PATCH 19/65] =?UTF-8?q?feat:=20=E9=87=8E=E7=94=9F=E5=8A=A8?= =?UTF-8?q?=E7=89=A9=E7=9B=91=E6=B5=8B=E9=BB=98=E8=AE=A4=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/entity/vo/WeWvaDefaultVo.java | 28 ++ .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 260 ++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWvaDefaultVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 1d6881fc..3a65a6b7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -63,6 +63,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWvaList(dataSourceRequest)); } + @PostMapping("/wva/default/GetKendoListCust") + @Operation(summary = "野生动物监测默认数据") + public ResponseResult getWvaDefaultList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWvaDefaultList(dataSourceRequest)); + } + @PostMapping("/we/fisht/year/qgc/GetKendoListCust") @Operation(summary = "全过程沿程鱼类变化情况有数据的流域和年份") public ResponseResult getQgcFishStaticsYearList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWvaDefaultVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWvaDefaultVo.java new file mode 100644 index 00000000..d683b725 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWvaDefaultVo.java @@ -0,0 +1,28 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +@Schema(description = "野生动物监测默认数据") +public class WeWvaDefaultVo { + + @Schema(description = "站点编码") + private String stcd; + + @Schema(description = "站点名称") + private String stnm; + + @Schema(description = "站类编码") + private String sttpCode; + + @Schema(description = "站类名称") + private String sttpName; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "最新时间") + private Date tm; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 9628eb31..8e642ae7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -13,6 +13,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeFishTQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeStaticsVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeTeSpecialAnimalVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeVmsstbprptVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaDefaultVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaYearQgcVo; @@ -33,6 +34,8 @@ public interface WeFishService { DataSourceResult getWvaList(DataSourceRequest dataSourceRequest); + DataSourceResult getWvaDefaultList(DataSourceRequest dataSourceRequest); + DataSourceResult getWvaDefaultYearList(DataSourceRequest dataSourceRequest); DataSourceResult>> getQgcFishStaticsYearList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 4660e5ec..f990f73f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -22,6 +22,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeRvcdYearVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeStaticsVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeTeSpecialAnimalVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeVmsstbprptVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaDefaultVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaYearQgcVo; import com.yfd.platform.qgc_env.wte.service.WeFishService; @@ -320,6 +321,64 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getWvaDefaultList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Map innerParamMap = new HashMap<>(); + Map outerParamMap = new HashMap<>(); + + String innerFilterSql = buildWeWvaDefaultInnerFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + innerParamMap, + new int[]{0} + ); + String outerFilterSql = buildWeWvaDefaultOuterFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + outerParamMap, + new int[]{0} + ); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.stcd AS stcd, t.stnm AS stnm, t.tm AS tm, t.sttpCode AS sttpCode, t.sttpName AS sttpName ") + .append("FROM (") + .append("SELECT latest.stcd AS stcd, ai.STNM AS stnm, latest.tm AS tm, ai.STTP AS sttpCode, sttp.STTP_NAME AS sttpName, ") + .append("ai.RSTCD AS rstcd, ai.BASE_ID AS baseId, ai.HBRVCD AS hbrvcd ") + .append("FROM (SELECT src.STCD AS stcd, MAX(src.TM) AS tm FROM SD_WVA_R src WHERE NVL(src.IS_DELETED, 0) = 0 "); + if (StrUtil.isNotBlank(innerFilterSql)) { + sql.append("AND ").append(innerFilterSql).append(" "); + } + sql.append("GROUP BY src.STCD) latest ") + .append("INNER JOIN SD_AIMONITOR_B_H ai ON latest.stcd = ai.STCD ") + .append("AND NVL(ai.IS_DELETED, 0) = 0 ") + .append("AND ai.STTP = 'WVA' ") + .append("LEFT JOIN SD_STTP_B sttp ON ai.STTP = sttp.STTP_CODE ") + .append("AND NVL(sttp.IS_DELETED, 0) = 0 ") + .append(") t WHERE 1 = 1 "); + if (StrUtil.isNotBlank(outerFilterSql)) { + sql.append("AND ").append(outerFilterSql).append(" "); + } + sql.append(buildWeWvaDefaultOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Map paramMap = new HashMap<>(); + paramMap.putAll(innerParamMap); + paramMap.putAll(outerParamMap); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql.toString(), + paramMap, + WeWvaDefaultVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : (long) list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getWvaList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -1748,6 +1807,207 @@ public class WeFishServiceImpl implements WeFishService { }; } + private String buildWeWvaDefaultInnerFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildWeWvaDefaultLeafCondition(filter, paramMap, indexHolder, true); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildWeWvaDefaultInnerFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildWeWvaDefaultOuterFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildWeWvaDefaultLeafCondition(filter, paramMap, indexHolder, false); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildWeWvaDefaultOuterFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildWeWvaDefaultLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + boolean inner) { + String column = inner ? mapWeWvaDefaultInnerColumn(filter.getField()) : mapWeWvaDefaultOuterColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeWeWvaValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object value : values) { + Object normalizedValue = normalizeWeWvaDefaultValue(filter.getField(), value); + if (normalizedValue == null) { + continue; + } + String key = (inner ? "weWvaDefaultInnerP" : "weWvaDefaultOuterP") + indexHolder[0]++; + paramMap.put(key, normalizedValue); + placeholders.add(buildWeWvaDefaultValueExpr(key, "tm".equals(filter.getField()), normalizedValue)); + } + if (placeholders.isEmpty()) { + return ""; + } + return column + ("ni".equals(operator) ? " NOT IN (" : " IN (") + String.join(", ", placeholders) + ")"; + } + + Object normalizedValue = normalizeWeWvaDefaultValue(filter.getField(), filter.getValue()); + if (normalizedValue == null) { + return ""; + } + String key = (inner ? "weWvaDefaultInnerP" : "weWvaDefaultOuterP") + indexHolder[0]++; + paramMap.put(key, normalizedValue); + String valueExpr = buildWeWvaDefaultValueExpr(key, "tm".equals(filter.getField()), normalizedValue); + return switch (operator) { + case "eq" -> column + " = " + valueExpr; + case "neq" -> column + " <> " + valueExpr; + case "gt" -> column + " > " + valueExpr; + case "gte" -> column + " >= " + valueExpr; + case "lt" -> column + " < " + valueExpr; + case "lte" -> column + " <= " + valueExpr; + case "contains" -> { + paramMap.put(key, "%" + String.valueOf(normalizedValue).trim() + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + String.valueOf(normalizedValue).trim() + "%"); + yield column + " NOT LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, String.valueOf(normalizedValue).trim() + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + String.valueOf(normalizedValue).trim()); + yield column + " LIKE #{map." + key + "}"; + } + default -> ""; + }; + } + + private String mapWeWvaDefaultInnerColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "src.STCD"; + case "tm" -> "src.TM"; + case "fid" -> "src.FID"; + default -> null; + }; + } + + private String mapWeWvaDefaultOuterColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "tm" -> "t.tm"; + case "sttpCode" -> "t.sttpCode"; + case "sttpName" -> "t.sttpName"; + case "rstcd" -> "t.rstcd"; + case "baseId" -> "t.baseId"; + case "hbrvcd" -> "t.hbrvcd"; + default -> null; + }; + } + + private Object normalizeWeWvaDefaultValue(String field, Object value) { + if (value == null) { + return null; + } + if ("tm".equals(field)) { + String text = String.valueOf(value).trim(); + return StrUtil.isBlank(text) ? null : text; + } + return value; + } + + private String buildWeWvaDefaultValueExpr(String paramKey, boolean dateField, Object value) { + if (!dateField || value == null) { + return "#{map." + paramKey + "}"; + } + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + + private String buildWeWvaDefaultOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return ""; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapWeWvaDefaultOuterColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return ""; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + private String buildWeMsstbprptViewSql() { return "SELECT " + "ai.STCD AS id, " + From 0295c67e41fbbdfd622d61b5fa9ef6ab218ddbe7 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 18:08:49 +0800 Subject: [PATCH 20/65] =?UTF-8?q?feat:=20=E6=B0=B4=E7=94=9F=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5=E5=AF=B9=E6=AF=94(=E6=9F=B1?= =?UTF-8?q?=E7=8A=B6=E5=9B=BE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 ++ .../entity/vo/WeCompareBarHeadColumnVo.java | 33 +++++++++ .../wte/entity/vo/WeCompareBarTableVo.java | 22 ++++++ .../qgc_env/wte/entity/vo/WeCompareBarVo.java | 29 ++++++++ .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 72 +++++++++++++++++++ 6 files changed, 165 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarHeadColumnVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarTableVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 3a65a6b7..45dc5d14 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -69,6 +69,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWvaDefaultList(dataSourceRequest)); } + @PostMapping("/we/compareBar/GetKendoListCust") + @Operation(summary = "水生生态调查对比(柱状图)") + public ResponseResult getWeCompareBarList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeCompareBarList(dataSourceRequest)); + } + @PostMapping("/we/fisht/year/qgc/GetKendoListCust") @Operation(summary = "全过程沿程鱼类变化情况有数据的流域和年份") public ResponseResult getQgcFishStaticsYearList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarHeadColumnVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarHeadColumnVo.java new file mode 100644 index 00000000..7790311d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarHeadColumnVo.java @@ -0,0 +1,33 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +@AllArgsConstructor +@Schema(description = "水生生态调查对比柱状图表头") +public class WeCompareBarHeadColumnVo { + + @Schema(description = "字段名") + private String dataIndex; + + @Schema(description = "标题") + private String title; + + @Schema(description = "是否可见") + private Boolean visible; + + @Schema(description = "键") + private String key; + + @Schema(description = "单位") + private boolean merge; + + @Schema(description = "子列") + private List children; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarTableVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarTableVo.java new file mode 100644 index 00000000..573d0f9c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarTableVo.java @@ -0,0 +1,22 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +@Schema(description = "水生生态调查对比柱状图表格") +public class WeCompareBarTableVo { + + @Schema(description = "表头") + private List columns; + + @Schema(description = "表格数据") + private Object dataSource; + + @Schema(description = "总数") + private Long total; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarVo.java new file mode 100644 index 00000000..2999824c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeCompareBarVo.java @@ -0,0 +1,29 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +@Schema(description = "水生生态调查对比柱状图数据") +public class WeCompareBarVo { + + @Schema(description = "鱼类名称") + private String ftp; + + @Schema(description = "科属") + private String genus; + + @Schema(description = "调查批次") + private String dcpc; + + @Schema(description = "对比批次") + private String dcpc2; + + @Schema(description = "鱼类数量") + private Integer fcnt; + + @Schema(description = "对比鱼类数量") + private Integer fcnt2; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 8e642ae7..0b2d6114 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -4,6 +4,7 @@ import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; @@ -38,6 +39,8 @@ public interface WeFishService { DataSourceResult getWvaDefaultYearList(DataSourceRequest dataSourceRequest); + DataSourceResult getWeCompareBarList(DataSourceRequest dataSourceRequest); + DataSourceResult>> getQgcFishStaticsYearList(DataSourceRequest dataSourceRequest); DataSourceResult getQgcWeFishStatics(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index f990f73f..2ecc469c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -10,6 +10,9 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.GroupHelper; import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarHeadColumnVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; @@ -423,6 +426,58 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getWeCompareBarList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String stcd = getFirstWeFishFilterText(filter, "stcd"); + String dcpc = getFirstWeFishFilterText(filter, "dcpc"); + String dcpc2 = getFirstWeFishFilterText(filter, "dcpc2"); + + List list = new ArrayList<>(); + long total = 0L; + if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(dcpc) && StrUtil.isNotBlank(dcpc2)) { + Map paramMap = new HashMap<>(); + paramMap.put("stcd", stcd); + paramMap.put("dcpc", dcpc); + paramMap.put("dcpc2", dcpc2); + + String sql = "SELECT dict.NAME AS ftp, " + + "MAX(NVL(dict.FAMILY, '') || NVL(dict.GENUS, '')) AS genus, " + + "#{map.dcpc} AS dcpc, " + + "#{map.dcpc2} AS dcpc2, " + + "SUM(CASE WHEN we.DCPC = #{map.dcpc} THEN NVL(fish.FCNT, 0) ELSE 0 END) AS fcnt, " + + "SUM(CASE WHEN we.DCPC = #{map.dcpc2} THEN NVL(fish.FCNT, 0) ELSE 0 END) AS fcnt2 " + + "FROM SD_WE_R we " + + "INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID AND NVL(fish.IS_DELETED, 0) = 0 " + + "INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD AND NVL(section.USFL, 0) = 1 " + + "INNER JOIN SD_FISHDICTORY_B dict ON dict.ID = fish.FTP AND NVL(dict.IS_DELETED, 0) = 0 " + + "WHERE NVL(we.IS_DELETED, 0) = 0 " + + "AND NVL(we.STATUS, 1) = 1 " + + "AND we.STCD = #{map.stcd} " + + "AND we.DCPC IN (#{map.dcpc}, #{map.dcpc2}) " + + "GROUP BY dict.NAME " + + "ORDER BY dict.NAME"; + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql, paramMap, WeCompareBarVo.class); + total = page != null ? page.getTotal() : list.size(); + } + + WeCompareBarTableVo tableVo = new WeCompareBarTableVo() + .setColumns(buildWeCompareBarColumns(dcpc, dcpc2)) + .setDataSource(list) + .setTotal(total); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(Collections.singletonList(tableVo)); + result.setTotal(total); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult>> getQgcFishStaticsYearList(DataSourceRequest dataSourceRequest) { Map paramMap = new HashMap<>(); @@ -1357,6 +1412,17 @@ public class WeFishServiceImpl implements WeFishService { return splitWeFishText(names); } + private List buildWeCompareBarColumns(String dcpc, String dcpc2) { + List columns = new ArrayList<>(); + columns.add(new WeCompareBarHeadColumnVo("ftp", "鱼种类", true, "ftp", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("genus", "科属", true, "genus", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("dcpc", StrUtil.isBlank(dcpc) ? "调查批次" : dcpc, true, "dcpc", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("dcpc2", StrUtil.isBlank(dcpc2) ? "对比批次" : dcpc2, true, "dcpc2", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("fcnt", "鱼类数量(尾)", true, "fnct", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("fcnt2", "对比鱼类数量(尾)", true, "fcnt2", false, new ArrayList<>())); + return columns; + } + private String firstNonBlankWeFishFilter(DataSourceRequest.FilterDescriptor filter, String... fields) { if (fields == null) { return null; @@ -3088,6 +3154,12 @@ public class WeFishServiceImpl implements WeFishService { return values; } + private List normalizeWeWvaValues(Object value) { + List values = new ArrayList<>(); + appendWeFishQgcValues(values, value); + return values; + } + private String buildWeFishListStatFilterCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { From 1fe6607dbf33bcb4772b570568e75ff69f702d92 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 18:59:51 +0800 Subject: [PATCH 21/65] =?UTF-8?q?feat:=20=E7=8E=AF=E4=BF=9D=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=9B=91=E6=B5=8B=E5=BC=80=E5=B1=95=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../wte/entity/vo/WeEnvmAutoMonitorVo.java | 27 + .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 620 ++++++++++++++++++ 4 files changed, 656 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeEnvmAutoMonitorVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 45dc5d14..716ffbc5 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -75,6 +75,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWeCompareBarList(dataSourceRequest)); } + @PostMapping("/base/evnmAutoMonitor/GetKendoListCust") + @Operation(summary = "环保自动监测开展情况") + public ResponseResult getEnvmAutoMonitorList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getEnvmAutoMonitorList(dataSourceRequest)); + } + @PostMapping("/we/fisht/year/qgc/GetKendoListCust") @Operation(summary = "全过程沿程鱼类变化情况有数据的流域和年份") public ResponseResult getQgcFishStaticsYearList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeEnvmAutoMonitorVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeEnvmAutoMonitorVo.java new file mode 100644 index 00000000..e84210c8 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeEnvmAutoMonitorVo.java @@ -0,0 +1,27 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "环保自动监测开展情况") +public class WeEnvmAutoMonitorVo { + + @Schema(description = "数量") + private Integer cnt; + + @Schema(description = "功能序号") + private Integer orderInx; + + @Schema(description = "功能序号名称") + private String orderInxName; + + @Schema(description = "类型路径") + private String sttpFullPath; + + @Schema(description = "站点类型") + private String sttpCode; + + @Schema(description = "站点类型名称") + private String sttpName; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 0b2d6114..45baa4e9 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -5,6 +5,7 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; @@ -41,6 +42,8 @@ public interface WeFishService { DataSourceResult getWeCompareBarList(DataSourceRequest dataSourceRequest); + DataSourceResult getEnvmAutoMonitorList(DataSourceRequest dataSourceRequest); + DataSourceResult>> getQgcFishStaticsYearList(DataSourceRequest dataSourceRequest); DataSourceResult getQgcWeFishStatics(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 2ecc469c..f316b217 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -13,6 +13,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarHeadColumnVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; @@ -478,6 +479,135 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getEnvmAutoMonitorList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String baseId = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "baseId"); + Date startTime = toDateValue(resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "startTime")); + Date endTime = toDateValue(resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "endTime")); + if (startTime == null || endTime == null) { + startTime = null; + endTime = null; + } + + List rstcds = getWeFishFilterTexts(filter, "rstcd"); + List hbrvcds = getWeFishFilterTexts(filter, "hbrvcd"); + List rvcds = getWeFishFilterTexts(filter, "rvcd"); + List showIds = getWeFishFilterTexts(filter, "showIds"); + boolean ignoreFhRstcd = shouldIgnoreWeEnvmFhRstcd(rstcds); + + List rows = new ArrayList<>(); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmWtSql(baseId, rstcds)), + 1, null, "ENV,ENVM,WT,", "水温监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmGjWqSql(baseId, hbrvcds, rvcds)), + 2, "WQ", "ENV,ENVM,WQ,", "国家水质站" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmZjWqSql(baseId, rstcds)), + 3, "WQ", "ENV,ENVM,WQ,", "水质监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmStGjSql(baseId)), + 5, null, "ST,ZQ-ST,ZZ", "国家水文站" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmStZjSql(baseId, rstcds)), + 6, null, "ST,ZQ-ST,ZZ", "水文监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmEngQecSql(baseId, rstcds)), + 7, "ENG", "ENG", "生态流量" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmVdSql(baseId, rstcds)), + 8, null, "VD,VD", "视频监控" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmRiverWqSql(baseId, rstcds)), + 9, "WQ", "ENV,ENVM,WQ,", "河道水质监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmFbWqSql(baseId, rstcds)), + 10, "WQFB", "ENV,ENVM,WQFB,", "增殖站水质站" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmFhSql(baseId, rstcds, ignoreFhRstcd)), + 11, "FH", "ENV,ENVP,FH,", "栖息地" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmFhWqSql(baseId, rstcds, ignoreFhRstcd)), + 12, "WQ", "ENV,ENVM,WQ,", "栖息地水质监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmFhWtSql(baseId, rstcds, ignoreFhRstcd)), + 13, "WTRV", "ENV,ENVM,WT,WTRV,", "栖息地水温监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmFhStSql(baseId, rstcds, ignoreFhRstcd)), + 14, null, "ST,ZQ-ST,ZZ", "水文监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmWeSql(baseId, rstcds)), + 15, "WE", "ENV,ENVM,WE,", "水生态调查断面" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmWvaSql(baseId, rstcds, hbrvcds)), + 16, "WVA", "ENV,ENVM,WVA,", "野生动物监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmVdEqsSql(baseId, rstcds)), + 17, "VD_EQS", "VD,VD_EQS,", "生态流量视频站" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmRareFishSql(baseId, rstcds, startTime, endTime)), + 18, null, "WE_FISH", "土著珍稀鱼类" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmTeAnimalsSql()), + 20, "TE_ANIMALS", "TE_ANIMALS", "重点陆生动物" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmRgWqSql(baseId, rstcds)), + 21, "WQ", "ENV,ENVM,WQ,", "人工水质监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmWeFishStaticsSql(baseId, rstcds, startTime, endTime)), + 22, "WE", "WE_FISH_ST", "调查鱼类统计" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmFpStaticsSql(baseId, rstcds)), + 23, "FP", "ENV,ENVP,FP,", "过鱼设施" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmVdYljSql(baseId, rstcds)), + 24, null, "VD,VD", "视频监控" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmAiSql(baseId, rstcds, hbrvcds)), + 25, "AI", "AI,AI_", "AI盒子" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmWtrvSql(baseId, rstcds)), + 26, null, "ENV,ENVM,WT,", "表层水温监测" + )); + rows.add(buildWeEnvmAutoMonitorVo( + queryWeEnvmAutoMonitorCount(buildWeEnvmWtvtSql(baseId, rstcds)), + 27, null, "ENV,ENVM,WT,", "垂向水温监测" + )); + + List finalRows = reorderWeEnvmAutoMonitorRows(rows, showIds); + DataSourceResult result = new DataSourceResult<>(); + result.setData(finalRows); + result.setTotal((long) finalRows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult>> getQgcFishStaticsYearList(DataSourceRequest dataSourceRequest) { Map paramMap = new HashMap<>(); @@ -3695,6 +3825,496 @@ public class WeFishServiceImpl implements WeFishService { } } + private WeEnvmAutoMonitorVo buildWeEnvmAutoMonitorVo(Integer cnt, + Integer orderInx, + String sttpCode, + String sttpFullPath, + String sttpName) { + WeEnvmAutoMonitorVo vo = new WeEnvmAutoMonitorVo(); + vo.setCnt(cnt == null ? 0 : cnt); + vo.setOrderInx(orderInx); + vo.setOrderInxName(sttpName); + vo.setSttpCode(sttpCode); + vo.setSttpFullPath(sttpFullPath); + vo.setSttpName(sttpName); + return vo; + } + + private List reorderWeEnvmAutoMonitorRows(List rows, List showIds) { + if (CollUtil.isEmpty(rows)) { + return new ArrayList<>(); + } + LinkedHashMap rowMap = new LinkedHashMap<>(); + for (WeEnvmAutoMonitorVo row : rows) { + if (row != null && row.getOrderInx() != null) { + rowMap.put(String.valueOf(row.getOrderInx()), row); + } + } + List result = new ArrayList<>(); + if (CollUtil.isNotEmpty(showIds)) { + for (String showId : showIds) { + WeEnvmAutoMonitorVo row = rowMap.get(showId); + if (row != null) { + result.add(row); + } + } + return result; + } + result.addAll(rowMap.values()); + result.sort((a, b) -> Integer.compare( + a == null || a.getOrderInx() == null ? Integer.MAX_VALUE : a.getOrderInx(), + b == null || b.getOrderInx() == null ? Integer.MAX_VALUE : b.getOrderInx() + )); + return result; + } + + private Integer queryWeEnvmAutoMonitorCount(SqlAndParams sqlAndParams) { + if (sqlAndParams == null || StrUtil.isBlank(sqlAndParams.sql())) { + return 0; + } + Map row = microservicDynamicSQLMapper.getOneBySql(sqlAndParams.sql(), sqlAndParams.params()); + return toWeFishIntegerValue(firstPresentWeFishValue(row, "CNT", "cnt")); + } + + private boolean shouldIgnoreWeEnvmFhRstcd(List rstcds) { + if (CollUtil.isEmpty(rstcds)) { + return false; + } + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(DISTINCT eng.STCD) AS cnt ") + .append("FROM SD_ENGINFO_B_H eng ") + .append("WHERE NVL(eng.IS_DELETED, 0) = 0 ") + .append("AND eng.HYCD = '10304' ") + .append("AND NVL(eng.BLDSTT_CODE, 0) IN (1, 2) "); + appendWeEnvmExactInCondition(sql, paramMap, "eng.STCD", "rstcd", rstcds); + Integer cnt = queryWeEnvmAutoMonitorCount(new SqlAndParams(sql.toString(), paramMap)); + return cnt != null && cnt == rstcds.size(); + } + + private SqlAndParams buildWeEnvmWtSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt ") + .append("FROM SD_WT_B_H wt ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wt.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wt.IS_DELETED, 0) = 0 ") + .append("AND wt.STTP IN ('WTRV', 'WTVT') ") + .append("AND NVL(wt.MWAY, 0) = 2 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wt.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmGjWqSql(String baseId, List hbrvcds, List rvcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt ") + .append("FROM SD_WQ_B_H wq ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wq.IS_DELETED, 0) = 0 ") + .append("AND wq.STTP = 'WQ' ") + .append("AND NVL(wq.MWAY, 0) = 2 ") + .append("AND NVL(wq.DTIN_TYPE, 0) = 1 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmExactInCondition(sql, paramMap, "eng.HBRVCD", "hbrvcd", hbrvcds); + appendWeEnvmExactInCondition(sql, paramMap, "eng.RVCD", "rvcd", rvcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmZjWqSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WQ_B_H wq ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wq.IS_DELETED, 0) = 0 ") + .append("AND wq.STTP IN ('WQ', 'WQFB') ") + .append("AND NVL(wq.MWAY, 0) = 2 ") + .append("AND NVL(wq.DTIN_TYPE, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wq.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmStGjSql(String baseId) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_RIVER_B_H river ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = river.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(river.IS_DELETED, 0) = 0 ") + .append("AND river.STTP IN ('ZQ', 'ZZ') ") + .append("AND NVL(river.MWAY, 0) = 2 ") + .append("AND NVL(river.DTIN_TYPE, 0) = 1 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmStZjSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_RIVER_B_H river ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = river.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(river.IS_DELETED, 0) = 0 ") + .append("AND river.STTP IN ('ZQ', 'ZZ') ") + .append("AND NVL(river.MWAY, 0) = 2 ") + .append("AND NVL(river.DTIN_TYPE, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "river.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmEngQecSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_ENGINFO_B_H eng ") + .append("WHERE NVL(eng.IS_DELETED, 0) = 0 ") + .append("AND NVL(eng.DTIN, 0) = 1 ") + .append("AND NVL(eng.BLDSTT_CODE, 0) = 2 "); + if (CollUtil.isEmpty(rstcds)) { + sql.append("AND NVL(eng.RUN_STATE, 0) = 4 "); + } else { + sql.append("AND NVL(eng.PRSC, 0) IN (1, 2, 3) ") + .append("AND NVL(eng.COENVW_STATE, 0) = 1 "); + } + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmExactInCondition(sql, paramMap, "eng.STCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmVdSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_VDINFO_B vd ") + .append("WHERE 1=1 ") + .append("AND vd.STTP LIKE 'VD%' ") + .append("AND NVL(vd.DTIN, 0) = 1 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "vd.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "vd.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmRiverWqSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WQ_B_H wq ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wq.IS_DELETED, 0) = 0 ") + .append("AND wq.STTP = 'WQ' ") + .append("AND NVL(wq.MWAY, 0) = 2 ") + .append("AND NVL(wq.DTIN_TYPE, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wq.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmFbWqSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WQ_B_H wq ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wq.IS_DELETED, 0) = 0 ") + .append("AND wq.STTP = 'WQFB' ") + .append("AND NVL(wq.MWAY, 0) = 2 ") + .append("AND NVL(wq.DTIN_TYPE, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wq.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmFhSql(String baseId, List rstcds, boolean ignoreRstcd) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_FHBT_B_H fh ") + .append("WHERE NVL(fh.IS_DELETED, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "fh.BASE_ID", baseId); + if (!ignoreRstcd) { + appendWeEnvmLikeCondition(sql, paramMap, "fh.RSTCD", "rstcd", rstcds); + } + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmFhWqSql(String baseId, List rstcds, boolean ignoreRstcd) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WQ_B_H wq ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wq.IS_DELETED, 0) = 0 ") + .append("AND wq.STTP = 'WQ' "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + if (!ignoreRstcd) { + appendWeEnvmLikeCondition(sql, paramMap, "wq.RSTCD", "rstcd", rstcds); + appendWeEnvmFhByRstcdCondition(sql, paramMap, "wq.FHSTCD", "fh_rstcd", rstcds); + } + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmFhWtSql(String baseId, List rstcds, boolean ignoreRstcd) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WT_B_H wt ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wt.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wt.IS_DELETED, 0) = 0 ") + .append("AND wt.STTP = 'WTRV' ") + .append("AND NVL(wt.DTIN_TYPE, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + if (!ignoreRstcd) { + appendWeEnvmLikeCondition(sql, paramMap, "wt.RSTCD", "rstcd", rstcds); + appendWeEnvmFhByRstcdCondition(sql, paramMap, "wt.FHSTCD", "fh_rstcd", rstcds); + } + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmFhStSql(String baseId, List rstcds, boolean ignoreRstcd) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_RIVER_B_H river ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = river.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(river.IS_DELETED, 0) = 0 ") + .append("AND river.STTP IN ('ZQ', 'ZZ') ") + .append("AND NVL(river.DTIN_TYPE, 0) = 0 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + if (!ignoreRstcd) { + appendWeEnvmLikeCondition(sql, paramMap, "river.RSTCD", "rstcd", rstcds); + appendWeEnvmFhByRstcdCondition(sql, paramMap, "river.FHSTCD", "fh_rstcd", rstcds); + } + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmWeSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WE_B_H weB ") + .append("WHERE NVL(weB.IS_DELETED, 0) = 0 ") + .append("AND EXISTS (SELECT 1 FROM SD_WE_R we ") + .append("WHERE we.STCD = weB.STCD AND NVL(we.IS_DELETED, 0) = 0 AND NVL(we.STATUS, 1) = 1) "); + appendWeEnvmBaseIdCondition(sql, paramMap, "weB.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "weB.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmWvaSql(String baseId, List rstcds, List hbrvcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_AIMONITOR_B_H ai ") + .append("WHERE NVL(ai.IS_DELETED, 0) = 0 ") + .append("AND ai.STTP = 'WVA' "); + appendWeEnvmBaseIdCondition(sql, paramMap, "ai.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "ai.RSTCD", "rstcd", rstcds); + appendWeEnvmExactInCondition(sql, paramMap, "ai.HBRVCD", "hbrvcd", hbrvcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmVdEqsSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_VDINFO_B vd ") + .append("WHERE 1=1 ") + .append("AND vd.STTP = 'VD_EQS' "); + appendWeEnvmBaseIdCondition(sql, paramMap, "vd.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "vd.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmRareFishSql(String baseId, List rstcds, Date startTime, Date endTime) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(DISTINCT fish.FTP) AS cnt ") + .append("FROM SD_WE_R we ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_FISHDICTORY_B dict ON dict.ID = fish.FTP AND NVL(dict.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H weB ON weB.STCD = we.STCD AND NVL(weB.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(we.IS_DELETED, 0) = 0 ") + .append("AND NVL(we.STATUS, 1) = 1 ") + .append("AND NVL(dict.RARE, 0) = 1 ") + .append("AND NVL(dict.SPEC_ORIGIN, 0) = 1 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "weB.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "weB.RSTCD", "rstcd", rstcds); + appendWeEnvmDateRangeCondition(sql, paramMap, "we.TM", startTime, endTime); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmTeAnimalsSql() { + String sql = "SELECT COUNT(1) AS cnt FROM (" + + "SELECT b.ID FROM MS_SPECANIMALS_B a " + + "INNER JOIN SD_VABASIC_B b ON a.ANIMAL_ID = b.ID " + + "WHERE NVL(a.IS_DELETED, 0) = 0 AND NVL(b.IS_DELETED, 0) = 0 AND NVL(b.ENABLE, 1) = 1 " + + "GROUP BY b.ID" + + ")"; + return new SqlAndParams(sql, new HashMap<>()); + } + + private SqlAndParams buildWeEnvmRgWqSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WQ_B_H wq ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wq.IS_DELETED, 0) = 0 ") + .append("AND wq.STTP = 'WQ' ") + .append("AND NVL(wq.MWAY, 0) = 1 ") + .append("AND NVL(wq.DTIN_TYPE, 0) = 2 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wq.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmWeFishStaticsSql(String baseId, List rstcds, Date startTime, Date endTime) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(DISTINCT fish.FTP) AS cnt ") + .append("FROM SD_WE_R we ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H weB ON weB.STCD = we.STCD AND NVL(weB.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(we.IS_DELETED, 0) = 0 ") + .append("AND NVL(we.STATUS, 1) = 1 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "weB.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "weB.RSTCD", "rstcd", rstcds); + appendWeEnvmDateRangeCondition(sql, paramMap, "we.TM", startTime, endTime); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmFpStaticsSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_FPSS_B_H fp ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(fp.IS_DELETED, 0) = 0 ") + .append("AND fp.LGTD IS NOT NULL "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmExactInCondition(sql, paramMap, "fp.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmVdYljSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_VDINFO_B vd ") + .append("WHERE 1=1 ") + .append("AND vd.STTP LIKE 'VD%' ") + .append("AND vd.STTP <> 'VD_FH' ") + .append("AND NVL(vd.DTIN, 0) = 1 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "vd.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "vd.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmAiSql(String baseId, List rstcds, List hbrvcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_AIMONITOR_B_H ai ") + .append("WHERE NVL(ai.IS_DELETED, 0) = 0 ") + .append("AND ai.STTP LIKE 'AI%' ") + .append("AND ai.STCD = ai.DTIN_SRC "); + appendWeEnvmBaseIdCondition(sql, paramMap, "ai.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "ai.RSTCD", "rstcd", rstcds); + appendWeEnvmExactInCondition(sql, paramMap, "ai.HBRVCD", "hbrvcd", hbrvcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmWtrvSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WT_B_H wt ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wt.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wt.IS_DELETED, 0) = 0 ") + .append("AND wt.STTP = 'WTRV' ") + .append("AND NVL(wt.MWAY, 0) = 2 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wt.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private SqlAndParams buildWeEnvmWtvtSql(String baseId, List rstcds) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT COUNT(1) AS cnt FROM SD_WT_B_H wt ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wt.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(wt.IS_DELETED, 0) = 0 ") + .append("AND wt.STTP = 'WTVT' ") + .append("AND NVL(wt.MWAY, 0) = 2 "); + appendWeEnvmBaseIdCondition(sql, paramMap, "eng.BASE_ID", baseId); + appendWeEnvmLikeCondition(sql, paramMap, "wt.RSTCD", "rstcd", rstcds); + return new SqlAndParams(sql.toString(), paramMap); + } + + private void appendWeEnvmBaseIdCondition(StringBuilder sql, Map paramMap, String column, String baseId) { + if (StrUtil.isBlank(baseId)) { + return; + } + sql.append("AND ").append(column).append(" = #{map.baseId} "); + paramMap.put("baseId", baseId); + } + + private void appendWeEnvmExactInCondition(StringBuilder sql, + Map paramMap, + String column, + String prefix, + List values) { + if (CollUtil.isEmpty(values)) { + return; + } + sql.append("AND ").append(column).append(" IN ("); + for (int i = 0; i < values.size(); i++) { + String key = prefix + i; + if (i > 0) { + sql.append(", "); + } + sql.append("#{map.").append(key).append("}"); + paramMap.put(key, values.get(i)); + } + sql.append(") "); + } + + private void appendWeEnvmLikeCondition(StringBuilder sql, + Map paramMap, + String column, + String prefix, + List values) { + if (CollUtil.isEmpty(values)) { + return; + } + sql.append("AND ("); + for (int i = 0; i < values.size(); i++) { + String key = prefix + i; + if (i > 0) { + sql.append(" OR "); + } + sql.append(column).append(" LIKE '%' || #{map.").append(key).append("} || '%'"); + paramMap.put(key, values.get(i)); + } + sql.append(") "); + } + + private void appendWeEnvmDateRangeCondition(StringBuilder sql, + Map paramMap, + String column, + Date startTime, + Date endTime) { + if (startTime == null || endTime == null) { + return; + } + sql.append("AND ").append(column).append(" BETWEEN #{map.startTime} AND #{map.endTime} "); + paramMap.put("startTime", startTime); + paramMap.put("endTime", endTime); + } + + private void appendWeEnvmFhByRstcdCondition(StringBuilder sql, + Map paramMap, + String column, + String prefix, + List rstcds) { + if (CollUtil.isEmpty(rstcds)) { + return; + } + sql.append("AND ").append(column).append(" IN (") + .append("SELECT fh.STCD FROM SD_FHBT_B_H fh ") + .append("WHERE NVL(fh.IS_DELETED, 0) = 0 "); + appendWeEnvmLikeCondition(sql, paramMap, "fh.RSTCD", prefix, rstcds); + sql.append(") "); + } + + private record SqlAndParams(String sql, Map params) { + } + private void fillWeFishDerivedFields(List list) { if (CollUtil.isEmpty(list)) { return; From 4703dfef3ac757486bc4c5971165ac31891bd0b5 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 09:37:21 +0800 Subject: [PATCH 22/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/service/impl/WeFishServiceImpl.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index f316b217..26263693 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -3002,7 +3002,7 @@ public class WeFishServiceImpl implements WeFishService { "fish.AVG_FSZ AS avgFsz, " + "fish.FID AS fid, " + "fish.FILE_ID AS fileId, " + - "dict.FISH_ID AS id, " + + "dict.ID AS id, " + "dict.NAME AS name, " + "dict.ALIAS AS alias, " + "dict.GENUS AS genus, " + @@ -3022,14 +3022,14 @@ public class WeFishServiceImpl implements WeFishService { "INNER JOIN SD_WEFISH_R fish ON fish.WER_ID = we.ID " + " AND NVL(fish.IS_DELETED, 0) = 0 " + "INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD " + - " AND NVL(section.USFL, 0) = 1 " + +// " AND NVL(section.USFL, 0) = 1 " + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = section.RSTCD " + " AND NVL(eng.IS_DELETED, 0) = 0 " + - "LEFT JOIN V_SD_FISHDICTORY_B dict ON dict.FISH_ID = fish.FTP " + - " AND (dict.RVCD = 'ZY' OR dict.RVCD = eng.HBRVCD) " + + "LEFT JOIN SD_FISHDICTORY_B dict ON dict.ID = fish.FTP " + +// " AND (dict.RVCD = 'ZY' OR dict.RVCD = eng.HBRVCD) " + "WHERE NVL(we.IS_DELETED, 0) = 0 " + // 旧库按 TASK_STATUS=Approved/null 过滤,新库改用 STATUS=1(完成) 承接审批通过口径 - "AND NVL(we.STATUS, 1) = 1 "; + "AND dict.IS_DELETED =0 "; } private String buildWeFishQgcFilterCondition(DataSourceRequest.FilterDescriptor filter, @@ -4084,7 +4084,7 @@ public class WeFishServiceImpl implements WeFishService { StringBuilder sql = new StringBuilder(); Map paramMap = new HashMap<>(); sql.append("SELECT COUNT(1) AS cnt FROM SD_WE_B_H weB ") - .append("WHERE NVL(weB.IS_DELETED, 0) = 0 ") + .append("WHERE 1=1 ") .append("AND EXISTS (SELECT 1 FROM SD_WE_R we ") .append("WHERE we.STCD = weB.STCD AND NVL(we.IS_DELETED, 0) = 0 AND NVL(we.STATUS, 1) = 1) "); appendWeEnvmBaseIdCondition(sql, paramMap, "weB.BASE_ID", baseId); @@ -4122,7 +4122,7 @@ public class WeFishServiceImpl implements WeFishService { .append("FROM SD_WE_R we ") .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID AND NVL(fish.IS_DELETED, 0) = 0 ") .append("INNER JOIN SD_FISHDICTORY_B dict ON dict.ID = fish.FTP AND NVL(dict.IS_DELETED, 0) = 0 ") - .append("INNER JOIN SD_WE_B_H weB ON weB.STCD = we.STCD AND NVL(weB.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H weB ON weB.STCD = we.STCD ") .append("WHERE NVL(we.IS_DELETED, 0) = 0 ") .append("AND NVL(we.STATUS, 1) = 1 ") .append("AND NVL(dict.RARE, 0) = 1 ") @@ -4163,7 +4163,7 @@ public class WeFishServiceImpl implements WeFishService { sql.append("SELECT COUNT(DISTINCT fish.FTP) AS cnt ") .append("FROM SD_WE_R we ") .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID AND NVL(fish.IS_DELETED, 0) = 0 ") - .append("INNER JOIN SD_WE_B_H weB ON weB.STCD = we.STCD AND NVL(weB.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H weB ON weB.STCD = we.STCD ") .append("WHERE NVL(we.IS_DELETED, 0) = 0 ") .append("AND NVL(we.STATUS, 1) = 1 "); appendWeEnvmBaseIdCondition(sql, paramMap, "weB.BASE_ID", baseId); From 16c51d5c5967246b919b6f6e1bc0d405bf16027a Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 10:03:14 +0800 Subject: [PATCH 23/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/qgc_env/wte/service/impl/WeFishServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 26263693..8d4ec677 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -1120,14 +1120,15 @@ public class WeFishServiceImpl implements WeFishService { .append("FROM SD_WE_B_H section ") .append("INNER JOIN SD_WE_R we ON section.STCD = we.STCD ") .append(" AND NVL(we.IS_DELETED, 0) = 0 ") - .append(" AND NVL(we.STATUS, 1) = 1 ") +// .append(" AND NVL(we.STATUS, 1) = 1 ") .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = section.RSTCD ") .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") .append("LEFT JOIN V_SD_FISHDICTORY_B dict ON fish.FTP = dict.FISH_ID ") .append(" AND (section.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') ") - .append("WHERE NVL(section.USFL, 0) = 1 "); + .append("WHERE 1 = 1 "); +// .append("WHERE NVL(section.USFL, 0) = 1 "); if (StrUtil.isNotBlank(baseId)) { paramMap.put("weFishStatBaseId", baseId); From e7d95c625fcdaa68f1d8642a17658de02893251e Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 10:13:46 +0800 Subject: [PATCH 24/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=99=BB=E5=BD=95=E7=A7=9F=E6=88=B7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/UserDetailsServiceImpl.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java index 6042beea..77506150 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java @@ -1,18 +1,23 @@ package com.yfd.platform.system.service.impl; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.yfd.platform.datasource.DataSource; import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.system.service.IUserService; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + import java.util.List; /** @@ -35,9 +40,19 @@ public class UserDetailsServiceImpl implements UserDetailsService { @Override @DataSource(name = "master") public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + // 获取当前请求 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); //根据用户名称或手机号查询用户信息 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.and(wrapper -> wrapper.eq("username", username).or().eq("phone", username)); + if (attributes != null) { + HttpServletRequest request = attributes.getRequest(); + String tenantId = request.getHeader("Tenant_Id"); + if(StrUtil.isNotBlank(tenantId)){ + queryWrapper.eq("TENANT_ID", tenantId); + } + } + SysUser user = userService.getOne(queryWrapper); if (ObjectUtil.isEmpty(user)) { throw new RuntimeException("用户账号不存在!"); From e6954b8baca25122f2d59737516d930ba53e6ebb Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 11:10:12 +0800 Subject: [PATCH 25/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=99=BB=E5=BD=95=E7=A7=9F=E6=88=B7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SdEngInfoBHServiceImpl.java | 8 +- .../service/impl/SdFpssBHServiceImpl.java | 10 ++- .../service/impl/SdHbrvDicServiceImpl.java | 6 +- .../service/impl/SdHydrobaseServiceImpl.java | 6 +- .../service/impl/SdRvcdDicServiceImpl.java | 6 +- .../system/service/IAdminAuthService.java | 39 +++++++++ .../platform/system/service/IUserService.java | 7 ++ .../service/impl/AdminAuthServiceImpl.java | 79 +++++++++++++++++ .../impl/SysOrganizationServiceImpl.java | 6 +- .../system/service/impl/UserServiceImpl.java | 86 +++++++++++++------ 10 files changed, 216 insertions(+), 37 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/system/service/IAdminAuthService.java create mode 100644 backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java index e860aa8b..d1250369 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java @@ -34,6 +34,7 @@ import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo; import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper; import com.yfd.platform.qgc_base.service.IMsOperationLogService; import com.yfd.platform.qgc_base.service.ISdEngInfoBHService; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.utils.QgcQueryWrapperUtil; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; @@ -81,6 +82,9 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl queryPageList(Page page, String ennm, String rvcd, String baseId, String hycd) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); @@ -93,7 +97,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl authorizedStations = getUserAuthorizedStationCodes(); if (authorizedStations != null && !authorizedStations.isEmpty()) { wrapper.in(SdEngInfoBH::getStcd, authorizedStations); - }else if (!"admin".equals(SecurityUtils.getCurrentUsername())){ + }else if (!adminAuthService.isCurrentManagedAdmin()){ return page; } return this.page(page, wrapper); @@ -135,7 +139,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl authorizedStations = getUserAuthorizedStationCodes(); diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssBHServiceImpl.java index ea8b2378..c85ffa59 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssBHServiceImpl.java @@ -10,6 +10,7 @@ import com.yfd.platform.qgc_base.domain.SdFpssBH; import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper; import com.yfd.platform.qgc_base.mapper.SdFpssBHMapper; import com.yfd.platform.qgc_base.service.ISdFpssBHService; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -29,6 +30,9 @@ public class SdFpssBHServiceImpl extends ServiceImpl i @Resource private SdEngInfoBHMapper sdEngInfoBHMapper; + @Resource + private IAdminAuthService adminAuthService; + @Override public Page selectPage(String stcd, String sttp, String rstcd, Integer usfl, Page page) { @@ -50,7 +54,7 @@ public class SdFpssBHServiceImpl extends ServiceImpl i Set authorizedStations = getUserAuthorizedStationCodes(); if (authorizedStations != null && !authorizedStations.isEmpty()) { wrapper.in(SdFpssBH::getRstcd, authorizedStations); - }else if (!"admin".equals(SecurityUtils.getCurrentUsername())){ + }else if (!adminAuthService.isCurrentManagedAdmin()){ return page; } @@ -68,7 +72,7 @@ public class SdFpssBHServiceImpl extends ServiceImpl i @Override public List selectForDropdown(String rstcd, String stnm, String baseId,String rvcd,String reachcd) { // 管理员直接查询,无需权限过滤 - if ("admin".equals(SecurityUtils.getCurrentUsername())) { + if (adminAuthService.isCurrentManagedAdmin()) { return queryFpssList(rstcd, stnm, baseId,rvcd,reachcd); } @@ -196,4 +200,4 @@ public class SdFpssBHServiceImpl extends ServiceImpl i .eq(SdFpssBH::getSttp, sttp); return getOne(wrapper); } -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java index b897970b..67dc9c00 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java @@ -15,6 +15,7 @@ import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper; import com.yfd.platform.qgc_base.mapper.SdHbrvDicMapper; import com.yfd.platform.qgc_base.mapper.SdHydrobaseMapper; import com.yfd.platform.qgc_base.service.ISdHbrvDicService; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.utils.QgcQueryWrapperUtil; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; @@ -46,6 +47,9 @@ public class SdHbrvDicServiceImpl extends ServiceImpl queryPageList(Page page, String hbrvnm, String baseid) { @@ -110,7 +114,7 @@ public class SdHbrvDicServiceImpl extends ServiceImpl authorizedStations = getUserAuthorizedStationCodes(); diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHydrobaseServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHydrobaseServiceImpl.java index 652d5d4d..9669eba8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHydrobaseServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHydrobaseServiceImpl.java @@ -13,6 +13,7 @@ import com.yfd.platform.qgc_base.entity.vo.HydrobaseWbsVo; import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper; import com.yfd.platform.qgc_base.mapper.SdHydrobaseMapper; import com.yfd.platform.qgc_base.service.ISdHydrobaseService; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -39,6 +40,9 @@ public class SdHydrobaseServiceImpl extends ServiceImpl queryPageList(Page page, String basename, String pbaseid) { return this.page(page, this.lambdaQuery() @@ -91,7 +95,7 @@ public class SdHydrobaseServiceImpl extends ServiceImpl(); } - }else if (!"admin".equals(SecurityUtils.getCurrentUsername())){ + }else if (!adminAuthService.isCurrentManagedAdmin()){ return new ArrayList<>(); } // else { diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdRvcdDicServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdRvcdDicServiceImpl.java index 60446e27..ff89fa82 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdRvcdDicServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdRvcdDicServiceImpl.java @@ -11,6 +11,7 @@ import com.yfd.platform.qgc_base.mapper.SdRvcdDicMapper; import com.yfd.platform.qgc_base.service.ISdRvcdDicService; import com.yfd.platform.qgc_data.domain.SysUserDataScope; import com.yfd.platform.qgc_data.mapper.SysUserDataScopeMapper; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -33,6 +34,9 @@ public class SdRvcdDicServiceImpl extends ServiceImpl queryPageList(Page page, String rvnm, String prvcd) { return this.page(page, this.lambdaQuery() @@ -120,7 +124,7 @@ public class SdRvcdDicServiceImpl extends ServiceImpl selectForDropdown(String rvnm, String rvcd) { List dropdownList = this.baseMapper.selectRegDropdown(rvnm, rvcd); - if("admin".equals(SecurityUtils.getCurrentUsername())){ + if(adminAuthService.isCurrentManagedAdmin()){ return dropdownList; } Set authorizedStations = getUserAuthorizedStationCodes(); diff --git a/backend/src/main/java/com/yfd/platform/system/service/IAdminAuthService.java b/backend/src/main/java/com/yfd/platform/system/service/IAdminAuthService.java new file mode 100644 index 00000000..ea25071d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/service/IAdminAuthService.java @@ -0,0 +1,39 @@ +package com.yfd.platform.system.service; + +import java.util.List; +import java.util.Set; + +/** + * 超级管理员判断服务 + */ +public interface IAdminAuthService { + + /** + * 查询超级管理员用户名列表(SYS_USER.USERTYPE = 0) + * + * @return 超级管理员用户名列表 + */ + List getSuperAdminUsernames(); + + /** + * 查询统一管理的管理员用户名集合 + * + * @return 管理员用户名集合 + */ + Set getManagedAdminUsernames(); + + /** + * 判断指定用户名是否为超级管理员 + * + * @param username 用户名 + * @return 是否为超级管理员 + */ + boolean isManagedAdminUsername(String username); + + /** + * 判断当前登录用户是否为超级管理员 + * + * @return 是否为超级管理员 + */ + boolean isCurrentManagedAdmin(); +} diff --git a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java index e5d970ac..4e9cdd62 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java @@ -103,6 +103,13 @@ public interface IUserService extends IService { ************************************/ ResponseResult resetPassword(String id) throws Exception; + /** + * 查询超级管理员用户名列表(SYS_USER.USERTYPE = 0) + * + * @return 超级管理员用户名列表 + */ + List getSuperAdminUsernames(); + /*********************************** * 用途说明:设置账号状态(管理员) * 参数说明 diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java new file mode 100644 index 00000000..046de510 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java @@ -0,0 +1,79 @@ +package com.yfd.platform.system.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysUserMapper; +import com.yfd.platform.system.service.IAdminAuthService; +import com.yfd.platform.system.service.IUserService; +import com.yfd.platform.utils.SecurityUtils; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 超级管理员判断服务实现 + */ +@Service +public class AdminAuthServiceImpl implements IAdminAuthService { + + private static final Set BUILT_IN_ADMIN_USERNAMES = + new LinkedHashSet<>(Collections.singletonList("admin")); + + @Resource + private SysUserMapper userMapper; + + @Override + public List getSuperAdminUsernames() { + + // 获取当前请求 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getUsertype, 0).select(SysUser::getUsername); + //根据用户名称或手机号查询用户信息 + if (attributes != null) { + HttpServletRequest request = attributes.getRequest(); + String tenantId = request.getHeader("Tenant_Id"); + if(StrUtil.isNotBlank(tenantId)){ + queryWrapper.eq(SysUser::getTenantId, tenantId); + } + } + List userList = userMapper.selectList(queryWrapper); + if (CollUtil.isEmpty(userList)) { + return new ArrayList<>(); + } + return userList.stream() + .map(SysUser::getUsername) + .filter(StrUtil::isNotBlank) + .distinct() + .collect(Collectors.toList()); + } + + @Override + public Set getManagedAdminUsernames() { + LinkedHashSet usernames = new LinkedHashSet<>(BUILT_IN_ADMIN_USERNAMES); + usernames.addAll(getSuperAdminUsernames()); + return usernames; + } + + @Override + public boolean isManagedAdminUsername(String username) { + return StrUtil.isNotBlank(username) && getManagedAdminUsernames().contains(username); + } + + @Override + public boolean isCurrentManagedAdmin() { + return isManagedAdminUsername(SecurityUtils.getCurrentUsername()); + } +} diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java index 6e20d9dc..dcf3e8b6 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysOrganizationServiceImpl.java @@ -11,6 +11,7 @@ import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysOrganizationMapper; import com.yfd.platform.system.mapper.SysRoleMapper; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.ISysOrganizationService; import com.yfd.platform.system.service.IUserService; import com.yfd.platform.utils.ObjectConverterUtil; @@ -38,6 +39,9 @@ public class SysOrganizationServiceImpl extends ServiceImpl> getOrgScopeTree(String roleId, String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - if(!"admin".equals(SecurityUtils.getCurrentUsername())){ + if(!adminAuthService.isCurrentManagedAdmin()){ String userId = SecurityUtils.getUserId(); List roles = sysRoleMapper.getRoleByUserId(userId); List ids = new ArrayList<>(); diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index 0e157cd4..5f11a266 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -22,6 +22,7 @@ import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysUserMapper; +import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.IUserService; import com.yfd.platform.utils.FileUtil; import com.yfd.platform.utils.PasswordGenerator; @@ -80,6 +81,9 @@ public class UserServiceImpl extends ServiceImpl impleme @Resource private SysUserDataScopeMapper sysUserDataScopeMapper; + @Resource + private IAdminAuthService adminAuthService; + /********************************** * 用途说明:获取当前用户账号及名称 * 参数说明 @@ -162,7 +166,7 @@ public class UserServiceImpl extends ServiceImpl impleme //账号有效 sysUser.setStatus(1); //判断注册的登录账号是否存在 - if (isExistAccount(sysUser.getUsername())) { + if (isExistAccount(sysUser.getUsername(),sysUser.getTenantId() )) { //新增用户 boolean ok = this.save(sysUser); //新增用户分配权限 @@ -419,7 +423,7 @@ public class UserServiceImpl extends ServiceImpl impleme //账号头像存储地址 String imgName = fileSpaceProperties.getSystem() + File.separator + "user" + File.separator + sysUser.getAvatar(); - if ("admin".equals(sysUser.getUsername())) { + if (adminAuthService.isManagedAdminUsername(sysUser.getUsername())) { return false; } else { boolean isOk = this.removeById(id); @@ -446,31 +450,30 @@ public class UserServiceImpl extends ServiceImpl impleme ************************************/ @Override public ResponseResult resetPassword(String id) throws Exception { - //根据当前用户id 查询角色表的级别 currentUser.getUser() 获取当前用户id - String level = sysUserMapper.getMaxLevel(id); - //判断是否获取级别 - if ("admin".equals(SecurityUtils.getCurrentUsername()) || StrUtil.isNotEmpty(level)) { - //判断当前用户级别 管理员及以上权限 - if ("admin".equals(SecurityUtils.getCurrentUsername()) || Integer.parseInt(level) <= 2) { - SysUser sysUser = sysUserMapper.selectById(id); - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - String password = PasswordGenerator.generateRandomPassword(sysUser.getUsername()); - //根据id 修改密码,密码修改时间,最近修改者,最近修改日期 将密码修改为 123456 - String cryptPassword = passwordEncoder.encode(password); - updateWrapper.eq("id", id).set("password", cryptPassword).set( - "pwdresettime", - new Timestamp(System.currentTimeMillis())).set( - "lastmodifydate", - new Timestamp(System.currentTimeMillis())).set( - "lastmodifier", getUsername()); - //是否修改成功 - this.update(updateWrapper); - return ResponseResult.successData(password); - } + if (hasAdminOperationPermission()) { + SysUser sysUser = sysUserMapper.selectById(id); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + String password = PasswordGenerator.generateRandomPassword(sysUser.getUsername()); + //根据id 修改密码,密码修改时间,最近修改者,最近修改日期 + String cryptPassword = passwordEncoder.encode(password); + updateWrapper.eq("id", id).set("password", cryptPassword).set( + "pwdresettime", + new Timestamp(System.currentTimeMillis())).set( + "lastmodifydate", + new Timestamp(System.currentTimeMillis())).set( + "lastmodifier", getUsername()); + //是否修改成功 + this.update(updateWrapper); + return ResponseResult.successData(password); } return ResponseResult.error(); } + @Override + public List getSuperAdminUsernames() { + return adminAuthService.getSuperAdminUsernames(); + } + /*********************************** * 用途说明:设置账号状态(管理员) * 参数说明 @@ -481,10 +484,8 @@ public class UserServiceImpl extends ServiceImpl impleme @Override public boolean setStatus(String id, String status) { boolean isOk = false; - //根据当前用户id 查询角色表的级别 currentUser.getUser() 获取当前用户id - String level = sysUserMapper.getMaxLevel(id); //判断当前用户级别 管理员及以上权限 - if ("admin".equals(SecurityUtils.getCurrentUsername()) || Integer.parseInt(level) <= 2) { + if (hasAdminOperationPermission()) { UpdateWrapper updateWrapper = new UpdateWrapper<>(); //根据id修改用户状态,最近修改人,最近修改时间 updateWrapper.eq("id", id).set("status", status).set( @@ -497,6 +498,35 @@ public class UserServiceImpl extends ServiceImpl impleme return isOk; } + private boolean hasAdminOperationPermission() { + if (adminAuthService.isCurrentManagedAdmin()) { + return true; + } + String currentUserId = SecurityUtils.getUserId(); + String level = sysUserMapper.getMaxLevel(currentUserId); + Integer roleLevel = parseRoleLevel(level); + return roleLevel != null && roleLevel <= 2; + } + + private boolean isCurrentManagedAdmin() { + return adminAuthService.isCurrentManagedAdmin(); + } + + private boolean isManagedAdminUsername(String username) { + return adminAuthService.isManagedAdminUsername(username); + } + + private Set getManagedAdminUsernames() { + return adminAuthService.getManagedAdminUsernames(); + } + + private Integer parseRoleLevel(String level) { + if (StrUtil.isBlank(level) || !StrUtil.isNumeric(level)) { + return null; + } + return Integer.parseInt(level); + } + /*********************************** * 用途说明:上传用户头像 * 参数说明 @@ -864,9 +894,9 @@ public class UserServiceImpl extends ServiceImpl impleme * account 登录名称 * 返回值说明: 重复返回 false 否则返回 true ************************************/ - private boolean isExistAccount(String username) { + private boolean isExistAccount(String username,String tenantId) { QueryWrapper queryWrapper = new QueryWrapper<>(); - if (this.list(queryWrapper.eq("username", username)).size() > 0) { + if (this.list(queryWrapper.eq("username", username).eq("TENANT_ID", tenantId)).size() > 0) { //判断 查询登录账号 结果集是否为null 重复返回 false 否则返回 tree return false; } else { From 852a5c6e91e7ca34c9d69f9275607e87518ab621 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 14:57:13 +0800 Subject: [PATCH 26/65] =?UTF-8?q?feat:=20=E6=B2=BF=E7=A8=8B=E9=B1=BC?= =?UTF-8?q?=E7=B1=BB=E5=8F=98=E5=8C=96=E6=83=85=E5=86=B5=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2tab=E9=A1=B5=E7=AD=BE=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 ++ .../wte/entity/vo/WeFishHbbQgcDetailVo.java | 29 +++++ .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 101 ++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishHbbQgcDetailVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 716ffbc5..0c424fbc 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -117,6 +117,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getQgcWeFishDetailList(dataSourceRequest)); } + @PostMapping("/we/fisht/qgcDetail/qgc/GetKendoListCust") + @Operation(summary = "环保部-沿程鱼类变化情况二级弹窗") + public ResponseResult getHbbQgcWeFishDetailList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getHbbQgcWeFishDetailList(dataSourceRequest)); + } + @PostMapping("/we/fisht/detail/GetKendoListCust") @Operation(summary = "沿程鱼类变化情况二级弹窗") public ResponseResult getWeFishDetailList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishHbbQgcDetailVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishHbbQgcDetailVo.java new file mode 100644 index 00000000..fc73c31a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishHbbQgcDetailVo.java @@ -0,0 +1,29 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +@Schema(description = "环保部-沿程鱼类变化情况二级弹窗") +public class WeFishHbbQgcDetailVo { + + @Schema(description = "电站编码") + private String rstcd; + + @Schema(description = "电站名称") + private String rstcdName; + + @Schema(description = "断面编码") + private String stcd; + + @Schema(description = "断面名称") + private String stnm; + + @Schema(description = "鱼类名称") + private String name; + + @Schema(description = "鱼类对应ID") + private String id; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 45baa4e9..305739f4 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -7,6 +7,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishHbbQgcDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; @@ -56,6 +57,8 @@ public interface WeFishService { DataSourceResult getQgcWeFishDetailList(DataSourceRequest dataSourceRequest); + DataSourceResult getHbbQgcWeFishDetailList(DataSourceRequest dataSourceRequest); + DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest); DataSourceResult getWeFishStatTabList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 8d4ec677..aeed73df 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -17,6 +17,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishHbbQgcDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; @@ -760,6 +761,30 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getHbbQgcWeFishDetailList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + Map paramMap = new HashMap<>(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String baseId = firstNonBlankWeFishFilter(filter, "baseId", "base_id"); + String rstcd = getFirstWeFishFilterText(filter, "stcd"); + String rvcd = firstNonBlankWeFishFilter(filter, "rvcd", "hbrvcd"); + String yr = getFirstWeFishFilterText(filter, "yr"); + String ty = getFirstWeFishFilterText(filter, "ty"); + + String sql = buildHbbQgcWeFishDetailSql(baseId, rstcd, rvcd, yr, ty, paramMap); + List> rows = microservicDynamicSQLMapper.pageAllList(page, sql, paramMap); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(buildHbbQgcWeFishDetailResult(rows)); + result.setTotal(page != null ? page.getTotal() : (long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getWeFishDetailList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -1411,6 +1436,63 @@ public class WeFishServiceImpl implements WeFishService { return sql.toString(); } + private String buildHbbQgcWeFishDetailSql(String baseId, + String rstcd, + String rvcd, + String yr, + String ty, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("section.RSTCD AS rstcd, ") + .append("eng.ENNM AS rstcdName, ") + .append("section.STCD AS stcd, ") + .append("section.STNM AS stnm, ") + .append("dict.ZY_FISH_ID AS id ") + .append("FROM SD_WE_B_H section ") + .append("INNER JOIN SD_WE_R we ON section.STCD = we.STCD ") + .append(" AND NVL(we.IS_DELETED, 0) = 0 ") + .append(" AND NVL(we.STATUS, 1) = 1 ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON section.RSTCD = eng.STCD ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN V_SD_FISHDICTORY_B dict ON fish.FTP = dict.FISH_ID ") + .append(" AND (section.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') ") + .append("WHERE NVL(section.USFL, 0) = 1 ") + .append("AND section.RSTCD IS NOT NULL ") + .append("AND dict.ZY_FISH_ID IS NOT NULL "); + + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("hbbQgcWeFishDetailBaseId", baseId); + sql.append("AND section.BASE_ID = #{map.hbbQgcWeFishDetailBaseId} "); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("hbbQgcWeFishDetailRstcd", rstcd); + sql.append("AND section.RSTCD = #{map.hbbQgcWeFishDetailRstcd} "); + } + if (StrUtil.isNotBlank(rvcd)) { + paramMap.put("hbbQgcWeFishDetailRvcd", rvcd); + sql.append("AND section.HBRVCD = #{map.hbbQgcWeFishDetailRvcd} "); + } + if (StrUtil.isNotBlank(yr)) { + paramMap.put("hbbQgcWeFishDetailYr", yr); + sql.append("AND TO_CHAR(we.TM, 'yyyy') = #{map.hbbQgcWeFishDetailYr} "); + } + if (StrUtil.isNotBlank(ty)) { + paramMap.put("hbbQgcWeFishDetailTy", ty); + sql.append("AND CASE ") + .append("WHEN dict.SPEC_ORIGIN = 2 THEN '1' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND NVL(dict.PTYPE, -1) <> 6 THEN '2' ") + .append("WHEN dict.SPEC_ORIGIN = 1 AND dict.PTYPE = 6 THEN '3' ") + .append("END = #{map.hbbQgcWeFishDetailTy} "); + } + + sql.append("GROUP BY section.RSTCD, eng.ENNM, section.STCD, section.STNM,dict.ZY_FISH_ID ") + .append("ORDER BY eng.ENNM ASC NULLS LAST, section.STNM ASC NULLS LAST"); + return sql.toString(); + } + private String buildWeFishStatTabSql(String baseId, String rstcd, String rvcd, @@ -1505,6 +1587,25 @@ public class WeFishServiceImpl implements WeFishService { return result; } + private List buildHbbQgcWeFishDetailResult(List> rows) { + List result = new ArrayList<>(); + if (CollUtil.isEmpty(rows)) { + return result; + } + Map fishNameMap = loadWeFishNameMap(); + for (Map row : rows) { + String fishIds = safeWeFishString(firstPresentWeFishValue(row, "ID", "id")); + result.add(new WeFishHbbQgcDetailVo() + .setRstcd(safeWeFishString(firstPresentWeFishValue(row, "RSTCD", "rstcd"))) + .setRstcdName(safeWeFishString(firstPresentWeFishValue(row, "RSTCDNAME", "rstcdName"))) + .setStcd(safeWeFishString(firstPresentWeFishValue(row, "STCD", "stcd"))) + .setStnm(safeWeFishString(firstPresentWeFishValue(row, "STNM", "stnm"))) + .setId(fishIds) + .setName(resolveWeFishNames(fishIds, fishNameMap))); + } + return result; + } + private List buildWeFishStationItems(String stcdText, String stnmText) { List result = new ArrayList<>(); if (StrUtil.isBlank(stcdText) || StrUtil.isBlank(stnmText)) { From 11f45d65e0b7c6b9a70e68b7af317d7acdbbe0a8 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 15:14:03 +0800 Subject: [PATCH 27/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/qgc_env/wte/service/impl/WeFishServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index aeed73df..d6006313 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -4304,8 +4304,8 @@ public class WeFishServiceImpl implements WeFishService { Map paramMap = new HashMap<>(); sql.append("SELECT COUNT(1) AS cnt FROM SD_AIMONITOR_B_H ai ") .append("WHERE NVL(ai.IS_DELETED, 0) = 0 ") - .append("AND ai.STTP LIKE 'AI%' ") - .append("AND ai.STCD = ai.DTIN_SRC "); + .append("AND ai.STTP LIKE 'AI%' "); +// .append("AND ai.STCD = ai.DTIN_SRC "); appendWeEnvmBaseIdCondition(sql, paramMap, "ai.BASE_ID", baseId); appendWeEnvmLikeCondition(sql, paramMap, "ai.RSTCD", "rstcd", rstcds); appendWeEnvmExactInCondition(sql, paramMap, "ai.HBRVCD", "hbrvcd", hbrvcds); From 805dab9c1069057cbfeae76a5deac9ffb703c5f0 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 15:48:31 +0800 Subject: [PATCH 28/65] =?UTF-8?q?feat:=20=E7=8E=AF=E4=BF=9D=E9=83=A8-?= =?UTF-8?q?=E6=B0=B4=E7=94=9F=E7=94=9F=E6=80=81=E8=B0=83=E6=9F=A5=E4=BA=8C?= =?UTF-8?q?=E7=BA=A7=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../wte/entity/vo/WeFishPageQgcVo.java | 37 ++++ .../wte/entity/vo/WeFishPageTableVo.java | 22 +++ .../qgc_env/wte/service/WeFishService.java | 3 + .../wte/service/impl/WeFishServiceImpl.java | 175 ++++++++++++++++++ 5 files changed, 243 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageQgcVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageTableVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 0c424fbc..b9a881bb 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -75,6 +75,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getWeCompareBarList(dataSourceRequest)); } + @PostMapping("/we/fishPage/qgc/GetKendoListCust") + @Operation(summary = "环保部-水生生态调查二级页面") + public ResponseResult getQgcWeFishPageList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getQgcWeFishPageList(dataSourceRequest)); + } + @PostMapping("/base/evnmAutoMonitor/GetKendoListCust") @Operation(summary = "环保自动监测开展情况") public ResponseResult getEnvmAutoMonitorList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageQgcVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageQgcVo.java new file mode 100644 index 00000000..ad5c68b0 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageQgcVo.java @@ -0,0 +1,37 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +@Schema(description = "环保部-水生生态调查二级页面数据") +public class WeFishPageQgcVo { + + @Schema(description = "鱼类名称") + private String ftp; + + @Schema(description = "科属") + private String genus; + + @Schema(description = "开始年份鱼类总量") + private Integer startFtpCnt; + + @Schema(description = "开始年份总量") + private Integer startCnt; + + @Schema(description = "开始年份占比") + private BigDecimal startYear; + + @Schema(description = "结束年份鱼类总量") + private Integer endFtpCnt; + + @Schema(description = "结束年份总量") + private Integer endCnt; + + @Schema(description = "结束年份占比") + private BigDecimal endYear; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageTableVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageTableVo.java new file mode 100644 index 00000000..99298e48 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFishPageTableVo.java @@ -0,0 +1,22 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +@Schema(description = "环保部-水生生态调查二级页面表格") +public class WeFishPageTableVo { + + @Schema(description = "表头") + private List columns; + + @Schema(description = "表格数据") + private Object dataSource; + + @Schema(description = "总数") + private Long total; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 305739f4..fe6da23e 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -9,6 +9,7 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishHbbQgcDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPageTableVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatTabVo; @@ -43,6 +44,8 @@ public interface WeFishService { DataSourceResult getWeCompareBarList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcWeFishPageList(DataSourceRequest dataSourceRequest); + DataSourceResult getEnvmAutoMonitorList(DataSourceRequest dataSourceRequest); DataSourceResult>> getQgcFishStaticsYearList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index d6006313..d6fa20be 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -18,6 +18,8 @@ import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishHbbQgcDetailVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPageQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPageTableVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; @@ -480,6 +482,136 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getQgcWeFishPageList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + DataSourceRequest.FilterDescriptor filter = dataSourceRequest == null ? null : dataSourceRequest.getFilter(); + + String startYear = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "startYear"); + String endYear = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "endYear"); + if (StrUtil.isBlank(startYear)) { + throw new IllegalArgumentException("开始年份不能为空!"); + } + if (StrUtil.isBlank(endYear)) { + throw new IllegalArgumentException("结束年份(endYear)不能为空!"); + } + + String baseId = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "baseId"); + String hbrvcd = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "hbrvcd"); + String rstcd = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "rstcd"); + String ftp = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "ftp"); + + Map paramMap = new HashMap<>(); + paramMap.put("startYear", startYear); + paramMap.put("endYear", endYear); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ftp, genus, startFtpCnt, startCnt, startYear, endFtpCnt, endCnt, endYear ") + .append("FROM (") + .append("SELECT dict.NAME AS ftp, ") + .append("CONCAT(CONCAT(dict.FAMILY,'-'),dict.GENUS) as genus, ") + .append("agg.startYear AS startYear, agg.endYear AS endYear, ") + .append("agg.startCnt AS startCnt, agg.startFtpCnt AS startFtpCnt, ") + .append("agg.endCnt AS endCnt, agg.endFtpCnt AS endFtpCnt ") + .append("FROM (") + .append("SELECT ftp, hbrvcd, ") + .append("ROUND(MAX(startYear), 2) AS startYear, ") + .append("ROUND(MAX(endYear), 2) AS endYear, ") + .append("MAX(startCnt) AS startCnt, ") + .append("MAX(startFtpCnt) AS startFtpCnt, ") + .append("MAX(endCnt) AS endCnt, ") + .append("MAX(endFtpCnt) AS endFtpCnt ") + .append("FROM (") + .append("SELECT fishAgg.ftp AS ftp, fishAgg.hbrvcd AS hbrvcd, fishAgg.fcnt AS fcnt, ") + .append("CASE WHEN fishAgg.yr = #{map.startYear} ") + .append("THEN CASE WHEN NVL(totalAgg.fcnt, 0) = 0 THEN 0 ELSE 100 * fishAgg.fcnt / totalAgg.fcnt END END AS startYear, ") + .append("CASE WHEN fishAgg.yr = #{map.endYear} ") + .append("THEN CASE WHEN NVL(totalAgg.fcnt, 0) = 0 THEN 0 ELSE 100 * fishAgg.fcnt / totalAgg.fcnt END END AS endYear, ") + .append("CASE WHEN fishAgg.yr = #{map.startYear} THEN fishAgg.fcnt END AS startFtpCnt, ") + .append("CASE WHEN fishAgg.yr = #{map.startYear} THEN totalAgg.fcnt END AS startCnt, ") + .append("CASE WHEN fishAgg.yr = #{map.endYear} THEN fishAgg.fcnt END AS endFtpCnt, ") + .append("CASE WHEN fishAgg.yr = #{map.endYear} THEN totalAgg.fcnt END AS endCnt ") + .append("FROM (") + .append("SELECT fish.FTP AS ftp, section.HBRVCD AS hbrvcd, SUM(NVL(fish.FCNT, 0)) AS fcnt, TO_CHAR(we.TM, 'YYYY') AS yr ") + .append("FROM SD_WE_R we ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD ") + .append("INNER JOIN V_SD_FISHDICTORY_B dictFilter ON dictFilter.FISH_ID = fish.FTP ") + .append(" AND (section.HBRVCD = dictFilter.RVCD OR dictFilter.RVCD = 'ZY') ") + .append("WHERE NVL(we.STATUS, 1) = 1 ") + .append("AND NVL(we.IS_DELETED, 0) = 0 ") + .append("AND TO_CHAR(we.TM, 'YYYY') IN (#{map.startYear}, #{map.endYear}) "); + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("fishPageBaseId", baseId); + sql.append("AND section.BASE_ID = #{map.fishPageBaseId} "); + } + if (StrUtil.isNotBlank(hbrvcd)) { + paramMap.put("fishPageHbrvcd", hbrvcd); + sql.append("AND section.HBRVCD = #{map.fishPageHbrvcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("fishPageRstcd", rstcd); + sql.append("AND section.RSTCD = #{map.fishPageRstcd} "); + } + sql.append("GROUP BY fish.FTP, section.HBRVCD, TO_CHAR(we.TM, 'YYYY') ") + .append(") fishAgg ") + .append("LEFT JOIN (") + .append("SELECT SUM(NVL(fish.FCNT, 0)) AS fcnt, TO_CHAR(we.TM, 'YYYY') AS yr ") + .append("FROM SD_WE_R we ") + .append("INNER JOIN SD_WEFISH_R fish ON we.ID = fish.WER_ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD ") + .append("INNER JOIN V_SD_FISHDICTORY_B dictFilter ON dictFilter.FISH_ID = fish.FTP ") + .append(" AND (section.HBRVCD = dictFilter.RVCD OR dictFilter.RVCD = 'ZY') ") + .append("WHERE NVL(we.STATUS, 1) = 1 ") + .append("AND NVL(we.IS_DELETED, 0) = 0 ") + .append("AND TO_CHAR(we.TM, 'YYYY') IN (#{map.startYear}, #{map.endYear}) "); + if (StrUtil.isNotBlank(baseId)) { + sql.append("AND section.BASE_ID = #{map.fishPageBaseId} "); + } + if (StrUtil.isNotBlank(hbrvcd)) { + sql.append("AND section.HBRVCD = #{map.fishPageHbrvcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + sql.append("AND section.RSTCD = #{map.fishPageRstcd} "); + } + sql.append("GROUP BY TO_CHAR(we.TM, 'YYYY') ") + .append(") totalAgg ON totalAgg.yr = fishAgg.yr ") + .append(") temp ") + .append("GROUP BY ftp, hbrvcd ") + .append(") agg ") + .append("INNER JOIN V_SD_FISHDICTORY_B dict ON dict.FISH_ID = agg.ftp ") + .append(" AND (agg.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY')") + .append(") r WHERE 1 = 1 "); + if (StrUtil.isNotBlank(ftp)) { + paramMap.put("fishPageFtp", "%" + ftp.trim() + "%"); + sql.append("AND r.ftp LIKE #{map.fishPageFtp} "); + } + sql.append(buildWeFishPageOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql.toString(), + paramMap, + WeFishPageQgcVo.class + ); + long total = page != null ? page.getTotal() : list.size(); + + WeFishPageTableVo tableVo = new WeFishPageTableVo() + .setColumns(buildWeFishPageColumns(startYear, endYear)) + .setDataSource(list) + .setTotal(total); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(Collections.singletonList(tableVo)); + result.setTotal(total); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getEnvmAutoMonitorList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -1655,6 +1787,17 @@ public class WeFishServiceImpl implements WeFishService { return columns; } + private List buildWeFishPageColumns(String startYear, String endYear) { + List columns = new ArrayList<>(); + columns.add(new WeCompareBarHeadColumnVo("genus", "科属", true, "genus", true, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("ftp", "鱼类名称", true, "ftp", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("startFtpCnt", startYear + "鱼类总量(尾)", true, "startFtpCnt", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("startYear", startYear + "占比(%)", true, "startYear", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("endFtpCnt", endYear + "鱼类总量(尾)", true, "endFtpCnt", false, new ArrayList<>())); + columns.add(new WeCompareBarHeadColumnVo("endYear", endYear + "占比(%)", true, "endYear", false, new ArrayList<>())); + return columns; + } + private String firstNonBlankWeFishFilter(DataSourceRequest.FilterDescriptor filter, String... fields) { if (fields == null) { return null; @@ -3328,6 +3471,38 @@ public class WeFishServiceImpl implements WeFishService { return " ORDER BY " + String.join(", ", orderByParts); } + private String buildWeFishPageOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY r.ftp ASC"; + } + Map columnMap = new LinkedHashMap<>(); + columnMap.put("ftp", "r.ftp"); + columnMap.put("genus", "r.genus"); + columnMap.put("startFtpCnt", "r.startFtpCnt"); + columnMap.put("startCnt", "r.startCnt"); + columnMap.put("startYear", "r.startYear"); + columnMap.put("endFtpCnt", "r.endFtpCnt"); + columnMap.put("endCnt", "r.endCnt"); + columnMap.put("endYear", "r.endYear"); + + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = columnMap.get(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return " ORDER BY r.ftp ASC"; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + private String buildWeStaticsSecondSelectSql(List selectFields) { Map columns = new LinkedHashMap<>(); columns.put("stcd", "r.stcd AS stcd"); From dd0ce6a7d9bf622c6e89a0430301365c903cb2df Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 16:34:04 +0800 Subject: [PATCH 29/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=94=B5?= =?UTF-8?q?=E7=AB=99=E6=9F=A5=E8=AF=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_base/service/impl/SdEngInfoBHServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java index d1250369..520e3752 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java @@ -1089,6 +1089,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl "t.id"; case "sttp" -> "t.sttp"; case "sttpCode" -> "t.sttpCode"; + case "runState" -> "t.runState"; case "sttpName" -> "t.sttpName"; case "stcd" -> "t.stcd"; case "stnm", "ennm" -> "t.stnm"; @@ -1900,6 +1903,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl "t.hbrvcd"; case "hbrvcdName" -> "t.hbrvcdName"; case "rvcd" -> "t.rvcd"; + case "prsc" -> "t.prsc"; case "rvcdName" -> "t.rvcdName"; case "addvcdName" -> "t.addvcdName"; case "hynm" -> "t.hynm"; From a37c7248abc57dcc6ccd3ed43ed581a7cc6c5471 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 30 Jun 2026 17:38:10 +0800 Subject: [PATCH 30/65] =?UTF-8?q?feat:=20=E9=9D=99=E6=80=81=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E5=92=8C=E5=8A=A8=E6=80=81=E5=AD=97=E5=85=B8=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E4=B8=AD=E6=96=87=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SdHbrvDicServiceImpl.java | 31 ++ .../platform/utils/CodeToNameMetadataBo.java | 94 +++++ .../utils/DictCodeToNameConverter.java | 350 ++++++++++++++++++ 3 files changed, 475 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/utils/CodeToNameMetadataBo.java create mode 100644 backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java index 67dc9c00..5d58e2fe 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdHbrvDicServiceImpl.java @@ -16,6 +16,8 @@ import com.yfd.platform.qgc_base.mapper.SdHbrvDicMapper; import com.yfd.platform.qgc_base.mapper.SdHydrobaseMapper; import com.yfd.platform.qgc_base.service.ISdHbrvDicService; import com.yfd.platform.system.service.IAdminAuthService; +import com.yfd.platform.utils.CodeToNameMetadataBo; +import com.yfd.platform.utils.DictCodeToNameConverter; import com.yfd.platform.utils.QgcQueryWrapperUtil; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; @@ -51,6 +53,35 @@ public class SdHbrvDicServiceImpl extends ServiceImpl + * 每个模块的 ServiceImpl 中可按需定义自己的 codeToNameMetadataBoList, + * 在查询方法返回前调用 dictCodeToNameConverter.convertCodeToName(voList, codeToNameMetadataBoList) + * 即可自动将 code 字段转为对应的 name 字段。 + *

+ * + *
+     * 使用示例:
+     * // 在查询方法末尾调用:
+     * dictCodeToNameConverter.convertCodeToName(voList, CODE_TO_NAME_META_LIST);
+     * 
+ */ + private static final List CODE_TO_NAME_META_LIST = new ArrayList<>(); + +// static { +// +// CODE_TO_NAME_META_LIST.add(CodeToNameMetadataBo.builder().codeProperty("grd").modifyProperty("grdName").dictType("STATIC").dictSource("TEST").build()); +// CODE_TO_NAME_META_LIST.add(CodeToNameMetadataBo.builder().codeProperty("baseid").modifyProperty("basename").dictType("DYNAMIC").dictSource("SD_HYDROBASE").codeColumn("BASEID").nameColumn("BASENAME").filter("NVL(IS_DELETED, 0) = 0 ").build()); +// } + + @Override public Page queryPageList(Page page, String hbrvnm, String baseid) { return this.page(page, this.lambdaQuery() diff --git a/backend/src/main/java/com/yfd/platform/utils/CodeToNameMetadataBo.java b/backend/src/main/java/com/yfd/platform/utils/CodeToNameMetadataBo.java new file mode 100644 index 00000000..5f8ba742 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/CodeToNameMetadataBo.java @@ -0,0 +1,94 @@ +package com.yfd.platform.utils; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 代码转名称元数据配置 + *

+ * 用于配置 VO 中某个 code 字段如何转换为对应的 name 字段, + * 支持静态字典(SYS_DICTIONARY / SYS_DICTIONARY_ITEMS)和动态字典(业务表)。 + *

+ * + *
+ * 使用示例:
+ * // 静态字典:将 vo.typeCode 转为 vo.typeName,字典编码为 "PROJECT_TYPE"
+ * CodeToNameMetadataBo.builder()
+ *     .codeProperty("typeCode")
+ *     .modifyProperty("typeName")
+ *     .dictType("STATIC")
+ *     .dictSource("PROJECT_TYPE")
+ *     .build();
+ *
+ * // 动态字典:将 vo.engCode 转为 vo.engName,查 SD_ENGINFO_B_H 表
+ * CodeToNameMetadataBo.builder()
+ *     .codeProperty("engCode")
+ *     .modifyProperty("engName")
+ *     .dictType("DYNAMIC")
+ *     .dictSource("SD_ENGINFO_B_H")
+ *     .codeColumn("STCD")
+ *     .nameColumn("ENNM")
+ *     .filter("NVL(IS_DELETED, 0) = 0")
+ *     .build();
+ * 
+ * + * @author Generated + * @since 2025-05-18 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CodeToNameMetadataBo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编码属性名(VO 中存放 code 的字段名) + */ + private String codeProperty; + + /** + * 名称属性名(VO 中需要设置 name 的字段名) + */ + private String modifyProperty; + + /** + * 字典类型:STATIC(静态字典)或 DYNAMIC(动态字典) + */ + private String dictType; + + /** + * 字典来源: + * - 静态字典:SYS_DICTIONARY 表中的 DICTCODE + * - 动态字典:业务表名 + */ + private String dictSource; + + /** + * 动态字典:表中编码列名(静态字典不需要) + */ + private String codeColumn; + + /** + * 动态字典:表中名称列名(静态字典不需要) + */ + private String nameColumn; + + /** + * 额外过滤条件(可选) + * - 静态字典:SYS_DICTIONARY_ITEMS 的额外 WHERE 条件 + * - 动态字典:业务表的额外 WHERE 条件 + */ + private String filter; + + /** + * 是否多选(code 值为逗号分隔的多个编码) + */ + @Builder.Default + private boolean isMulti = false; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java b/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java new file mode 100644 index 00000000..a7db357d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java @@ -0,0 +1,350 @@ +package com.yfd.platform.utils; + +import cn.hutool.core.util.StrUtil; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.system.domain.SysDictionary; +import com.yfd.platform.system.domain.SysDictionaryItems; +import com.yfd.platform.system.mapper.SysDictionaryItemsMapper; +import com.yfd.platform.system.mapper.SysDictionaryMapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * 字典代码转名称转换器 + *

+ * 支持静态字典(SYS_DICTIONARY / SYS_DICTIONARY_ITEMS)和动态字典(业务表查询), + * 将 VO 中的 code 字段值转换为对应的 name 字段值。 + *

+ * + *

使用方式

+ *
+ * // 1. 在 ServiceImpl 中注入
+ * @Resource
+ * private DictCodeToNameConverter dictCodeToNameConverter;
+ *
+ * // 2. 定义元数据列表(通常放在 static 静态代码块中)
+ * private static final List<CodeToNameMetadataBo> CODE_TO_NAME_META_LIST = List.of(
+ *     CodeToNameMetadataBo.builder()
+ *         .codeProperty("stationType")
+ *         .modifyProperty("stationTypeName")
+ *         .dictType("STATIC")
+ *         .dictSource("STATION_TYPE")
+ *         .build(),
+ *     CodeToNameMetadataBo.builder()
+ *         .codeProperty("engCode")
+ *         .modifyProperty("engName")
+ *         .dictType("DYNAMIC")
+ *         .dictSource("SD_ENGINFO_B_H")
+ *         .codeColumn("STCD")
+ *         .nameColumn("ENNM")
+ *         .filter("NVL(IS_DELETED, 0) = 0")
+ *         .build()
+ * );
+ *
+ * // 3. 在查询方法中调用转换
+ * public DataSourceResult<MyVo> queryList(DataSourceRequest request) {
+ *     // ... 查询数据得到 voList ...
+ *     dictCodeToNameConverter.convertCodeToName(voList, CODE_TO_NAME_META_LIST);
+ *     // ... 返回结果 ...
+ * }
+ * 
+ * + * @author Generated + * @since 2025-05-18 + */ +@Slf4j +@Component +public class DictCodeToNameConverter { + + @Resource + private SysDictionaryMapper sysDictionaryMapper; + + @Resource + private SysDictionaryItemsMapper sysDictionaryItemsMapper; + + @Resource + private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + + /** + * 静态字典缓存:dictCode -> Map + */ + private final Map> staticDictCache = new ConcurrentHashMap<>(); + + /** + * 动态字典缓存:缓存key -> Map + */ + private final Map> dynamicDictCache = new ConcurrentHashMap<>(); + + /** + * 批量转换:根据元数据配置,将 VO 列表中的 code 字段转换为对应的 name 字段 + * + * @param voList VO 对象列表 + * @param metadataList 元数据配置列表 + * @param VO 类型 + */ + public void convertCodeToName(List voList, List metadataList) { + if (voList == null || voList.isEmpty() || metadataList == null || metadataList.isEmpty()) { + return; + } + + for (CodeToNameMetadataBo metadata : metadataList) { + try { + Map codeNameMap = loadCodeNameMap(metadata); + if (codeNameMap.isEmpty()) { + continue; + } + applyCodeToName(voList, metadata, codeNameMap); + } catch (Exception e) { + log.error("字典转换失败: codeProperty={}, dictSource={}", metadata.getCodeProperty(), metadata.getDictSource(), e); + } + } + } + + /** + * 加载静态字典映射 + * + * @param dictCode 字典编码 + * @return Map + */ + public Map loadStaticDictMap(String dictCode) { + return staticDictCache.computeIfAbsent(dictCode, key -> { + Map map = new LinkedHashMap<>(); + try { + SysDictionary dict = sysDictionaryMapper.selectOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(SysDictionary::getDictCode, key) + ); + if (dict == null) { + log.warn("静态字典未找到: dictCode={}", key); + return map; + } + List items = sysDictionaryItemsMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(SysDictionaryItems::getDictId, dict.getId()) + .orderByAsc(SysDictionaryItems::getOrderNo) + ); + for (SysDictionaryItems item : items) { + if (StrUtil.isNotBlank(item.getItemCode())) { + map.put(item.getItemCode(), StrUtil.nullToDefault(item.getDictName(), item.getItemCode())); + } + } + } catch (Exception e) { + log.error("加载静态字典失败: dictCode={}", key, e); + } + return map; + }); + } + + /** + * 加载动态字典映射(从业务表查询) + * + * @param tableName 表名 + * @param codeColumn 编码列名 + * @param nameColumn 名称列名 + * @param filter 额外过滤条件 + * @return Map + */ + public Map loadDynamicDictMap(String tableName, String codeColumn, String nameColumn, String filter) { + String cacheKey = tableName + "|" + codeColumn + "|" + nameColumn + "|" + StrUtil.nullToDefault(filter, ""); + return dynamicDictCache.computeIfAbsent(cacheKey, key -> { + Map map = new LinkedHashMap<>(); + try { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ").append(codeColumn).append(" AS code, ") + .append(nameColumn).append(" AS name ") + .append("FROM ").append(tableName) + .append(" WHERE 1=1 "); + if (StrUtil.isNotBlank(filter)) { + sql.append("AND ").append(filter).append(" "); + } + Map params = new HashMap<>(); + List> rows = microservicDynamicSQLMapper.getAllList(sql.toString(), params); + for (Map row : rows) { + String code = Objects.toString(row.get("CODE"), null); + String name = Objects.toString(row.get("NAME"), null); + if (StrUtil.isNotBlank(code)) { + map.put(code, StrUtil.nullToDefault(name, code)); + } + } + } catch (Exception e) { + log.error("加载动态字典失败: tableName={}", tableName, e); + } + return map; + }); + } + + /** + * 根据元数据加载 code->name 映射 + */ + private Map loadCodeNameMap(CodeToNameMetadataBo metadata) { + if ("STATIC".equalsIgnoreCase(metadata.getDictType())) { + return loadStaticDictMap(metadata.getDictSource()); + } else if ("DYNAMIC".equalsIgnoreCase(metadata.getDictType())) { + return loadDynamicDictMap( + metadata.getDictSource(), + metadata.getCodeColumn(), + metadata.getNameColumn(), + metadata.getFilter() + ); + } + log.warn("未知字典类型: dictType={}", metadata.getDictType()); + return Collections.emptyMap(); + } + + /** + * 将 code->name 映射应用到 VO 列表 + */ + private void applyCodeToName(List voList, CodeToNameMetadataBo metadata, Map codeNameMap) { + for (T vo : voList) { + try { + String codeValue = getFieldValue(vo, metadata.getCodeProperty()); + if (StrUtil.isBlank(codeValue)) { + continue; + } + + String nameValue; + if (metadata.isMulti()) { + // 多选:逗号分隔的多个code + nameValue = Arrays.stream(codeValue.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .map(c -> codeNameMap.getOrDefault(c, c)) + .collect(Collectors.joining(",")); + } else { + nameValue = codeNameMap.getOrDefault(codeValue.trim(), codeValue); + } + setFieldValue(vo, metadata.getModifyProperty(), nameValue); + } catch (Exception e) { + log.debug("字段转换跳过: vo={}, codeProperty={}", vo.getClass().getSimpleName(), metadata.getCodeProperty(), e); + } + } + } + + /** + * 清除所有缓存 + */ + public void clearCache() { + staticDictCache.clear(); + dynamicDictCache.clear(); + } + + /** + * 清除指定静态字典缓存 + */ + public void clearStaticDictCache(String dictCode) { + staticDictCache.remove(dictCode); + } + + /** + * 清除指定动态字典缓存 + */ + public void clearDynamicDictCache(String tableName, String codeColumn, String nameColumn, String filter) { + String cacheKey = tableName + "|" + codeColumn + "|" + nameColumn + "|" + StrUtil.nullToDefault(filter, ""); + dynamicDictCache.remove(cacheKey); + } + + // ==================== 反射工具方法 ==================== + + /** + * 通过反射获取对象的字段值(转为字符串),支持驼峰命名 + */ + private String getFieldValue(T obj, String fieldName) { + try { + Field field = findField(obj.getClass(), fieldName); + if (field == null) { + return null; + } + field.setAccessible(true); + Object value = field.get(obj); + return value != null ? value.toString() : null; + } catch (Exception e) { + return null; + } + } + + /** + * 通过反射设置对象的字段值,支持驼峰命名 + */ + private void setFieldValue(T obj, String fieldName, String value) { + try { + Field field = findField(obj.getClass(), fieldName); + if (field == null) { + return; + } + field.setAccessible(true); + field.set(obj, value); + } catch (Exception ignored) { + // 忽略设置失败 + } + } + + /** + * 查找字段(忽略大小写,支持驼峰和下划线变体),递归查找父类 + */ + private Field findField(Class clazz, String fieldName) { + if (clazz == null || clazz == Object.class) { + return null; + } + // 先精确匹配 + for (Field field : clazz.getDeclaredFields()) { + if (field.getName().equals(fieldName)) { + return field; + } + } + // 忽略大小写匹配 + for (Field field : clazz.getDeclaredFields()) { + if (field.getName().equalsIgnoreCase(fieldName)) { + return field; + } + } + // 驼峰-下划线互转匹配 + String camelName = underlineToCamel(fieldName); + String underlineName = camelToUnderline(fieldName); + for (Field field : clazz.getDeclaredFields()) { + String fName = field.getName(); + if (fName.equalsIgnoreCase(camelName) || fName.equalsIgnoreCase(underlineName)) { + return field; + } + } + return findField(clazz.getSuperclass(), fieldName); + } + + private String underlineToCamel(String str) { + if (StrUtil.isBlank(str) || !str.contains("_")) { + return str; + } + StringBuilder sb = new StringBuilder(); + boolean upper = false; + for (char c : str.toCharArray()) { + if (c == '_') { + upper = true; + } else { + sb.append(upper ? Character.toUpperCase(c) : c); + upper = false; + } + } + return sb.toString(); + } + + private String camelToUnderline(String str) { + if (StrUtil.isBlank(str)) { + return str; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (Character.isUpperCase(c)) { + sb.append('_').append(Character.toLowerCase(c)); + } else { + sb.append(c); + } + } + return sb.toString(); + } +} \ No newline at end of file From 0d6647aa45f9fcafeb40e8e50f3a041e82c9855f Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 08:47:22 +0800 Subject: [PATCH 31/65] =?UTF-8?q?fix:=20=E9=9D=99=E6=80=81=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E5=92=8C=E5=8A=A8=E6=80=81=E5=AD=97=E5=85=B8=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E4=B8=AD=E6=96=87=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/DictCodeToNameConverter.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java b/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java index a7db357d..363d4f92 100644 --- a/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java +++ b/backend/src/main/java/com/yfd/platform/utils/DictCodeToNameConverter.java @@ -1,6 +1,7 @@ package com.yfd.platform.utils; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.system.domain.SysDictionary; import com.yfd.platform.system.domain.SysDictionaryItems; @@ -106,6 +107,46 @@ public class DictCodeToNameConverter { } } + /** + * 分页结果转换:将 Page 中所有记录的 code 字段转换为对应的 name 字段 + * + *
+     * 使用示例:
+     * Page<SdHbrvDic> page = hbrvDicService.queryPageList(...);
+     * dictCodeToNameConverter.convertCodeToName(page, CODE_TO_NAME_META_LIST);
+     * 
+ * + * @param page 分页对象 + * @param metadataList 元数据配置列表 + * @param VO 类型 + */ + public void convertCodeToName(Page page, List metadataList) { + if (page == null || page.getRecords() == null || page.getRecords().isEmpty()) { + return; + } + convertCodeToName(page.getRecords(), metadataList); + } + + /** + * 单个对象转换:将单个对象的 code 字段转换为对应的 name 字段 + * + *
+     * 使用示例:
+     * SdHbrvDic hbrvDic = hbrvDicService.getById(hbrvcd);
+     * dictCodeToNameConverter.convertCodeToName(hbrvDic, CODE_TO_NAME_META_LIST);
+     * 
+ * + * @param obj 单个对象 + * @param metadataList 元数据配置列表 + * @param VO 类型 + */ + public void convertCodeToName(T obj, List metadataList) { + if (obj == null || metadataList == null || metadataList.isEmpty()) { + return; + } + convertCodeToName(Collections.singletonList(obj), metadataList); + } + /** * 加载静态字典映射 * From 27cf1e504c161b547206e6dffd1ca0937e01b4de Mon Sep 17 00:00:00 2001 From: lilin <18811154576@163.com> Date: Wed, 1 Jul 2026 09:11:16 +0800 Subject: [PATCH 32/65] =?UTF-8?q?=E5=9B=BE=E4=BE=8B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4=EF=BC=8C?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=20=E6=96=B0=E5=A2=9E=20=E4=BF=AE=E6=94=B9=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/config/SecurityConfig.java | 1 + .../yfd/platform/config/SwaggerConfig.java | 4 +- .../controller/MapLayerController.java | 21 +- .../controller/MapLegendController.java | 99 +++++++++- .../qgc_sys/mapLayer/domain/MsMaplegendB.java | 6 + .../qgc_sys/mapLayer/domain/MsMapmoduleB.java | 5 +- .../mapLayer/domain/MsMaptoolboxB.java | 186 ++++++++++++++++++ .../mapLayer/entity/vo/MapLayerVo.java | 80 ++++++++ .../mapLayer/entity/vo/MapLegendVo.java | 97 +++++++++ .../mapLayer/mapper/MsMapmoduleBMapper.java | 76 +++++++ .../mapLayer/mapper/MsMaptoolboxBMapper.java | 15 ++ .../mapLayer/service/IMapLayerBizService.java | 12 ++ .../service/IMapLegendBizService.java | 33 ++++ .../service/impl/MapLayerBizServiceImpl.java | 49 +++++ .../service/impl/MapLegendBizServiceImpl.java | 145 ++++++++++++++ .../controller/MapmoduleBController.java | 69 ++++++- .../qgc_sys/mapcfg/entity/MapmoduleVo.java | 47 +++++ .../mapcfg/service/IMapmoduleBService.java | 9 + .../service/impl/MapmoduleBServiceImpl.java | 91 +++++++++ 19 files changed, 1038 insertions(+), 7 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaptoolboxB.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLegendVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaptoolboxBMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/entity/MapmoduleVo.java diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 7648c9b2..bedbb152 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -73,6 +73,7 @@ public class SecurityConfig { // .requestMatchers("/fh/**").permitAll() // .requestMatchers("/data/**").permitAll() .requestMatchers("/mapLayer/**").permitAll() + .requestMatchers("/mapmodule/**").permitAll() .requestMatchers("/mapLegend/**").permitAll() .requestMatchers("/sms/**").permitAll() .requestMatchers(HttpMethod.GET, "/").permitAll() diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index e6a0b033..fd4d2841 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -164,10 +164,10 @@ public class SwaggerConfig { } @Bean - public GroupedOpenApi groupSysMlgApi() { + public GroupedOpenApi groupSysMcfgApi() { return GroupedOpenApi.builder() .group("5.1 图例结构管理") - .packagesToScan("com.yfd.platform.qgc_sys.mapLegend.controller") + .packagesToScan("com.yfd.platform.qgc_sys.mapcfg.controller") .build(); } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java index 981346ce..84c0ef86 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLayerController.java @@ -1,9 +1,11 @@ package com.yfd.platform.qgc_sys.mapLayer.controller; import cn.hutool.core.util.StrUtil; +import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.exception.BizException; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo; import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerBizService; import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerService; @@ -37,7 +39,24 @@ public class MapLayerController { @PostMapping("/getAllMapLayerTree") public ResponseResult getAllMapLayerTree(@RequestBody MapLayerAo flag) { List tree = mapLayerBizService.getMapLayerTree(flag); - return ResponseResult.successData(tree); + // 构建 Kendo 数据源结果 + DataSourceResult dataSourceResult = new DataSourceResult<>(); + dataSourceResult.setData(tree); + // 计算总节点数 + long total = countTreeNodes(tree); + dataSourceResult.setTotal(tree.size()); + return ResponseResult.successData(dataSourceResult); + } + private long countTreeNodes(List nodes) { + if (nodes == null) return 0; + long count = 0; + for (MsMaplayerB node : nodes) { + count++; // 当前节点 + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + count += countTreeNodes(node.getChildren()); + } + } + return count; } /** diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java index f038b8e7..bb5830c7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java @@ -3,21 +3,32 @@ package com.yfd.platform.qgc_sys.mapLayer.controller; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.exception.BizException; import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplayerBMapper; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerService; import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendService; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLegendVo; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendBizService; import com.yfd.platform.utils.DataSourceRequestUtil; +import com.yfd.platform.utils.SecurityUtils; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import java.util.List; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; /** * 地图图例管理 @@ -32,6 +43,11 @@ public class MapLegendController { @Resource private IMapLegendService mapLegendService; + @Resource + private IMapLegendBizService mapLegendBizService; + + @Resource + private MsMaplayerBMapper msMaplayerBMapper; // 新增注入 /** * 条件过滤数据列表(Kendo UI 数据源) */ @@ -54,6 +70,68 @@ public class MapLegendController { resultPage.setTotal(list.size()); } + List records = resultPage.getRecords(); + if (records != null && !records.isEmpty()) { + // ---------- 2. 批量获取父级信息(用于 parentCode、parentName)---------- + Set parentIds = records.stream() + .filter(e -> e.getDataType() != null && e.getDataType() == 2) // 只处理图例数据 + .map(MsMaplegendB::getParentId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + Map parentMap = new HashMap<>(); + if (!parentIds.isEmpty()) { + List parents = mapLegendService.listByIds(parentIds); + parentMap = parents.stream() + .collect(Collectors.toMap(MsMaplegendB::getId, Function.identity())); + } + + // ---------- 3. 批量获取图层名称(根据 layerCode 查 MS_MAPLAYER_B)---------- + Set layerCodes = records.stream() + .map(MsMaplegendB::getLayerCode) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + Map layerCodeNameMap = new HashMap<>(); + if (!layerCodes.isEmpty()) { + // 使用 Mapper 查询 + List layerList = msMaplayerBMapper.selectList( + new LambdaQueryWrapper() + .in(MsMaplayerB::getCode, layerCodes) + ); + layerCodeNameMap = layerList.stream() + .collect(Collectors.toMap(MsMaplayerB::getCode, MsMaplayerB::getTitle)); + } + + // ---------- 4. 遍历记录,填充三个额外字段 ---------- + for (MsMaplegendB entity : records) { + // 4.1 填充 parentCode / parentName(仅 dataType=2) + if (entity.getDataType() != null && entity.getDataType() == 2) { + String parentId = entity.getParentId(); + if (parentId != null && parentMap.containsKey(parentId)) { + MsMaplegendB parent = parentMap.get(parentId); + entity.setParentCode(parent.getCode()); + entity.setParentName(parent.getName()); + } else { + entity.setParentCode(null); + entity.setParentName(null); + } + } else { + // 非 dataType=2 的记录,这两个字段置空 + entity.setParentCode(null); + entity.setParentName(null); + } + + // 4.2 填充 layerCodeName(所有记录均可填充,如果图层不存在则置空) + String layerCode = entity.getLayerCode(); + if (layerCode != null && layerCodeNameMap.containsKey(layerCode)) { + entity.setLayerCodeName(layerCodeNameMap.get(layerCode)); + } else { + entity.setLayerCodeName(null); + } + } + } + // 构建 Kendo 数据源结果 DataSourceResult dataSourceResult = new DataSourceResult<>(); dataSourceResult.setData(resultPage.getRecords()); @@ -86,6 +164,15 @@ public class MapLegendController { if (legend.getDataType() == 2 && StrUtil.isBlank(legend.getLayerCode())) { throw new BizException("关联的图层编码(layerCode)不能为空."); } + if (StrUtil.isNotBlank(legend.getName())){ + if(StrUtil.isBlank(legend.getGroupName())){ + legend.setGroupName(legend.getName()); + } + if(StrUtil.isBlank(legend.getParentName())){ + legend.setGroupName(legend.getName()); + } + } + legend.setRecordUser(SecurityUtils.getUserId()); mapLegendService.saveOrUpdate(legend); return ResponseResult.success("保存成功."); } @@ -99,4 +186,14 @@ public class MapLegendController { mapLegendService.delelteByIds(ids); return ResponseResult.success("删除成功."); } + + /** + * 地图图例管理图层树(下拉选) + */ + @Operation(summary = "地图图例管理图层树(下拉选)") + @GetMapping("/getAllMapLegendTree") + public ResponseResult getAllMapLayerTree(Integer flag) { + List tree = mapLegendBizService.getMapLegendTree(flag); + return ResponseResult.successData(tree); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java index 6147f6c3..3e2151d7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaplegendB.java @@ -131,4 +131,10 @@ public class MsMaplegendB implements Serializable { @TableField("IS_FILTER") private Integer isFilter; + + @TableField(exist = false) + private String layerCodeName; + + @TableField(exist = false) + private String parentCode; } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java index aac57f40..84c2f75d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMapmoduleB.java @@ -80,11 +80,14 @@ public class MsMapmoduleB implements Serializable { @TableField("TEMPLATE_ID") private String templateId; + @TableField("SYSTEM_ID") + private String systemId; + /** * 归属的系统ID(非数据库字段,用于字典翻译) */ @TableField(exist = false) - private String systemId; + private String systemName; /** * 菜单名称(非数据库字段,用于字典翻译) diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaptoolboxB.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaptoolboxB.java new file mode 100644 index 00000000..1439c017 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/domain/MsMaptoolboxB.java @@ -0,0 +1,186 @@ +package com.yfd.platform.qgc_sys.mapLayer.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 地图工具箱表 + * + * @author migration + */ +@Data +@TableName("MS_MAPTOOLBOX_B") +public class MsMaptoolboxB implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + /** + * 名称 + */ + @TableField("NAME") + private String name; + + /** + * 名称(英文) + */ + @TableField("NAME_EN") + private String nameEn; + + /** + * 编码 + */ + @TableField("CODE") + private String code; + + /** + * 地图模式 + */ + @TableField("MAP_MODEL") + private String mapModel; + + /** + * 所属父节点 + */ + @TableField("PATENT_ID") + private String patentId; + + /** + * 树全路径 + */ + @TableField("FULL_PATH") + private String fullPath; + + /** + * 层级 + */ + @TableField("TREE_LEVEL") + private Integer treeLevel; + + /** + * 是否有子集 + */ + @TableField("HAS_CHILDREN") + private Integer hasChildren; + + /** + * 图标 + */ + @TableField("ICON") + private String icon; + + /** + * 备注 + */ + @TableField("DESCRIPTION") + private String description; + + /** + * 是否启用 + */ + @TableField("ENABLE") + private Integer enable; + + /** + * 系统内置项 + */ + @TableField("INTERNAL") + private Integer internal; + + /** + * 排序 + */ + @TableField("ORDER_INDEX") + private Integer orderIndex; + + /** + * 过滤内容 + */ + @TableField("FILTER_CONTENT") + private String filterContent; + + /** + * 创建人 + */ + @TableField("RECORD_USER") + private String recordUser; + + /** + * 创建时间 + */ + @TableField("RECORD_TIME") + private Date recordTime; + + /** + * 更新人 + */ + @TableField("MODIFY_USER") + private String modifyUser; + + /** + * 更新时间 + */ + @TableField("MODIFY_TIME") + private Date modifyTime; + + /** + * 是否已删除 + */ + @TableField("IS_DELETED") + private Integer isDeleted; + + /** + * 删除人 + */ + @TableField("DELETE_USER") + private String deleteUser; + + /** + * 删除时间 + */ + @TableField("DELETE_TIME") + private Date deleteTime; + + /** + * 类型:0-功能区 1-地形 2-图例 + */ + @TableField("TOOL_TYPE") + private Integer toolType; + + /** + * 归属的系统ID(非数据库字段,来自MS_MAPMODULE_B关联) + */ + @TableField(exist = false) + private String systemId; + + /** + * 是否默认勾选(非数据库字段,来自MS_MAPMODULE_B关联) + */ + @TableField(exist = false) + private Integer checked; + + /** + * 是否可勾选(非数据库字段,来自MS_MAPMODULE_B关联) + */ + @TableField(exist = false) + private Integer canBeChecked; + + /** + * 是否多选(非数据库字段,来自MS_MAPMODULE_B关联) + */ + @TableField(exist = false) + private Integer multiSelect; + + /** 子级集合(非数据库字段) */ + @TableField(exist = false) + private List children; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerVo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerVo.java new file mode 100644 index 00000000..55c7ad5e --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLayerVo.java @@ -0,0 +1,80 @@ +package com.yfd.platform.qgc_sys.mapLayer.entity.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 地图图层管理封装VO + * + * @author migration + */ +@Data +@Schema(description = "地图图层管理封装VO") +public class MapLayerVo { + + @Schema(description = "主键") + private String id; + + @Schema(description = "父id") + private String parentId; + + @Schema(description = "标题名称") + private String title; + + @Schema(description = "图层标识") + @JsonProperty(value = "key") + private String code; + + @Schema(description = "标签层级") + @JsonProperty(value = "labelLevel") + private Integer labelLevel; + + @Schema(description = "是否可以选择:0=否 1=是") + private Integer checkable; + + @Schema(description = "图层分类") + private String type; + + @Schema(description = "图层上下层层级关系") + @JsonProperty(value = "zIndex") + private String zIndex; + + @Schema(description = "各类站点图层对应类型") + private String sttpType; + + @Schema(description = "图层展示数据格式") + private String layers; + + @Schema(description = "url地址") + private String url; + + @Schema(description = "3D url地址") + private String urlThd; + + @Schema(description = "图层透明度") + private BigDecimal opacity; + + @Schema(description = "子级集合") + private List children; + + @Schema(description = "参数json") + private String paramJson; + + @Schema(description = "排序") + private String orderIndex; + + @Schema(description = "是否默认勾选:0=否 1=是") + private Integer checked; + + @Schema(description = "是否可勾选:0=否 1=是") + private Integer canBeChecked; + + @Schema(description = "是否多选:0=否 1=是") + private Integer multiSelect; + @Schema(description = "参数设置:steady=静态 dynamic=动态") + private String options; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLegendVo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLegendVo.java new file mode 100644 index 00000000..3ad7fa4a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/entity/vo/MapLegendVo.java @@ -0,0 +1,97 @@ +package com.yfd.platform.qgc_sys.mapLayer.entity.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 地图图例VO + * + * @author migration + */ +@Data +@Schema(description = "地图图例VO") +public class MapLegendVo { + + @Schema(description = "图例id") + private String id; + + @Schema(description = "父级id") + private String parentId; + + @Schema(description = "分组名") + private String groupName; + + @Schema(description = "层级名称") + private String parentName; + + @Schema(description = "图例名") + private String name; + + @Schema(description = "图例code") + private String code; + + @Schema(description = "图例icon") + private String icon; + + @Schema(description = "图例英文(对应描点数据中的状态)") + private String nameEn; + + @Schema(description = "图层code") + private String layerCode; + + @Schema(description = "是否多选;0=否;1=是") + private Integer multiSelect; + + @Schema(description = "是否默认勾选;0=否;1=是") + private Integer checked; + + @Schema(description = "是否可勾选;0=否;1=是") + private Integer canBeChecked; + + @Schema(description = "子排序") + private Integer orderIndex; + + @Schema(description = "父排序") + private Integer pSort; + + @Schema(description = "最小缩放等级") + private Integer minZoom; + + @Schema(description = "最大缩放等级") + private Integer maxZoom; + + @Schema(description = "最小高程-三维") + private BigDecimal minHeightThd; + + @Schema(description = "最大高程-三维") + private BigDecimal maxHeightThd; + + @Schema(description = "是否显示;0=否;1=是") + private Integer ifShow; + + @Schema(description = "是否过滤;0=否;1=是") + private Integer isFilter; + + @JsonProperty(value = "color") + @Schema(description = "图例颜色") + private String color; + + @JsonProperty(value = "shape") + @Schema(description = "图例形状") + private String shape; + + @JsonProperty(value = "minVal") + @Schema(description = "区间最小值") + private BigDecimal minVal; + + @JsonProperty(value = "maxVal") + @Schema(description = "区间最大值") + private BigDecimal maxVal; + + @Schema(description = "子级") + private List childrenList; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java index 774e4c00..e219ae10 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java @@ -2,7 +2,14 @@ package com.yfd.platform.qgc_sys.mapLayer.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaptoolboxB; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerVo; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLegendVo; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; /** * 地图与菜单映射表 Mapper 接口 @@ -11,4 +18,73 @@ import org.apache.ibatis.annotations.Mapper; */ @Mapper public interface MsMapmoduleBMapper extends BaseMapper { + + /** + * 查询地图图层树(关联MS_MAPMODULE_B与MS_MAPLAYER_B) + */ + @Select("") + List getMapLayerTree(@Param("moduleId") String moduleId, @Param("sid") String sid, + @Param("templateId") String templateId); + + /** + * 查询地图工具箱(关联MS_MAPMODULE_B与MS_MAPTOOLBOX_B) + */ + @Select("") + List getMapToolBox(@Param("moduleId") String moduleId, @Param("sid") String sid, + @Param("templateId") String templateId); + + /** + * 查询模块关联的图例列表(关联MS_MAPMODULE_B与MS_MAPLEGEND_B) + */ + @Select("") + List getModuleMapLegendList(@Param("moduleId") String moduleId, @Param("sid") String sid, + @Param("templateId") String templateId); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaptoolboxBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaptoolboxBMapper.java new file mode 100644 index 00000000..cff67cc6 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMaptoolboxBMapper.java @@ -0,0 +1,15 @@ +package com.yfd.platform.qgc_sys.mapLayer.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaptoolboxB; +import org.apache.ibatis.annotations.Mapper; + +/** + * 地图工具箱表 Mapper 接口 + * + * @author migration + */ +@Mapper +public interface MsMaptoolboxBMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java index f0933a77..6705b7df 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLayerBizService.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_sys.mapLayer.service; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerVo; import java.util.List; @@ -19,4 +20,15 @@ public interface IMapLayerBizService { * @return 图层树列表 */ List getMapLayerTree(MapLayerAo flag); + + /** + * 根据模块ID、系统ID、模板ID获取地图图层树(关联MS_MAPMODULE_B) + * + * @param moduleId 模块ID + * @param systemId 系统ID + * @param templateId 模板ID + * @return 图层树列表 + */ + List getMapLayerTree(String moduleId, String systemId, String templateId); + } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java new file mode 100644 index 00000000..30d35833 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java @@ -0,0 +1,33 @@ +package com.yfd.platform.qgc_sys.mapLayer.service; + +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLegendVo; + +import java.util.List; + +/** + * 地图图例业务服务接口 + * + * @author migration + */ +public interface IMapLegendBizService { + + /** + * 获取地图图例树(下拉选) + * + * @param flag 数据类型过滤:null=全部, 1=结构, 2=数据 + * @return 图例树 + */ + List getMapLegendTree(Integer flag); + + + /** + * 根据模块ID、系统ID、模板ID获取模块关联的图例列表 + * + * @param moduleId 模块ID + * @param systemId 系统ID + * @param templateId 模板ID + * @return 图例列表 + */ + List getModuleMapLegendList(String moduleId, String systemId, String templateId); + +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java index 4ba92e0a..0bab5095 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLayerBizServiceImpl.java @@ -4,7 +4,9 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB; import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerVo; import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplayerBMapper; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerBizService; import com.yfd.platform.system.domain.SysDictionary; import com.yfd.platform.system.domain.SysDictionaryItems; @@ -38,6 +40,9 @@ public class MapLayerBizServiceImpl implements IMapLayerBizService { @Resource private SysUserMapper sysUserMapper; + @Resource + private MsMapmoduleBMapper msMapmoduleBMapper; + @Override public List getMapLayerTree(MapLayerAo flag) { // 1. 查询字典 "DTZJLX" 获取需要排除的图层类型 @@ -159,6 +164,50 @@ public class MapLayerBizServiceImpl implements IMapLayerBizService { if (children != null && !children.isEmpty()) { parent.setChildren(children); convertTree(children, childrenMap); + }else { + // 当没有子节点时,显式设置为空列表,保证 JSON 输出为 [] 而不是 null + parent.setChildren(new ArrayList<>()); + } + } + } + + @Override + public List getMapLayerTree(String moduleId, String systemId, String templateId) { + // 通过 JOIN 查询 MS_MAPLAYER_B 和 MS_MAPMODULE_B + List allLayers = msMapmoduleBMapper.getMapLayerTree(moduleId, systemId, templateId); + + if (allLayers == null || allLayers.isEmpty()) { + return new ArrayList<>(); + } + + // 取第一级 + List parents = allLayers.stream() + .filter(p -> StrUtil.isBlank(p.getParentId())) + .collect(Collectors.toList()); + + // 通过父级id分组子节点 + Map> childrenMap = allLayers.stream() + .filter(p -> StrUtil.isNotBlank(p.getParentId())) + .collect(Collectors.groupingBy(MapLayerVo::getParentId)); + + // 递归构建树 + convertLayerVoTree(parents, childrenMap); + return parents; + } + + /** + * 递归转换图层VO为树结构 + */ + private void convertLayerVoTree(List parents, Map> childrenMap) { + if (parents == null || parents.isEmpty()) { + return; + } + for (MapLayerVo parent : parents) { + String id = parent.getId(); + List children = childrenMap.get(id); + if (children != null && !children.isEmpty()) { + parent.setChildren(children); + convertLayerVoTree(children, childrenMap); } } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java new file mode 100644 index 00000000..cdc7a489 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java @@ -0,0 +1,145 @@ +package com.yfd.platform.qgc_sys.mapLayer.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplegendB; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLegendVo; +import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendBizService; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendService; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 地图图例业务服务实现类 + * + * @author migration + */ +@Service +public class MapLegendBizServiceImpl implements IMapLegendBizService { + + @Resource + private IMapLegendService legendService; + @Resource + private MsMapmoduleBMapper msMapmoduleBMapper; + /** + * 数据类型枚举:1=结构 + */ + private static final int DATA_TYPE_STRUCT = 1; + /** + * 数据类型枚举:2=数据 + */ + private static final int DATA_TYPE_DATA = 2; + + @Override + public List getMapLegendTree(Integer flag) { + // 查询所有数据 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(MsMaplegendB::getIsDeleted, 0); + if (flag != null) { + if (flag == DATA_TYPE_STRUCT) { + wrapper.eq(MsMaplegendB::getDataType, DATA_TYPE_STRUCT); + } else if (flag == DATA_TYPE_DATA) { + wrapper.eq(MsMaplegendB::getDataType, DATA_TYPE_DATA); + } + } + List legendList = legendService.list(wrapper); + + // 转换为VO + List list = new ArrayList<>(); + for (MsMaplegendB legend : legendList) { + MapLegendVo vo = new MapLegendVo(); + BeanUtil.copyProperties(legend, vo); + list.add(vo); + } + + // 取第一级 + List parents = list.stream() + .filter(p -> StringUtils.isBlank(p.getParentId())) + .sorted(Comparator.comparing(MapLegendVo::getOrderIndex, Comparator.nullsLast(Integer::compareTo))) + .collect(Collectors.toList()); + + // 通过父级id分组 + Map> mapList = list.stream() + .filter(p -> StringUtils.isNotBlank(p.getParentId())) + .collect(Collectors.groupingBy(MapLegendVo::getParentId)); + + // 递归转换数据为树结构 + convertTree(parents, mapList); + return parents; + } + + /** + * 递归转换树结构 + */ + private void convertTree(List parents, Map> subList) { + if (parents == null || parents.isEmpty()) { + return; + } + for (MapLegendVo p : parents) { + String id = p.getId(); + for (Map.Entry> entry : subList.entrySet()) { + String pid = entry.getKey(); + List children = entry.getValue(); + if (id.equals(pid)) { + p.setChildrenList(children); + convertTree(children, subList); + } + } + } + } + + + @Override + public List getModuleMapLegendList(String moduleId, String systemId, String templateId) { + List list = new ArrayList<>(); + // 通过 JOIN 查询 MS_MAPLEGEND_B 和 MS_MAPMODULE_B + List bbiMapLegendList = msMapmoduleBMapper.getModuleMapLegendList(moduleId, systemId, templateId); + + if (bbiMapLegendList == null || bbiMapLegendList.isEmpty()) { + return list; + } + + // 按父级分组 + Map> collect = bbiMapLegendList.stream() + .collect(Collectors.groupingBy(MapLegendVo::getParentName)); + + // 遍历 + collect.forEach((str, mapLegendVoList) -> { + MapLegendVo mapLegendVo = new MapLegendVo(); + mapLegendVo.setName(str); + mapLegendVo.setPSort(mapLegendVoList.get(0).getPSort()); + // 按子级分组名分组 + Map> collect1 = mapLegendVoList.stream() + .collect(Collectors.groupingBy(MapLegendVo::getGroupName)); + List childrenList = new ArrayList<>(); + for (String groupNameStr : collect1.keySet()) { + List list1 = collect1.get(groupNameStr); + // 如果子级和父级名称相同,则不用子级 + if (groupNameStr.equalsIgnoreCase(str)) { + childrenList = list1; + } else { + MapLegendVo mapLegendVoChild = new MapLegendVo(); + mapLegendVoChild.setName(groupNameStr); + if (null != list1 && list1.size() > 0) { + mapLegendVoChild.setPSort(list1.get(0).getPSort()); + } + mapLegendVoChild.setChildrenList(list1); + childrenList.add(mapLegendVoChild); + } + } + List collect2 = childrenList.stream() + .sorted(Comparator.comparing(MapLegendVo::getPSort, Comparator.nullsLast(Integer::compareTo))) + .collect(Collectors.toList()); + mapLegendVo.setChildrenList(collect2); + list.add(mapLegendVo); + }); + return list.stream() + .sorted(Comparator.comparing(MapLegendVo::getPSort, Comparator.nullsLast(Integer::compareTo))) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java index 09204d83..0ddd61ef 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java @@ -1,5 +1,6 @@ package com.yfd.platform.qgc_sys.mapcfg.controller; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.DataSourceRequest; @@ -8,13 +9,17 @@ import com.yfd.platform.config.ResponseResult; import com.yfd.platform.common.exception.BizException; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; import com.yfd.platform.qgc_sys.mapcfg.service.IMapmoduleBService; +import com.yfd.platform.qgc_sys.mapcfg.entity.MapmoduleVo; +import com.yfd.platform.system.domain.SysMenu; +import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.utils.DataSourceRequestUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * 地图菜单配置控制层 @@ -29,6 +34,9 @@ public class MapmoduleBController { @Resource private IMapmoduleBService mapmoduleBService; + @Resource + private SysMenuMapper sysMenuMapper; + /** * 条件过滤数据列表(Kendo UI 数据源) */ @@ -57,9 +65,55 @@ public class MapmoduleBController { dataSourceResult.setData(dataList); dataSourceResult.setTotal(resultPage.getTotal()); - // 翻译字典值(菜单名称) + // 翻译字典值(原有逻辑,可能处理其他字段) if (dataList != null && !dataList.isEmpty()) { mapmoduleBService.translateDict(dataList); + + // ----- 新增:填充 moduleName ----- + // 1. 先收集需要从数据库查询的 moduleId(排除 "tycd") + Set needQueryIds = dataList.stream() + .map(MsMapmoduleB::getModuleId) + .filter(id -> id != null && !"tycd".equals(id)) // 过滤掉 "tycd" + .collect(Collectors.toSet()); + + Map menuNameMap = new HashMap<>(); + if (!needQueryIds.isEmpty()) { + // 查询 SYS_MENU 表(假设实体为 SysMenu,Mapper 为 sysMenuMapper) + List menus = sysMenuMapper.selectList( + new LambdaQueryWrapper() + .in(SysMenu::getId, needQueryIds) // 注意 id 类型需匹配 + ); + menuNameMap = menus.stream() + .collect(Collectors.toMap( + menu -> String.valueOf(menu.getId()), // 统一转为字符串 + SysMenu::getName + )); + } + + // 2. 遍历 dataList 设置 moduleName + for (MsMapmoduleB entity : dataList) { + String moduleId = entity.getModuleId(); + if (moduleId == null) { + entity.setModuleName(null); + } else if ("tycd".equals(moduleId)) { + // 特殊处理:固定为 "通用菜单" + entity.setModuleName("通用菜单"); + } else { + // 从查询结果中获取 + entity.setModuleName(menuNameMap.get(moduleId)); + // 如果 menuNameMap 中不存在,则置 null(或保留原值,视业务而定) + if (entity.getModuleName() == null) { + entity.setModuleName(null); // 或者 entity.setModuleName(""); + } + } + } + // ========== 2. 处理 systemName 特殊值 ========== + for (MsMapmoduleB entity : dataList) { + if ("qgc".equals(entity.getSystemId())) { + entity.setSystemName("qgc"); + } + // 其他 systemId 保留字典翻译的结果 + } } return ResponseResult.successData(dataSourceResult); @@ -98,4 +152,15 @@ public class MapmoduleBController { mapmoduleBService.delelteByIds(ids); return ResponseResult.success("删除成功."); } + + + /** + * 地图图层管理数据 + */ + @Operation(summary = "地图图层管理数据") + @PostMapping("/getMapData") + public ResponseResult getMapData(@RequestBody MsMapmoduleB mapmoduleB) { + MapmoduleVo result = mapmoduleBService.getMapData(mapmoduleB); + return ResponseResult.successData(result); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/entity/MapmoduleVo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/entity/MapmoduleVo.java new file mode 100644 index 00000000..30134555 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/entity/MapmoduleVo.java @@ -0,0 +1,47 @@ +package com.yfd.platform.qgc_sys.mapcfg.entity; + +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaptoolboxB; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerVo; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLegendVo; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 地图与菜单查询返回实体类 + * + * @author migration + */ +@Data +@Schema(description = "地图菜单配置实体类") +public class MapmoduleVo { + + /** GIS地图多功能区 */ + @Schema(description = "GIS地图多功能区") + private List maptoolbox; + + /** GIS默认数据加载 - 地形 */ + @Schema(description = "GIS默认数据加载 - 地形") + private List terrain; + + /** GIS默认数据加载 - 图例 */ + @Schema(description = "GIS默认数据加载 - 图例") + private List legend; + + /** GIS默认数据加载 - 内容模块 */ + @Schema(description = "GIS默认数据加载 - 内容模块") + private List content; + + /** GIS默认数据加载 - 环保监测 */ + @Schema(description = "GIS默认数据加载 - 环保监测") + private List hbcj; + + /** GIS图层区 */ + @Schema(description = "GIS图层区") + private List mapLayerVos; + + /** 地图图例 */ + @Schema(description = "地图图例") + private List mapLegendVos; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java index 26c34a34..c6dcf69c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/IMapmoduleBService.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_sys.mapcfg.service; import com.baomidou.mybatisplus.extension.service.IService; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapcfg.entity.MapmoduleVo; import java.util.List; @@ -33,4 +34,12 @@ public interface IMapmoduleBService extends IService { * @param ids ID列表 */ void delelteByIds(List ids); + + /** + * 获取地图数据(图层树、图例、工具箱) + * + * @param mapmoduleB 查询参数 + * @return 地图数据 + */ + MapmoduleVo getMapData(MsMapmoduleB mapmoduleB); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java index d650bb50..1b7b5098 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/service/impl/MapmoduleBServiceImpl.java @@ -4,8 +4,15 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB; +import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaptoolboxB; import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerBizService; +import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendBizService; import com.yfd.platform.qgc_sys.mapcfg.service.IMapmoduleBService; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerVo; +import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLegendVo; +import com.yfd.platform.qgc_sys.mapcfg.entity.MapmoduleVo; + import com.yfd.platform.system.domain.SysMenu; import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.utils.SecurityUtils; @@ -29,6 +36,13 @@ public class MapmoduleBServiceImpl extends ServiceImpl lambdaQueryWrapper = new LambdaQueryWrapper<>(); + // lambdaQueryWrapper.eq(MsTemplateB::getIsDefault, 1); + // lambdaQueryWrapper.eq(MsTemplateB::getIsDeleted, 0); + // lambdaQueryWrapper.eq(MsTemplateB::getModuleId, mapmoduleB.getModuleId()); + // MsTemplateB msTemplateB = msTemplateBMapper.selectOne(lambdaQueryWrapper); + // if (msTemplateB != null) { + // templateId = msTemplateB.getId(); + // } + // } else { + // templateId = mapmoduleB.getTemplateId(); + // } + // ========== 预留代码结束 ========== + + MapmoduleVo mapmoduleVo = new MapmoduleVo(); + + // 1. GIS图层区 + List layer = mapLayerBizService.getMapLayerTree( + mapmoduleB.getModuleId(), mapmoduleB.getSystemId(), templateId); + mapmoduleVo.setMapLayerVos(layer); + + // 2. 地图图例 + List legend = mapLegendBizService.getModuleMapLegendList( + mapmoduleB.getModuleId(), mapmoduleB.getSystemId(), templateId); + mapmoduleVo.setMapLegendVos(legend); + + // 3. 地图工具箱 + List mapToolBox = baseMapper.getMapToolBox( + mapmoduleB.getModuleId(), mapmoduleB.getSystemId(), templateId); + + // 按toolType分组 + Map> groupedByType = mapToolBox.stream() + .collect(Collectors.groupingBy(MsMaptoolboxB::getToolType)); + + // 图例(toolType=2) + mapmoduleVo.setLegend(groupedByType.get(2)); + + // 内容模块(toolType=3) + List contentLayerTree = getContentLayerTree(groupedByType); + mapmoduleVo.setContent(contentLayerTree); + + // 环保监测(toolType=4) + mapmoduleVo.setHbcj(groupedByType.get(4)); + + return mapmoduleVo; + } + + /** + * 获取内容模块图层树 + */ + private List getContentLayerTree(Map> groupedByType) { + List msMaptoolboxBList = new java.util.ArrayList<>(); + List contentToolBoxList = groupedByType.get(3); + if (contentToolBoxList != null) { + for (MsMaptoolboxB msMaptoolboxB : contentToolBoxList) { + if (StrUtil.isNotBlank(msMaptoolboxB.getPatentId())) { + // 如果内容模块没有进行配置,则默认全部勾选 + if (msMaptoolboxB.getChecked() == null) { + msMaptoolboxB.setChecked(1); + } + msMaptoolboxBList.add(msMaptoolboxB); + } + } + } + return msMaptoolboxBList; + } } \ No newline at end of file From ff45b9a5f333f5f68b5155b20b89937cca428f6a Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 09:52:43 +0800 Subject: [PATCH 33/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java index 520e3752..be1aa4b8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java @@ -1504,7 +1504,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl Date: Wed, 1 Jul 2026 10:12:55 +0800 Subject: [PATCH 34/65] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index d470ba6e..124541a0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -3327,6 +3327,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { "'ENG' AS sttpCode, " + "'电站' AS sttpName, " + "eng.STCD AS stcd, " + + "pbh.TTPWR AS ttpwr, " + "eng.ENNM AS stnm, " + "eng.ENNM AS ennm, " + "eng.BASE_ID AS baseId, " + @@ -3346,6 +3347,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + "NVL(eng.ORDER_INDEX, 999999) AS siteStepSort " + "FROM SD_ENGINFO_B_H eng " + + "INNER JOIN SD_PWR_B_H pbh ON pbh.STCD= eng.STCD " + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + @@ -5440,6 +5442,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { case "sttpCode" -> "t.sttpCode"; case "sttpName" -> "t.sttpName"; case "stcd" -> "t.stcd"; + case "ttpwr" -> "t.ttpwr"; case "stnm" -> "t.stnm"; case "ennm" -> "t.ennm"; case "baseId" -> "t.baseId"; From 5a3fc371a6c6778e6efeb40605a7a9ce1defe6e4 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 11:39:54 +0800 Subject: [PATCH 35/65] =?UTF-8?q?feat:=20=E6=9F=A5=E8=AF=A2=E6=B0=B4?= =?UTF-8?q?=E7=94=9F=E7=94=9F=E6=80=81=E6=96=AD=E9=9D=A2=E7=9A=84=E5=B9=B4?= =?UTF-8?q?=E4=BB=BD=E5=8F=8A=E6=98=AF=E5=90=A6=E9=B1=BC=E7=B1=BB,?= =?UTF-8?q?=E6=B0=B4=E6=B8=A9,=E6=B0=B4=E8=B4=A8,=E6=B5=81=E9=80=9F?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 11 ++- .../wte/entity/vo/WeDefaultDataVo.java | 16 ++++ .../qgc_env/wte/service/WeFishService.java | 21 +----- .../wte/service/impl/WeFishServiceImpl.java | 75 +++++++++++++------ 4 files changed, 79 insertions(+), 44 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeDefaultDataVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index b9a881bb..88fa9eb2 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -7,10 +7,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/wte") @@ -158,4 +155,10 @@ public class WeFishController { public ResponseResult getTeSpecialAnimalList(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(weFishService.getTeSpecialAnimalList(dataSourceRequest)); } + + @GetMapping("/getWeDefaultData") + @Operation(summary = "查询水生生态断面的年份及是否鱼类,水温,水质,流速数据") + public ResponseResult getWeDefaultData(@RequestParam("stcd") String stcd) { + return ResponseResult.successData(weFishService.getWeDefaultData(stcd)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeDefaultDataVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeDefaultDataVo.java new file mode 100644 index 00000000..afaafca0 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeDefaultDataVo.java @@ -0,0 +1,16 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "水生生态断面默认数据实体类") +public class WeDefaultDataVo { + + private String yr; + private Integer hasFtp; + private Integer hasFv; + private Integer hasWq; + private Integer hasWt; + +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index fe6da23e..7bb90c5b 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -2,24 +2,7 @@ package com.yfd.platform.qgc_env.wte.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishHbbQgcDetailVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPageTableVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatTabVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishTQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeStaticsVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeTeSpecialAnimalVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeVmsstbprptVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaDefaultVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaYearQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.*; import java.util.List; import java.util.Map; @@ -71,4 +54,6 @@ public interface WeFishService { DataSourceResult getQgcWeFishPoint(DataSourceRequest dataSourceRequest); DataSourceResult getTeSpecialAnimalList(DataSourceRequest dataSourceRequest); + + List getWeDefaultData(String stcd); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index d6fa20be..f19fb5ec 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -10,28 +10,7 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.GroupHelper; import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; -import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarHeadColumnVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarTableVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeCompareBarVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeEnvmAutoMonitorVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishListStatQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishDetailVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishHbbQgcDetailVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPageQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPageTableVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeMsstbprptVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishPointQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishStatTabVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeFishTQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeRvcdYearVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeStaticsVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeTeSpecialAnimalVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeVmsstbprptVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaDefaultVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaQgcVo; -import com.yfd.platform.qgc_env.wte.entity.vo.WeWvaYearQgcVo; +import com.yfd.platform.qgc_env.wte.entity.vo.*; import com.yfd.platform.qgc_env.wte.service.WeFishService; import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; @@ -1123,6 +1102,58 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public List getWeDefaultData(String stcd) { + String sql = "SELECT\n" + + "\ta.stcd,\n" + + "\tTO_CHAR( a.TM, 'yyyy' ) AS yr,\n" + + "CASE\n" + + "\t\t\n" + + "\t\tWHEN COUNT( b.ID ) > 0 THEN\n" + + "\t\t1 ELSE 0 \n" + + "\tEND AS hasFtp,\n" + + "CASE\n" + + "\t\t\n" + + "\t\tWHEN COUNT( c.ID ) > 0 THEN\n" + + "\t\t1 ELSE 0 \n" + + "\tEND AS hasFv,\n" + + "CASE\n" + + "\t\t\n" + + "\t\tWHEN COUNT( d.ID ) > 0 THEN\n" + + "\t\t1 ELSE 0 \n" + + "\tEND AS hasWq,\n" + + "CASE\n" + + "\t\t\n" + + "\t\tWHEN COUNT( e.ID ) > 0 THEN\n" + + "\t\t1 ELSE 0 \n" + + "\tEND AS hasWt \n" + + "FROM\n" + + "\tSD_WE_R a\n" + + "\tLEFT JOIN SD_WEFISH_R b ON a.ID = b.WER_ID \n" + + "\tAND b.IS_DELETED = 0\n" + + "\tLEFT JOIN SD_WEFV_R c ON a.ID = c.WER_ID \n" + + "\tAND c.IS_DELETED = 0\n" + + "\tLEFT JOIN SD_WEWQ_R d ON a.ID = d.WER_ID \n" + + "\tAND d.IS_DELETED = 0\n" + + "\tLEFT JOIN SD_WEWT_R e ON a.ID = e.WER_ID \n" + + "\tAND e.IS_DELETED = 0 \n" + + "WHERE\n" + + "\t1 = 1 \n" + + "\tAND a.IS_DELETED = 0 \n" + + "\tAND a.stcd = #{map.stcd} \n" + + "GROUP BY\n" + + "\ta.stcd,\n" + + "\tTO_CHAR( a.TM, 'yyyy' ) \n" + + "ORDER BY\n" + + "\tTO_CHAR( a.TM, 'yyyy' ) DESC,\n" + + "\ta.stcd\n" + + "\n"; + Map paramMap = new HashMap<>(); + paramMap.put("stcd", stcd); + List oneBySqlWithResultType = microservicDynamicSQLMapper.getAllListWithResultType(sql, paramMap, WeDefaultDataVo.class); + return oneBySqlWithResultType; + } + private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; From 9ce9f273ea8c3c1bc4a39a336dd13294c8fd5af4 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 12:55:56 +0800 Subject: [PATCH 36/65] =?UTF-8?q?feat:=20=E5=85=A8=E8=BF=87=E7=A8=8BAI?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E7=9B=91=E6=B5=8B=E6=97=A5=E5=8E=86=E8=A1=A8?= =?UTF-8?q?(=E6=96=87=E4=BB=B6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../warn/controller/WarnDataController.java | 6 + .../qgc_env/warn/entity/vo/AiFileVo.java | 43 +++ .../qgc_env/warn/service/WarnDataService.java | 3 + .../service/impl/WarnDataServiceImpl.java | 249 ++++++++++++++++++ 4 files changed, 301 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiFileVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java index 00421006..ebb0f33c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java @@ -74,4 +74,10 @@ public class WarnDataController { public ResponseResult getWarnStcdKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(warnDataService.getWarnStcdKendoListCust(dataSourceRequest)); } + + @PostMapping("/ai/com/qgc/aiFile/GetKendoListCust") + @Operation(summary = "全过程AI识别监测日历表(文件)") + public ResponseResult getAiFileKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(warnDataService.getAiFileKendoListCust(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiFileVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiFileVo.java new file mode 100644 index 00000000..c4d2abce --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiFileVo.java @@ -0,0 +1,43 @@ +package com.yfd.platform.qgc_env.warn.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * AI文件列表VO - 全过程AI识别监测日历表(文件) + * + * @author Generated + * @since 2025-07-01 + */ +@Data +public class AiFileVo { + + private String stcd; + + private String stnm; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date tm; + + private String fid; + + private String rstcd; + + private String ennm; + + private String stCode; + + private String stName; + + private Integer baseStepSort; + + private Integer rvcdStepSort; + + private Integer rstcdStepSort; + + private Integer siteStepSort; + + private Integer dataType; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java index eccdcb72..66f942ff 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java @@ -8,6 +8,7 @@ import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiDmRunVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiComListVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiRstcdVo; +import com.yfd.platform.qgc_env.warn.entity.vo.AiFileVo; import com.yfd.platform.qgc_env.warn.entity.vo.EngWarnCountVo; import com.yfd.platform.qgc_env.warn.entity.vo.StcdWarnStateVo; @@ -32,4 +33,6 @@ public interface WarnDataService { DataSourceResult getAlarmPointKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getWarnStcdKendoListCust(DataSourceRequest dataSourceRequest); + + DataSourceResult getAiFileKendoListCust(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java index efd22964..1928c9ed 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java @@ -13,6 +13,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.qgc_env.warn.entity.vo.AlarmPointVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiComListVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiDmRunVo; +import com.yfd.platform.qgc_env.warn.entity.vo.AiFileVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiRecordVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiRstcdVo; @@ -356,6 +357,254 @@ public class WarnDataServiceImpl implements WarnDataService { return result; } + @Override + public DataSourceResult getAiFileKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId"); + String tm = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "tm"); + String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd"); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String type = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "type"); + String dataType = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "dataType"); + + Date startTime = null, endTime = null; + if (StrUtil.isNotBlank(tm)) { + String[] ll = tm.split(","); + if (ll.length == 2) { + startTime = DateUtil.parse(ll[0]); + endTime = DateUtil.parse(ll[1]); + if (startTime.after(endTime)) { + Date tmp = startTime; + startTime = endTime; + endTime = tmp; + } + } + } + + if (StrUtil.isNotBlank(rstcd)) { + rstcd = rstcd.replace("[", "").replace("]", "").replaceAll("\"", "'"); + } + + Map paramMap = new HashMap<>(); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT * FROM ("); + sql.append(buildAiFileHeartbeatSql(baseId, type, rstcd, stcd, startTime, endTime, paramMap, "hb")); + sql.append(" UNION "); + sql.append(buildAiFileComSql(baseId, type, rstcd, stcd, startTime, endTime, paramMap, "ac")); + sql.append(") WHERE 1=1 "); + + if (StrUtil.isNotBlank(dataType)) { + paramMap.put("dataType", Integer.parseInt(dataType)); + sql.append("AND DATA_TYPE = #{map.dataType} "); + } + + sql.append(buildAiFileOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql.toString(), + paramMap, + AiFileVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page == null ? list.size() : page.getTotal()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildAiFileHeartbeatSql(String baseId, String type, String rstcd, String stcd, + Date startTime, Date endTime, Map paramMap, String keyPrefix) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("a.STCD AS STCD, ") + .append("b.RSTCD AS RSTCD, ") + .append("eng.ENNM AS ENNM, ") + .append("b.STCD AS STCODE, ") + .append("b.STNM AS STNAME, ") + .append("hb.ORDER_INDEX AS BASESTEPSORT, ") + .append("along.ORDER_INDEX AS RVCDSTEPSORT, ") + .append("rstSort.SORT AS RSTCDSTEPSORT, ") + .append("siteSort.SORT AS SITESTEPSORT, ") + .append("b.STNM AS STNM, ") + .append("a.TM AS TM, "); + + if (StrUtil.isNotBlank(type)) { + if ("AI_5001".equals(type) || "AI_50011".equals(type)) { + sql.append("3 AS DATA_TYPE, "); + } else { + sql.append("1 AS DATA_TYPE, "); + } + } else { + sql.append("1 AS DATA_TYPE, "); + } + + sql.append("REGEXP_SUBSTR(a.FID, '[^,]+', 1, LEVEL) AS FID "); + sql.append("FROM SD_AIHEARTBEAT_R a "); + sql.append("INNER JOIN SD_AIMONITOR_B_H b ON a.STCD = b.STCD AND NVL(b.IS_DELETED, 0) = 0 AND b.STTP LIKE 'AI_%' "); + sql.append("LEFT JOIN SD_ENGINFO_B_H eng ON b.RSTCD = eng.STCD AND NVL(eng.IS_DELETED, 0) = 0 "); + sql.append("LEFT JOIN SD_HYDROBASE hb ON b.BASE_ID = hb.BASEID AND NVL(hb.IS_DELETED, 0) = 0 "); + sql.append("LEFT JOIN MS_ALONG_B along ON b.HBRVCD = along.RVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 "); + sql.append("LEFT JOIN (SELECT det.SORT, cfg.RVCD, det.STCD FROM MS_ALONGDET_B det INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common') rstSort ON rstSort.RVCD = b.HBRVCD AND rstSort.STCD = b.RSTCD "); + sql.append("LEFT JOIN (SELECT det.SORT, cfg.RVCD, det.STCD FROM MS_ALONGDET_B det INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common') siteSort ON siteSort.RVCD = b.HBRVCD AND siteSort.STCD = b.STCD "); + sql.append("WHERE NVL(a.IS_DELETED, 0) = 0 "); + sql.append("AND a.FID NOT LIKE '%ORA-%' AND a.FID NOT LIKE '%Out%' "); + + if (StrUtil.isNotBlank(type)) { + if ("AI_50011".equals(type)) { + sql.append("AND b.STTP = 'AI_5001' "); + } else { + sql.append("AND b.STTP = '").append(type).append("' "); + } + } + if (StrUtil.isNotBlank(baseId)) { + paramMap.put(keyPrefix + "BaseId", baseId); + sql.append("AND b.BASE_ID = #{map.").append(keyPrefix).append("BaseId} "); + } + if (StrUtil.isNotBlank(stcd)) { + paramMap.put(keyPrefix + "Stcd", stcd); + sql.append("AND b.STCD = #{map.").append(keyPrefix).append("Stcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + sql.append("AND b.RSTCD IN (").append(rstcd).append(") "); + } + if (startTime != null) { + paramMap.put(keyPrefix + "StartTime", startTime); + sql.append("AND a.TM >= #{map.").append(keyPrefix).append("StartTime} "); + } + if (endTime != null) { + paramMap.put(keyPrefix + "EndTime", endTime); + sql.append("AND a.TM <= #{map.").append(keyPrefix).append("EndTime} "); + } + + sql.append("CONNECT BY REGEXP_SUBSTR(a.FID, '[^,]+', 1, LEVEL) IS NOT NULL "); + sql.append("AND PRIOR a.ID = a.ID "); + sql.append("AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL"); + + return sql.toString(); + } + + private String buildAiFileComSql(String baseId, String type, String rstcd, String stcd, + Date startTime, Date endTime, Map paramMap, String keyPrefix) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("a.STCD AS STCD, ") + .append("b.RSTCD AS RSTCD, ") + .append("eng.ENNM AS ENNM, ") + .append("b.STCD AS STCODE, ") + .append("b.STNM AS STNAME, ") + .append("hb.ORDER_INDEX AS BASESTEPSORT, ") + .append("along.ORDER_INDEX AS RVCDSTEPSORT, ") + .append("rstSort.SORT AS RSTCDSTEPSORT, ") + .append("siteSort.SORT AS SITESTEPSORT, ") + .append("b.STNM AS STNM, ") + .append("a.TM AS TM, "); + + if (StrUtil.isNotBlank(type)) { + if ("AI_5001".equals(type) || "AI_50011".equals(type)) { + sql.append("(CASE WHEN a.TYPE = 'AI_5001' AND (a.IS_BIG_DEBRIS_AREA IS NULL OR a.IS_BIG_DEBRIS_AREA = 0) THEN 4 WHEN a.TYPE = 'AI_5001' AND a.IS_BIG_DEBRIS_AREA > 0 THEN 5 END) AS DATA_TYPE, "); + } else { + sql.append("2 AS DATA_TYPE, "); + } + } else { + sql.append("2 AS DATA_TYPE, "); + } + + sql.append("REGEXP_SUBSTR(a.FID, '[^,]+', 1, LEVEL) AS FID "); + sql.append("FROM SD_AICOM_R a "); + sql.append("INNER JOIN SD_AIMONITOR_B_H b ON a.STCD = b.STCD AND NVL(b.IS_DELETED, 0) = 0 AND b.STTP LIKE 'AI_%' "); + sql.append("LEFT JOIN SD_ENGINFO_B_H eng ON b.RSTCD = eng.STCD AND NVL(eng.IS_DELETED, 0) = 0 "); + sql.append("LEFT JOIN SD_HYDROBASE hb ON b.BASE_ID = hb.BASEID AND NVL(hb.IS_DELETED, 0) = 0 "); + sql.append("LEFT JOIN MS_ALONG_B along ON b.HBRVCD = along.RVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 "); + sql.append("LEFT JOIN (SELECT det.SORT, cfg.RVCD, det.STCD FROM MS_ALONGDET_B det INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common') rstSort ON rstSort.RVCD = b.HBRVCD AND rstSort.STCD = b.RSTCD "); + sql.append("LEFT JOIN (SELECT det.SORT, cfg.RVCD, det.STCD FROM MS_ALONGDET_B det INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common') siteSort ON siteSort.RVCD = b.HBRVCD AND siteSort.STCD = b.STCD "); + sql.append("WHERE NVL(a.IS_DELETED, 0) = 0 "); + sql.append("AND (a.TASK_STATUS IS NULL OR a.TASK_STATUS = 'Approved') "); + sql.append("AND a.FID NOT LIKE '%ORA-%' AND a.FID NOT LIKE '%Out%' "); + + if (StrUtil.isNotBlank(type)) { + if ("AI_50011".equals(type)) { + paramMap.put(keyPrefix + "Type", "AI_5001"); + sql.append("AND a.TYPE = #{map.").append(keyPrefix).append("Type} "); + } else { + paramMap.put(keyPrefix + "Type", type); + sql.append("AND a.TYPE = #{map.").append(keyPrefix).append("Type} "); + } + } + if (StrUtil.isNotBlank(baseId)) { + paramMap.put(keyPrefix + "BaseId", baseId); + sql.append("AND b.BASE_ID = #{map.").append(keyPrefix).append("BaseId} "); + } + if (StrUtil.isNotBlank(stcd)) { + paramMap.put(keyPrefix + "Stcd", stcd); + sql.append("AND b.STCD = #{map.").append(keyPrefix).append("Stcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + sql.append("AND b.RSTCD IN (").append(rstcd).append(") "); + } + if (startTime != null) { + paramMap.put(keyPrefix + "StartTime", startTime); + sql.append("AND a.TM >= #{map.").append(keyPrefix).append("StartTime} "); + } + if (endTime != null) { + paramMap.put(keyPrefix + "EndTime", endTime); + sql.append("AND a.TM <= #{map.").append(keyPrefix).append("EndTime} "); + } + + sql.append("CONNECT BY REGEXP_SUBSTR(a.FID, '[^,]+', 1, LEVEL) IS NOT NULL "); + sql.append("AND PRIOR a.ID = a.ID "); + sql.append("AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL"); + + return sql.toString(); + } + + private String buildAiFileOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY STCD, TM DESC "; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor item : sortList) { + if (item == null || StrUtil.isBlank(item.getField())) { + continue; + } + String column = mapAiFileColumn(item.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(item.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (orderItems.isEmpty()) { + return " ORDER BY STCD, TM DESC "; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String mapAiFileColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "STCD"; + case "stnm" -> "STNM"; + case "tm" -> "TM"; + case "fid" -> "FID"; + case "rstcd" -> "RSTCD"; + case "ennm" -> "ENNM"; + case "stCode" -> "STCODE"; + case "stName" -> "STNAME"; + case "baseStepSort" -> "BASESTEPSORT"; + case "rvcdStepSort" -> "RVCDSTEPSORT"; + case "rstcdStepSort" -> "RSTCDSTEPSORT"; + case "siteStepSort" -> "SITESTEPSORT"; + case "dataType" -> "DATA_TYPE"; + default -> null; + }; + } + private AiDmRunVo buildAiDmRunVo(Map row) { if (row == null || row.isEmpty()) { return null; From 159f24eaf7fa403a331d6aabc3a8dc1d68341d45 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 13:11:38 +0800 Subject: [PATCH 37/65] =?UTF-8?q?feat:=20(=E5=85=A8=E8=BF=87=E7=A8=8B)?= =?UTF-8?q?=E5=A2=9E=E6=AE=96=E7=AB=99=E4=BA=8C=E7=BA=A7=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?:=20=E8=BF=87=E7=A8=8B=E5=9B=BE-=E4=BA=A7=E5=8D=B5=E5=92=8C?= =?UTF-8?q?=E5=AD=B5=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/controller/FbStationController.java | 8 + .../qgc_env/fb/entity/vo/FishhatchrecRVo.java | 17 ++ .../qgc_env/fb/entity/vo/HeadColunmsVo.java | 52 ++++ .../qgc_env/fb/entity/vo/TableVo.java | 27 ++ .../qgc_env/fb/service/FbStationService.java | 3 + .../fb/service/impl/FbStationServiceImpl.java | 233 ++++++++++++++++++ 6 files changed, 340 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java index 9d05bd9f..f0d90c09 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java @@ -132,4 +132,12 @@ public class FbStationController { public ResponseResult getResearchKendoList(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(fbStationService.getResearchKendoList(dataSourceRequest)); } + + @PostMapping("/fishhatchrecr/fish/GetKendoListCust") + @Operation(summary = "(全过程)增殖站二级页面: 过程图-产卵和孵化") + public ResponseResult getFishhatchrecrFishKendoListCust( + @Parameter(description = "类型:1-鱼卵数量,2-出苗数量") @RequestParam("type") Integer type, + @RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getFishhatchrecrFishKendoListCust(type, dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java new file mode 100644 index 00000000..9e767b51 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java @@ -0,0 +1,17 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +@Data +public class FishhatchrecRVo { + + private String tm; + + private String ftp; + + private String ftpName; + + private String eggcount; + + private String outcount; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java new file mode 100644 index 00000000..9093d280 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java @@ -0,0 +1,52 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class HeadColunmsVo { + + private String dataIndex; + + private String title; + + private Boolean visible = true; + + private String key; + + private String unit; + + private boolean merge; + + private String dataType; + + private String dataFormat; + + private List children; + + public HeadColunmsVo(String title, String dataIndex) { + this.title = title; + this.dataIndex = dataIndex; + } + + public HeadColunmsVo(String dataIndex, String title, Boolean visible, String key, boolean merge, List children) { + this.dataIndex = dataIndex; + this.title = title; + this.visible = visible; + this.key = key; + this.merge = merge; + this.children = children; + } + + public HeadColunmsVo setDataType(String dataType) { + this.dataType = dataType; + return this; + } + + public HeadColunmsVo setDataFormat(String dataFormat) { + this.dataFormat = dataFormat; + return this; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java new file mode 100644 index 00000000..5bd4141b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java @@ -0,0 +1,27 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class TableVo { + + private List columns; + + private Object dataSource; + + private Long total; + + private Integer wtDeviceType; + + public TableVo() { + } + + public TableVo(List dataSource, Long total) { + this.dataSource = dataSource; + if (total != null) { + this.total = total; + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java index 1bada486..b9fde95c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java @@ -16,6 +16,7 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbStInfoResultVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.YearRpStatisticsVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationOverviewSecondVo; +import com.yfd.platform.qgc_env.fb.entity.vo.TableVo; import java.util.List; import java.util.Map; @@ -57,4 +58,6 @@ public interface FbStationService { DataSourceResult getOverviewSecond(DataSourceRequest dataSourceRequest); DataSourceResult getQgcOverviewSecond(DataSourceRequest dataSourceRequest); + + DataSourceResult getFishhatchrecrFishKendoListCust(Integer type, DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java index a3e50842..dff8e149 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java @@ -30,6 +30,9 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbStInfoResultVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationOverviewSecondVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsRawVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FishhatchrecRVo; +import com.yfd.platform.qgc_env.fb.entity.vo.HeadColunmsVo; +import com.yfd.platform.qgc_env.fb.entity.vo.TableVo; import com.yfd.platform.qgc_env.fb.entity.vo.YearRpStatisticsVo; import com.yfd.platform.qgc_env.fb.service.FbStationService; import com.yfd.platform.utils.QgcQueryWrapperUtil; @@ -4103,4 +4106,234 @@ public class FbStationServiceImpl implements FbStationService { } values.add(text); } + + @Override + public DataSourceResult getFishhatchrecrFishKendoListCust(Integer type, DataSourceRequest dataSourceRequest) { + DataSourceResult dataSourceResult = new DataSourceResult<>(); + String unit = type == 1 ? "(万粒)" : "(万尾)"; + + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT tm, ") + .append("LISTAGG(TO_CHAR(ftp), ',') WITHIN GROUP (ORDER BY ftp) AS ftp, ") + .append("LISTAGG(TO_CHAR(NAME), ',') WITHIN GROUP (ORDER BY ftp) AS ftpName, ") + .append("LISTAGG(eggcount, ',') WITHIN GROUP (ORDER BY ftp) AS eggcount, ") + .append("LISTAGG(outcount, ',') WITHIN GROUP (ORDER BY ftp) AS outcount ") + .append("FROM (") + .append("SELECT ") + .append("TO_CHAR(tm, 'YYYY-MM') AS tm, ftp, ") + .append("CASE WHEN NAME IS NULL THEN TO_NCHAR(ftp) ELSE NAME END AS NAME, ") + .append("CASE WHEN SUM(eggcount) IS NULL THEN '-' ELSE RTRIM(TO_CHAR(SUM(eggcount), 'FM999999999999990.99'), '.') END AS eggcount, ") + .append("CASE WHEN SUM(outcount) IS NULL THEN '-' ELSE RTRIM(TO_CHAR(SUM(outcount), 'FM999999999999990.99'), '.') END AS outcount ") + .append("FROM (") + .append("SELECT ") + .append("t.tm, ") + .append("CASE WHEN fishViewZy.ZY_FISH_ID IS NULL THEN t.ftp ELSE fishViewZy.ZY_FISH_ID END AS ftp, ") + .append("CASE WHEN fishViewZy.NAME IS NULL THEN fishViewRv.NAME ELSE fishViewZy.NAME END AS NAME, ") + .append("t.eggcount, ") + .append("t.outcount ") + .append("FROM SD_FBFISHHATCHREC_R t ") + .append("LEFT JOIN SD_FBRD_B_H fb ON t.stcd = fb.STCD ") + .append("LEFT JOIN V_SD_FISHDICTORY_B fishViewRv ON t.FTP = fishViewRv.FISH_ID AND fb.HBRVCD = fishViewRv.RVCD ") + .append("LEFT JOIN V_SD_FISHDICTORY_B fishViewZy ON t.FTP = fishViewZy.FISH_ID AND fishViewZy.RVCD = 'ZY' ") + .append("WHERE NVL(t.IS_DELETED, 0) = 0 "); + + appendFishhatchrecrFishFilterConditions(sql, dataSourceRequest, paramMap); + + sql.append(") GROUP BY TO_CHAR(tm, 'YYYY-MM'), ftp, NAME ") + .append(") GROUP BY tm ") + .append("ORDER BY tm DESC "); + + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, FishhatchrecRVo.class + ); + + long total = page != null ? page.getTotal() : list.size(); + TableVo tableVo = buildFishhatchrecrFishTableVo(list, total, type, unit); + dataSourceResult.setData(Collections.singletonList(tableVo)); + dataSourceResult.setTotal(total); + dataSourceResult.setAggregates(new HashMap<>()); + return dataSourceResult; + } + + private void appendFishhatchrecrFishFilterConditions(StringBuilder sql, + DataSourceRequest dataSourceRequest, + Map paramMap) { + if (dataSourceRequest == null || dataSourceRequest.getFilter() == null) { + return; + } + String filterSql = buildFishhatchrecrFishFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + } + + private String buildFishhatchrecrFishFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildFishhatchrecrFishLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFishhatchrecrFishFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildFishhatchrecrFishLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + String column = mapFishhatchrecrFishColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("in".equals(operator)) { + List values = normalizeQgcBsmfRValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "hatchFishP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add("#{map." + key + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "hatchFishP" + indexHolder[0]++; + Object normalizedValue = normalizeFishhatchrecrFishValue(field, value); + return switch (operator) { + case "eq" -> { + paramMap.put(key, normalizedValue); + yield column + " = #{map." + key + "}"; + } + case "neq" -> { + paramMap.put(key, normalizedValue); + yield column + " <> #{map." + key + "}"; + } + case "contains" -> { + paramMap.put(key, "%" + normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + normalizedValue); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, normalizedValue); + yield column + " > #{map." + key + "}"; + } + case "gte" -> { + paramMap.put(key, normalizedValue); + yield column + " >= #{map." + key + "}"; + } + case "lt" -> { + paramMap.put(key, normalizedValue); + yield column + " < #{map." + key + "}"; + } + case "lte" -> { + paramMap.put(key, normalizedValue); + yield column + " <= #{map." + key + "}"; + } + default -> ""; + }; + } + + private String mapFishhatchrecrFishColumn(String field) { + return switch (field) { + case "stcd" -> "t.STCD"; + case "ftp" -> "t.FTP"; + case "fishsrc" -> "t.FISHSRC"; + case "tm" -> "t.TM"; + case "rstcd" -> "fb.RSTCD"; + case "baseId" -> "fb.BASE_ID"; + case "hbrvcd" -> "fb.HBRVCD"; + default -> ""; + }; + } + + private Object normalizeFishhatchrecrFishValue(String field, Object value) { + if (value == null) { + return null; + } + if ("tm".equalsIgnoreCase(field) && value instanceof String text) { + return parseDateTimeSafely(text); + } + return value; + } + + private TableVo buildFishhatchrecrFishTableVo(List list, long total, Integer type, String unit) { + TableVo tableVo = new TableVo(); + List> resultData = new ArrayList<>(); + List columns = new ArrayList<>(); + Map fishMap = new LinkedHashMap<>(); + + if (CollUtil.isNotEmpty(list)) { + for (FishhatchrecRVo vo : list) { + Map rowMap = new LinkedHashMap<>(); + rowMap.put("tm", vo.getTm()); + + List ftpList = splitCsv(vo.getFtp()); + List ftpNameList = splitCsv(vo.getFtpName()); + List eggCountList = splitCsv(vo.getEggcount()); + List outCountList = splitCsv(vo.getOutcount()); + + int size = Math.min(ftpList.size(), Math.min(ftpNameList.size(), + Math.min(eggCountList.size(), outCountList.size()))); + + for (int i = 0; i < size; i++) { + String ftp = ftpList.get(i); + String ftpName = ftpNameList.get(i); + String value = type == 1 ? eggCountList.get(i) : outCountList.get(i); + rowMap.put(ftp, "-".equals(value) ? null : value); + fishMap.putIfAbsent(ftp, ftpName); + } + resultData.add(rowMap); + } + } + + columns.add(new HeadColunmsVo("tm", "时间", true, "tm", false, new ArrayList<>()) + .setDataType("date") + .setDataFormat("yyyy-MM")); + for (Map.Entry entry : fishMap.entrySet()) { + columns.add(new HeadColunmsVo(entry.getKey(), entry.getValue() + unit, true, entry.getKey(), false, new ArrayList<>())); + } + + tableVo.setColumns(columns); + tableVo.setDataSource(resultData); + tableVo.setTotal(total); + return tableVo; + } } From d964cf6d2017eb99e1a92691bfdfbc0f13c5f4cf Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 13:37:28 +0800 Subject: [PATCH 38/65] =?UTF-8?q?feat:=20(=E5=85=A8=E8=BF=87=E7=A8=8B)?= =?UTF-8?q?=E5=A2=9E=E6=AE=96=E7=AB=99=E4=BA=8C=E7=BA=A7=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?:=20=E8=BF=87=E7=A8=8B=E5=9B=BE-=E9=B1=BC=E8=8B=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/controller/FbStationController.java | 6 + .../qgc_env/fb/entity/vo/FishbreedRVo.java | 15 ++ .../qgc_env/fb/service/FbStationService.java | 2 + .../fb/service/impl/FbStationServiceImpl.java | 236 ++++++++++++++++++ 4 files changed, 259 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishbreedRVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java index f0d90c09..7fa6c42f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java @@ -140,4 +140,10 @@ public class FbStationController { @RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(fbStationService.getFishhatchrecrFishKendoListCust(type, dataSourceRequest)); } + + @PostMapping("/fishbreedr/fish/GetKendoListCust") + @Operation(summary = "(全过程)增殖站二级页面: 过程图-鱼苗") + public ResponseResult getFishbreedrFishKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getFishbreedrFishKendoListCust(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishbreedRVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishbreedRVo.java new file mode 100644 index 00000000..1d184777 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishbreedRVo.java @@ -0,0 +1,15 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +@Data +public class FishbreedRVo { + + private String tm; + + private String ftp; + + private String ftpName; + + private String counts; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java index b9fde95c..77cd39aa 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java @@ -60,4 +60,6 @@ public interface FbStationService { DataSourceResult getQgcOverviewSecond(DataSourceRequest dataSourceRequest); DataSourceResult getFishhatchrecrFishKendoListCust(Integer type, DataSourceRequest dataSourceRequest); + + DataSourceResult getFishbreedrFishKendoListCust(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java index dff8e149..e1fa5911 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java @@ -30,6 +30,7 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbStInfoResultVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationOverviewSecondVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsRawVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FishbreedRVo; import com.yfd.platform.qgc_env.fb.entity.vo.FishhatchrecRVo; import com.yfd.platform.qgc_env.fb.entity.vo.HeadColunmsVo; import com.yfd.platform.qgc_env.fb.entity.vo.TableVo; @@ -4336,4 +4337,239 @@ public class FbStationServiceImpl implements FbStationService { tableVo.setTotal(total); return tableVo; } + + @Override + public DataSourceResult getFishbreedrFishKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceResult dataSourceResult = new DataSourceResult<>(); + + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT tm,\n") + .append("LISTAGG(TO_CHAR(ftp), ',') WITHIN GROUP (ORDER BY ftp) AS ftp,\n") + .append("LISTAGG(TO_CHAR(NAME), ',') WITHIN GROUP (ORDER BY ftp) AS ftpName,\n") + .append("LISTAGG(counts, ',') WITHIN GROUP (ORDER BY ftp) AS counts\n") + .append("FROM (\n") + .append("SELECT \n") + .append("to_CHAR(tm,'YYYY-MM') AS tm, ftp, CASE WHEN NAME IS NULL THEN TO_NCHAR(ftp) ELSE NAME END AS NAME, CASE WHEN SUM(counts) IS NULL THEN '-' ELSE TO_CHAR(SUM(counts)) END AS counts\n") + .append("FROM (\n") + .append("SELECT\n") + .append("\ttm,\n") + .append("\tCASE WHEN ZY_FISH_ID IS NULL THEN ftp ELSE ZY_FISH_ID END AS ftp,\n") + .append("\tCASE WHEN NAME IS NULL THEN TO_NCHAR(ftp) ELSE NAME END AS NAME,\n") + .append("\tcounts\n") + .append("FROM\n") + .append("\t(\n") + .append("\tSELECT\n") + .append("\t\tstcd,\n") + .append("\t\tftp AS ftp,\n") + .append("\t\tcounts AS counts,\n") + .append("\t\ttm AS tm\n") + .append("\tFROM\n") + .append("\t\tSD_FBFISHBREED_R\n") + .append("\tWHERE\n") + .append("\t\tNVL(is_deleted, 0) = 0 "); + + appendFishbreedrFishFilterConditions(sql, dataSourceRequest, paramMap); + + sql.append(") t\n") + .append("LEFT JOIN SD_FBRD_B_H s ON\n") + .append("\tt.stcd = s.STCD\n") + .append("LEFT JOIN V_SD_FISHDICTORY_B f ON\n") + .append("\tt.FTP = f.FISH_ID\n") + .append("\tAND (s.HBRVCD = f.RVCD\n") + .append("\t\tOR f.RVCD = 'ZY')\n") + .append(") GROUP BY to_CHAR(tm,'YYYY-MM'), ftp, NAME\n") + .append(") GROUP BY tm\n") + .append("ORDER BY TM DESC"); + + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, FishbreedRVo.class + ); + + long total = page != null ? page.getTotal() : list.size(); + TableVo tableVo = buildFishbreedrFishTableVo(list, total); + dataSourceResult.setData(Collections.singletonList(tableVo)); + dataSourceResult.setTotal(total); + dataSourceResult.setAggregates(new HashMap<>()); + return dataSourceResult; + } + + private void appendFishbreedrFishFilterConditions(StringBuilder sql, + DataSourceRequest dataSourceRequest, + Map paramMap) { + if (dataSourceRequest == null || dataSourceRequest.getFilter() == null) { + return; + } + String filterSql = buildFishbreedrFishFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + } + + private String buildFishbreedrFishFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildFishbreedrFishLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFishbreedrFishFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildFishbreedrFishLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + String column = mapFishbreedrFishColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("in".equals(operator)) { + List values = normalizeQgcBsmfRValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "breedFishP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add("#{map." + key + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "breedFishP" + indexHolder[0]++; + Object normalizedValue = normalizeFishbreedrFishValue(field, value); + return switch (operator) { + case "eq" -> { + paramMap.put(key, normalizedValue); + yield column + " = #{map." + key + "}"; + } + case "neq" -> { + paramMap.put(key, normalizedValue); + yield column + " <> #{map." + key + "}"; + } + case "contains" -> { + paramMap.put(key, "%" + normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + normalizedValue); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, normalizedValue); + yield column + " > #{map." + key + "}"; + } + case "gte" -> { + paramMap.put(key, normalizedValue); + yield column + " >= #{map." + key + "}"; + } + case "lt" -> { + paramMap.put(key, normalizedValue); + yield column + " < #{map." + key + "}"; + } + case "lte" -> { + paramMap.put(key, normalizedValue); + yield column + " <= #{map." + key + "}"; + } + default -> ""; + }; + } + + private String mapFishbreedrFishColumn(String field) { + return switch (field) { + case "stcd" -> "t.STCD"; + case "ftp" -> "t.FTP"; + case "counts" -> "t.COUNTS"; + case "tm" -> "t.TM"; + case "rstcd" -> "s.RSTCD"; + case "baseId" -> "s.BASE_ID"; + case "hbrvcd" -> "s.HBRVCD"; + default -> ""; + }; + } + + private Object normalizeFishbreedrFishValue(String field, Object value) { + if (value == null) { + return null; + } + if ("tm".equalsIgnoreCase(field) && value instanceof String text) { + return parseDateTimeSafely(text); + } + return value; + } + + private TableVo buildFishbreedrFishTableVo(List list, long total) { + TableVo tableVo = new TableVo(); + List> resultData = new ArrayList<>(); + List columns = new ArrayList<>(); + Map fishMap = new LinkedHashMap<>(); + + if (CollUtil.isNotEmpty(list)) { + for (FishbreedRVo vo : list) { + Map rowMap = new LinkedHashMap<>(); + rowMap.put("tm", vo.getTm()); + + List ftpList = splitCsv(vo.getFtp()); + List ftpNameList = splitCsv(vo.getFtpName()); + List countsList = splitCsv(vo.getCounts()); + + int size = Math.min(ftpList.size(), Math.min(ftpNameList.size(), countsList.size())); + + for (int i = 0; i < size; i++) { + String ftp = ftpList.get(i); + String ftpName = ftpNameList.get(i); + String countStr = countsList.get(i); + rowMap.put(ftp, "-".equals(countStr) ? null : countStr); + fishMap.putIfAbsent(ftp, ftpName); + } + resultData.add(rowMap); + } + } + + columns.add(new HeadColunmsVo("tm", "时间", true, "tm", false, new ArrayList<>()) + .setDataType("date") + .setDataFormat("yyyy-MM")); + for (Map.Entry entry : fishMap.entrySet()) { + columns.add(new HeadColunmsVo(entry.getKey(), entry.getValue() + "(尾)", true, entry.getKey(), false, new ArrayList<>())); + } + + tableVo.setColumns(columns); + tableVo.setDataSource(resultData); + tableVo.setTotal(total); + return tableVo; + } } From 04614d9d890f00e8a3dffbd14005084c0272e075 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 14:28:34 +0800 Subject: [PATCH 39/65] =?UTF-8?q?feat:=20=E5=8A=A8=E7=89=A9=E6=95=91?= =?UTF-8?q?=E5=8A=A9=E7=AB=99=E6=95=B0=E6=8D=AE=E5=B9=B4=E4=BB=BD=E5=88=97?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/service/impl/FbStationServiceImpl.java | 12 ++--- .../controller/VapConstructionController.java | 6 +++ .../vap/service/VpConstructionService.java | 2 + .../impl/VpConstructionServiceImpl.java | 47 +++++++++++++++++++ .../wte/controller/WeFishController.java | 2 +- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java index e1fa5911..d3df7885 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java @@ -4353,10 +4353,10 @@ public class FbStationServiceImpl implements FbStationService { .append("to_CHAR(tm,'YYYY-MM') AS tm, ftp, CASE WHEN NAME IS NULL THEN TO_NCHAR(ftp) ELSE NAME END AS NAME, CASE WHEN SUM(counts) IS NULL THEN '-' ELSE TO_CHAR(SUM(counts)) END AS counts\n") .append("FROM (\n") .append("SELECT\n") - .append("\ttm,\n") - .append("\tCASE WHEN ZY_FISH_ID IS NULL THEN ftp ELSE ZY_FISH_ID END AS ftp,\n") - .append("\tCASE WHEN NAME IS NULL THEN TO_NCHAR(ftp) ELSE NAME END AS NAME,\n") - .append("\tcounts\n") + .append("\tt.tm,\n") + .append("\tCASE WHEN f.ZY_FISH_ID IS NULL THEN t.ftp ELSE f.ZY_FISH_ID END AS ftp,\n") + .append("\tCASE WHEN f.NAME IS NULL THEN TO_NCHAR(t.ftp) ELSE f.NAME END AS NAME,\n") + .append("\tt.counts\n") .append("FROM\n") .append("\t(\n") .append("\tSELECT\n") @@ -4511,10 +4511,10 @@ public class FbStationServiceImpl implements FbStationService { private String mapFishbreedrFishColumn(String field) { return switch (field) { - case "stcd" -> "t.STCD"; + case "stcd" -> "STCD"; case "ftp" -> "t.FTP"; case "counts" -> "t.COUNTS"; - case "tm" -> "t.TM"; + case "tm" -> "TM"; case "rstcd" -> "s.RSTCD"; case "baseId" -> "s.BASE_ID"; case "hbrvcd" -> "s.HBRVCD"; diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java index ffa9a01e..9941bbe0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java @@ -64,4 +64,10 @@ public class VapConstructionController { public ResponseResult getVarKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(vpConstructionService.processVarKendoList(dataSourceRequest)); } + + @PostMapping("/var/year/GetKendoListCust") + @Operation(summary = "动物救助站数据年份列表") + public ResponseResult getVarYearKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(vpConstructionService.getVarYearList(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java index 28de636f..350b45c5 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java @@ -23,4 +23,6 @@ public interface VpConstructionService { DataSourceResult processVacKendoList(DataSourceRequest dataSourceRequest); DataSourceResult processVarKendoList(DataSourceRequest dataSourceRequest); + + DataSourceResult getVarYearList(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java index fe46774a..ba529d7b 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java @@ -1814,4 +1814,51 @@ public class VpConstructionServiceImpl implements VpConstructionService { } return " ORDER BY " + String.join(", ", orderItems); } + + @Override + public DataSourceResult getVarYearList(DataSourceRequest dataSourceRequest) { + DataSourceResult dataSourceResult = new DataSourceResult<>(); + DataSourceLoadOptionsBase loadOptionsBase = dataSourceRequest.toDevRequest(); + String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptionsBase, "baseId"); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptionsBase, "stcd"); + String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptionsBase, "rstcd"); + + StringBuilder sql = new StringBuilder("SELECT TO_CHAR(r.TM, 'YYYY') year FROM SD_VA_R r " + + "LEFT JOIN SD_VABASIC_B svb ON r.TETP = svb.ID " + + "LEFT JOIN SD_VA_B_H a ON a.STCD = r.STCD WHERE NVL(r.IS_DELETED, 0) = 0 "); + + if (StrUtil.isNotBlank(baseId)) { + sql.append(" AND a.BASE_ID = #{map.baseId} "); + } + if (StrUtil.isNotBlank(stcd)) { + sql.append(" AND a.STCD = #{map.stcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + sql.append(" AND a.RSTCD = #{map.rstcd} "); + } + sql.append(" GROUP BY TO_CHAR(r.TM, 'YYYY') ORDER BY TO_CHAR(r.TM, 'YYYY') DESC "); + + Map paramMap = new HashMap<>(); + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("baseId", baseId); + } + if (StrUtil.isNotBlank(stcd)) { + paramMap.put("stcd", stcd); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("rstcd", rstcd); + } + + Page page = KendoUtil.getPage(dataSourceRequest); + List> list = microservicDynamicSQLMapper.pageAllList(page, sql.toString(), paramMap); + List yList = new ArrayList<>(); + for (Map it : list) { + if (it.get("YEAR") != null && StrUtil.isNotBlank(it.get("YEAR").toString())) { + yList.add(it.get("YEAR").toString()); + } + } + dataSourceResult.setData(yList); + dataSourceResult.setTotal(page != null ? page.getTotal() : (long) yList.size()); + return dataSourceResult; + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 88fa9eb2..a6d730b4 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -156,7 +156,7 @@ public class WeFishController { return ResponseResult.successData(weFishService.getTeSpecialAnimalList(dataSourceRequest)); } - @GetMapping("/getWeDefaultData") + @GetMapping("/we/wer/getWeDefaultData") @Operation(summary = "查询水生生态断面的年份及是否鱼类,水温,水质,流速数据") public ResponseResult getWeDefaultData(@RequestParam("stcd") String stcd) { return ResponseResult.successData(weFishService.getWeDefaultData(stcd)); From 78c93eeb02091f7f898df6df578432603772033a Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 14:52:28 +0800 Subject: [PATCH 40/65] =?UTF-8?q?feat:=20=E6=9F=A5=E8=AF=A2=E6=B0=B4?= =?UTF-8?q?=E7=94=9F=E7=94=9F=E6=80=81=E6=96=AD=E9=9D=A2=E6=9C=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E5=B9=B4=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/MicroservicDynamicSQLMapper.java | 16 ++++++++++++++ .../wte/controller/WeFishController.java | 6 +++++ .../qgc_env/wte/service/WeFishService.java | 2 ++ .../wte/service/impl/WeFishServiceImpl.java | 22 +++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java b/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java index 59e435bd..319f2ffd 100644 --- a/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java +++ b/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java @@ -5,6 +5,8 @@ import cn.hutool.core.bean.copier.CopyOptions; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Mapper; + +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.ArrayList; @@ -49,6 +51,20 @@ public interface MicroservicDynamicSQLMapper { return convertList(allList, resultType); } + default List getSingleColumnList(String sql, Map paramMap) { + List> rows = getAllList(sql, paramMap); + if (rows == null || rows.isEmpty()) { + return Collections.emptyList(); + } + List result = new ArrayList<>(rows.size()); + for (Map row : rows) { + // 获取第一个值并转为字符串 + Object firstValue = row.values().iterator().next(); + result.add(firstValue == null ? null : firstValue.toString()); + } + return result; + } + @Select({"select count(1) count from ${sql} and ${ew.sqlSegment}"}) Integer count(@Param("select") String select, @Param("sql") String sql, @Param("ew") QueryWrapper queryWrapper); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index a6d730b4..b3d75380 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -161,4 +161,10 @@ public class WeFishController { public ResponseResult getWeDefaultData(@RequestParam("stcd") String stcd) { return ResponseResult.successData(weFishService.getWeDefaultData(stcd)); } + + @GetMapping("/we/wer/getWeYr") + @Operation(summary = "查询水生生态断面有数据的年份") + public ResponseResult getWeYr(@RequestParam("stcd") String stcd) { + return ResponseResult.successData(weFishService.getWeYr(stcd)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 7bb90c5b..d156e5ad 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -56,4 +56,6 @@ public interface WeFishService { DataSourceResult getTeSpecialAnimalList(DataSourceRequest dataSourceRequest); List getWeDefaultData(String stcd); + + DataSourceResult getWeYr(String stcd); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index f19fb5ec..cac93758 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -1154,6 +1154,28 @@ public class WeFishServiceImpl implements WeFishService { return oneBySqlWithResultType; } + @Override + public DataSourceResult getWeYr(String stcd) { + DataSourceResult dataSourceResult = new DataSourceResult(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT TO_CHAR(TM, 'yyyy') AS yr FROM SD_WE_R ") + .append("WHERE NVL(IS_DELETED, 0) = 0 AND NVL(STATUS, 1) = 1 "); + if (StrUtil.isNotBlank(stcd)) { + sql.append("AND STCD = #{map.stcd} "); + } + sql.append("GROUP BY TO_CHAR(TM, 'yyyy') ") + .append("ORDER BY TO_CHAR(TM, 'yyyy') DESC"); + + Map paramMap = new HashMap<>(); + if (StrUtil.isNotBlank(stcd)) { + paramMap.put("stcd", stcd); + } + List yrList = microservicDynamicSQLMapper.getSingleColumnList(sql.toString(), paramMap); + dataSourceResult.setData(yrList); + dataSourceResult.setTotal(yrList == null ? 0L : yrList.size()); + return dataSourceResult; + } + private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; From a8541ad11e2f12882fb63d5b73709b3af9a6fcad Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 15:19:00 +0800 Subject: [PATCH 41/65] =?UTF-8?q?feat:=20=E7=8F=8D=E7=A8=80=E6=A4=8D?= =?UTF-8?q?=E7=89=A9=E5=9B=AD=E6=95=B0=E6=8D=AE=E5=B9=B4=E4=BB=BD=E5=88=97?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/VapConstructionController.java | 6 +++ .../vap/service/VpConstructionService.java | 2 + .../impl/VpConstructionServiceImpl.java | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java index 9941bbe0..ef34b630 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java @@ -70,4 +70,10 @@ public class VapConstructionController { public ResponseResult getVarYearKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(vpConstructionService.getVarYearList(dataSourceRequest)); } + + @PostMapping("/vpr/year/GetKendoListCust") + @Operation(summary = "珍稀植物园数据年份列表") + public ResponseResult getVprYearKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(vpConstructionService.getVprYearList(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java index 350b45c5..0a362f81 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java @@ -25,4 +25,6 @@ public interface VpConstructionService { DataSourceResult processVarKendoList(DataSourceRequest dataSourceRequest); DataSourceResult getVarYearList(DataSourceRequest dataSourceRequest); + + DataSourceResult getVprYearList(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java index ba529d7b..e0bc4ccf 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java @@ -1861,4 +1861,51 @@ public class VpConstructionServiceImpl implements VpConstructionService { dataSourceResult.setTotal(page != null ? page.getTotal() : (long) yList.size()); return dataSourceResult; } + + @Override + public DataSourceResult getVprYearList(DataSourceRequest dataSourceRequest) { + DataSourceResult dataSourceResult = new DataSourceResult<>(); + DataSourceLoadOptionsBase loadOptionsBase = dataSourceRequest.toDevRequest(); + String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptionsBase, "baseId"); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptionsBase, "stcd"); + String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptionsBase, "rstcd"); + + StringBuilder sql = new StringBuilder("SELECT TO_CHAR(r.TM, 'YYYY') year FROM SD_VP_R r " + + "LEFT JOIN SD_VPBASIC_B svb ON r.PLANT_ID = svb.ID " + + "LEFT JOIN SD_VP_B_H a ON a.STCD = r.STCD WHERE NVL(r.IS_DELETED, 0) = 0 "); + + if (StrUtil.isNotBlank(baseId)) { + sql.append(" AND a.BASE_ID = #{map.baseId} "); + } + if (StrUtil.isNotBlank(stcd)) { + sql.append(" AND a.STCD = #{map.stcd} "); + } + if (StrUtil.isNotBlank(rstcd)) { + sql.append(" AND a.RSTCD = #{map.rstcd} "); + } + sql.append(" GROUP BY TO_CHAR(r.TM, 'YYYY') ORDER BY TO_CHAR(r.TM, 'YYYY') DESC "); + + Map paramMap = new HashMap<>(); + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("baseId", baseId); + } + if (StrUtil.isNotBlank(stcd)) { + paramMap.put("stcd", stcd); + } + if (StrUtil.isNotBlank(rstcd)) { + paramMap.put("rstcd", rstcd); + } + + Page page = KendoUtil.getPage(dataSourceRequest); + List> list = microservicDynamicSQLMapper.pageAllList(page, sql.toString(), paramMap); + List yList = new ArrayList<>(); + for (Map it : list) { + if (it.get("YEAR") != null && StrUtil.isNotBlank(it.get("YEAR").toString())) { + yList.add(it.get("YEAR").toString()); + } + } + dataSourceResult.setData(yList); + dataSourceResult.setTotal(page != null ? page.getTotal() : (long) yList.size()); + return dataSourceResult; + } } From 511745c1d03bf245e7158295e9d0d36107712551 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 16:36:08 +0800 Subject: [PATCH 42/65] =?UTF-8?q?feat:=20=E6=B0=B4=E7=94=9F=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5-=E6=B0=B4=E6=B8=A9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/entity/vo/WeWtVo.java | 18 ++ .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 203 ++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWtVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index b3d75380..4dcbfecd 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -167,4 +167,10 @@ public class WeFishController { public ResponseResult getWeYr(@RequestParam("stcd") String stcd) { return ResponseResult.successData(weFishService.getWeYr(stcd)); } + + @PostMapping("/we/wewtr/GetKendoListCust") + @Operation(summary = "水生生态调查-水温数据列表") + public ResponseResult getWeWtR(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeWtR(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWtVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWtVo.java new file mode 100644 index 00000000..70bffdb7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWtVo.java @@ -0,0 +1,18 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class WeWtVo { + + private String dcpc; + + private String stcd; + + private Date tm; + + private BigDecimal wt; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index d156e5ad..bbedae64 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -58,4 +58,6 @@ public interface WeFishService { List getWeDefaultData(String stcd); DataSourceResult getWeYr(String stcd); + + DataSourceResult getWeWtR(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index cac93758..89db2a0f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -12,6 +12,7 @@ import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.qgc_env.wte.entity.vo.*; import com.yfd.platform.qgc_env.wte.service.WeFishService; +import com.yfd.platform.utils.KendoUtil; import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -1176,6 +1177,208 @@ public class WeFishServiceImpl implements WeFishService { return dataSourceResult; } + @Override + public DataSourceResult getWeWtR(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.DCPC, t.STCD, t1.WT AS wt, t.TM FROM SD_WE_R t ") + .append("INNER JOIN SD_WEWT_R t1 ON t.ID = t1.WER_ID ") + .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t.STATUS, 1) = 1 AND NVL(t1.IS_DELETED, 0) = 0 "); + + String filterSql = buildWeWtFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append("AND ").append(filterSql).append(" "); + } + + DataSourceResult result = new DataSourceResult<>(); + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + String groupBy = KendoUtil.getGroupBy(dataSourceRequest); + if (StrUtil.isNotBlank(groupBy)) { + List groupFields = new ArrayList<>(); + for (GroupingInfo item : groupInfos) { + if (item != null && StrUtil.isNotBlank(item.getSelector())) { + groupFields.add(item.getSelector()); + } + } + StringBuilder temp = new StringBuilder(); + temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); + if (groupInfos.length > 1) { + temp.append("count"); + } else { + temp.append("count_").append(String.join("_", groupFields)); + } + String groupedSql = temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); + List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + } + + sql.append(buildWeWtOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, WeWtVo.class); + + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildWeWtFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildWeWtLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildWeWtFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildWeWtLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapWeWtColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeWeFishQgcValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + boolean isDateField = "t.tm".equals(column); + for (Object value : values) { + String paramKey = "weWtParam" + indexHolder[0]++; + paramMap.put(paramKey, value); + if (isDateField) { + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); + } else { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); + } + } else { + placeholders.add("#{map." + paramKey + "}"); + } + } + String prefix = "ni".equals(operator) ? "NOT " : ""; + return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; + } + String paramKey = "weWtParam" + indexHolder[0]++; + paramMap.put(paramKey, filter.getValue()); + boolean isDateField = "t.tm".equals(column); + String valueExpr; + if (isDateField) { + String text = String.valueOf(filter.getValue()).trim(); + if (text.length() <= 10) { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } else { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + } else { + valueExpr = "#{map." + paramKey + "}"; + } + return switch (operator) { + case "lt", "lessthan" -> column + " < " + valueExpr; + case "lte", "lessthanorequals" -> column + " <= " + valueExpr; + case "gt", "greaterthan" -> column + " > " + valueExpr; + case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; + case "ne", "notequals" -> column + " <> " + valueExpr; + case "contains", "doesnotcontain", "startswith", "endswith" -> { + String pattern = switch (operator) { + case "contains" -> "%#{map." + paramKey + "}%"; + case "doesnotcontain" -> "%#{map." + paramKey + "}%"; + case "startswith" -> "#{map." + paramKey + "}%"; + case "endswith" -> "%#{map." + paramKey + "}"; + default -> "%#{map." + paramKey + "}%"; + }; + String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; + yield column + " " + likePrefix + "LIKE " + pattern; + } + default -> column + " = " + valueExpr; + }; + } + + private String mapWeWtColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field.toLowerCase()) { + case "dcpc" -> "t.dcpc"; + case "stcd" -> "t.stcd"; + case "wt" -> "t1.wt"; + case "tm" -> "t.tm"; + default -> null; + }; + } + + private String buildWeWtOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY t.tm DESC NULLS LAST, t.stcd ASC"; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapWeWtColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return " ORDER BY t.tm DESC NULLS LAST, t.stcd ASC"; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; From 2b0709036cb7d62ef488c1dd3012632fb213f702 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 16:56:34 +0800 Subject: [PATCH 43/65] =?UTF-8?q?feat:=20=E6=B0=B4=E7=94=9F=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5-=E6=B0=B4=E8=B4=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/entity/vo/WeWqVo.java | 51 ++++ .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 247 +++++++++++++++++- 4 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWqVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index 4dcbfecd..eb3f9084 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -173,4 +173,10 @@ public class WeFishController { public ResponseResult getWeWtR(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(weFishService.getWeWtR(dataSourceRequest)); } + + @PostMapping("/we/wewqr/GetKendoListCust") + @Operation(summary = "水生生态调查-水质数据列表") + public ResponseResult getWeWqR(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeWqR(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWqVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWqVo.java new file mode 100644 index 00000000..6600e9c2 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeWqVo.java @@ -0,0 +1,51 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class WeWqVo { + private String stcd; + private String dcpc; + private String name; + private Date tm; + private BigDecimal ph; + private BigDecimal dox; + private BigDecimal codmn; + private BigDecimal codcr; + private BigDecimal bod5; + private BigDecimal nh3n; + private BigDecimal tp; + private BigDecimal tn; + private BigDecimal cu; + private BigDecimal zn; + private BigDecimal f; + private BigDecimal se; + private BigDecimal ars; + private BigDecimal hg; + private BigDecimal cd; + private BigDecimal cr6; + private BigDecimal pb; + private BigDecimal cn; + private BigDecimal vlph; + private BigDecimal oil; + private BigDecimal las; + private BigDecimal s2; + private BigDecimal fcg; + private BigDecimal cl; + private BigDecimal so4; + private BigDecimal no3; + private BigDecimal thrd; + private BigDecimal cond; + private BigDecimal fe; + private BigDecimal mn; + private BigDecimal al; + private BigDecimal chla; + private BigDecimal clarity; + private BigDecimal tu; + private BigDecimal cyano; + private String fid; + private Integer parameter; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index bbedae64..554ff54f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -60,4 +60,6 @@ public interface WeFishService { DataSourceResult getWeYr(String stcd); DataSourceResult getWeWtR(DataSourceRequest dataSourceRequest); + + DataSourceResult getWeWqR(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 89db2a0f..ec0c1ed3 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -1186,7 +1186,7 @@ public class WeFishServiceImpl implements WeFishService { StringBuilder sql = new StringBuilder(); sql.append("SELECT t.DCPC, t.STCD, t1.WT AS wt, t.TM FROM SD_WE_R t ") .append("INNER JOIN SD_WEWT_R t1 ON t.ID = t1.WER_ID ") - .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t.STATUS, 1) = 1 AND NVL(t1.IS_DELETED, 0) = 0 "); + .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t1.IS_DELETED, 0) = 0 "); String filterSql = buildWeWtFilterCondition( dataSourceRequest == null ? null : dataSourceRequest.getFilter(), @@ -1379,6 +1379,251 @@ public class WeFishServiceImpl implements WeFishService { return " ORDER BY " + String.join(", ", orderByParts); } + @Override + public DataSourceResult getWeWqR(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.DCPC, t.STCD, t1.TM, t1.NAME, t1.PH, t1.DOX, t1.CODMN, t1.CODCR, t1.BOD5, t1.NH3N ") + .append(", t1.TP, t1.TN, t1.CU, t1.ZN, t1.F, t1.SE, t1.ARS, t1.HG, t1.CD, t1.CR6, t1.PB, t1.CN, t1.VLPH, t1.OIL ") + .append(", t1.LAS, t1.S2, t1.FCG, t1.CL, t1.SO4, t1.NO3, t1.THRD, t1.COND, t1.FE, t1.MN, t1.AL, t1.CHLA ") + .append(", t1.CLARITY, t1.TU, t1.CYANO, t1.FID, t1.PARAMETER ") + .append("FROM SD_WE_R t ") + .append("INNER JOIN SD_WEWQ_R t1 ON t.ID = t1.WER_ID ") + .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t1.IS_DELETED, 0) = 0 "); + + String filterSql = buildWeWqFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append("AND ").append(filterSql).append(" "); + } + + DataSourceResult result = new DataSourceResult<>(); + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + String groupBy = KendoUtil.getGroupBy(dataSourceRequest); + if (StrUtil.isNotBlank(groupBy)) { + List groupFields = new ArrayList<>(); + for (GroupingInfo item : groupInfos) { + if (item != null && StrUtil.isNotBlank(item.getSelector())) { + groupFields.add(item.getSelector()); + } + } + StringBuilder temp = new StringBuilder(); + temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); + if (groupInfos.length > 1) { + temp.append("count"); + } else { + temp.append("count_").append(String.join("_", groupFields)); + } + String groupedSql = temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); + List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + } + + sql.append(buildWeWqOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, WeWqVo.class); + + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildWeWqFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + List conditions = new ArrayList<>(); + List filters = filter.getFilters(); + if (CollUtil.isNotEmpty(filters)) { + for (DataSourceRequest.FilterDescriptor child : filters) { + String condition = buildWeWqFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(condition)) { + conditions.add(condition); + } + } + } else { + String leafCondition = buildWeWqLeafCondition(filter, paramMap, indexHolder); + if (StrUtil.isNotBlank(leafCondition)) { + conditions.add(leafCondition); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return "(" + String.join(logic, conditions) + ")"; + } + + private String buildWeWqLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapWeWqColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeWeFishQgcValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + boolean isDateField = "t1.tm".equals(column); + for (Object value : values) { + String paramKey = "weWqParam" + indexHolder[0]++; + paramMap.put(paramKey, value); + if (isDateField) { + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); + } else { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); + } + } else { + placeholders.add("#{map." + paramKey + "}"); + } + } + String prefix = "ni".equals(operator) ? "NOT " : ""; + return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; + } + String paramKey = "weWqParam" + indexHolder[0]++; + paramMap.put(paramKey, filter.getValue()); + boolean isDateField = "t1.tm".equals(column); + String valueExpr; + if (isDateField) { + String text = String.valueOf(filter.getValue()).trim(); + if (text.length() <= 10) { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } else { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + } else { + valueExpr = "#{map." + paramKey + "}"; + } + return switch (operator) { + case "lt", "lessthan" -> column + " < " + valueExpr; + case "lte", "lessthanorequals" -> column + " <= " + valueExpr; + case "gt", "greaterthan" -> column + " > " + valueExpr; + case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; + case "ne", "notequals" -> column + " <> " + valueExpr; + case "contains", "doesnotcontain", "startswith", "endswith" -> { + String pattern = switch (operator) { + case "contains" -> "%#{map." + paramKey + "}%"; + case "doesnotcontain" -> "%#{map." + paramKey + "}%"; + case "startswith" -> "#{map." + paramKey + "}%"; + case "endswith" -> "%#{map." + paramKey + "}"; + default -> "%#{map." + paramKey + "}%"; + }; + String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; + yield column + " " + likePrefix + "LIKE " + pattern; + } + default -> column + " = " + valueExpr; + }; + } + + private String mapWeWqColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field.toLowerCase()) { + case "dcpc" -> "t.dcpc"; + case "stcd" -> "t.stcd"; + case "name" -> "t1.name"; + case "tm" -> "t1.tm"; + case "ph" -> "t1.ph"; + case "dox" -> "t1.dox"; + case "codmn" -> "t1.codmn"; + case "codcr" -> "t1.codcr"; + case "bod5" -> "t1.bod5"; + case "nh3n" -> "t1.nh3n"; + case "tp" -> "t1.tp"; + case "tn" -> "t1.tn"; + case "cu" -> "t1.cu"; + case "zn" -> "t1.zn"; + case "f" -> "t1.f"; + case "se" -> "t1.se"; + case "ars" -> "t1.ars"; + case "hg" -> "t1.hg"; + case "cd" -> "t1.cd"; + case "cr6" -> "t1.cr6"; + case "pb" -> "t1.pb"; + case "cn" -> "t1.cn"; + case "vlph" -> "t1.vlph"; + case "oil" -> "t1.oil"; + case "las" -> "t1.las"; + case "s2" -> "t1.s2"; + case "fcg" -> "t1.fcg"; + case "cl" -> "t1.cl"; + case "so4" -> "t1.so4"; + case "no3" -> "t1.no3"; + case "thrd" -> "t1.thrd"; + case "cond" -> "t1.cond"; + case "fe" -> "t1.fe"; + case "mn" -> "t1.mn"; + case "al" -> "t1.al"; + case "chla" -> "t1.chla"; + case "clarity" -> "t1.clarity"; + case "tu" -> "t1.tu"; + case "cyano" -> "t1.cyano"; + case "fid" -> "t1.fid"; + case "parameter" -> "t1.parameter"; + default -> null; + }; + } + + private String buildWeWqOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapWeWqColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; From 3392474a50a7267aa9c873bb832a7344429d8c81 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 17:13:18 +0800 Subject: [PATCH 44/65] =?UTF-8?q?feat:=20=E6=B0=B4=E7=94=9F=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5-=E6=B5=81=E9=80=9F=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/controller/WeFishController.java | 6 + .../qgc_env/wte/entity/vo/WeFvVo.java | 15 ++ .../qgc_env/wte/service/WeFishService.java | 2 + .../wte/service/impl/WeFishServiceImpl.java | 206 ++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFvVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index eb3f9084..d5f145ee 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -179,4 +179,10 @@ public class WeFishController { public ResponseResult getWeWqR(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(weFishService.getWeWqR(dataSourceRequest)); } + + @PostMapping("/we/fvR/GetKendoListCust") + @Operation(summary = "水生生态调查-流速数据列表") + public ResponseResult getWeFvR(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getWeFvR(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFvVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFvVo.java new file mode 100644 index 00000000..0db148d6 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WeFvVo.java @@ -0,0 +1,15 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class WeFvVo { + private String dcpc; + private String stcd; + private Date tm; + private BigDecimal flowrate; + private String fid; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index 554ff54f..ba33bd32 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -62,4 +62,6 @@ public interface WeFishService { DataSourceResult getWeWtR(DataSourceRequest dataSourceRequest); DataSourceResult getWeWqR(DataSourceRequest dataSourceRequest); + + DataSourceResult getWeFvR(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index ec0c1ed3..bc54e635 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -1624,6 +1624,212 @@ public class WeFishServiceImpl implements WeFishService { return " ORDER BY " + String.join(", ", orderByParts); } + @Override + public DataSourceResult getWeFvR(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.DCPC, t.STCD, t1.TM, t1.FLOW_RATE AS flowrate, t1.FID ") + .append("FROM SD_WE_R t ") + .append("INNER JOIN SD_WEFV_R t1 ON t.ID = t1.WER_ID ") + .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t1.IS_DELETED, 0) = 0 "); + + String filterSql = buildWeFvFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append("AND ").append(filterSql).append(" "); + } + + DataSourceResult result = new DataSourceResult<>(); + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + String groupBy = KendoUtil.getGroupBy(dataSourceRequest); + if (StrUtil.isNotBlank(groupBy)) { + List groupFields = new ArrayList<>(); + for (GroupingInfo item : groupInfos) { + if (item != null && StrUtil.isNotBlank(item.getSelector())) { + groupFields.add(item.getSelector()); + } + } + StringBuilder temp = new StringBuilder(); + temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); + if (groupInfos.length > 1) { + temp.append("count"); + } else { + temp.append("count_").append(String.join("_", groupFields)); + } + String groupedSql = temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); + List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + } + + sql.append(buildWeFvOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, WeFvVo.class); + + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildWeFvFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + List conditions = new ArrayList<>(); + List filters = filter.getFilters(); + if (CollUtil.isNotEmpty(filters)) { + for (DataSourceRequest.FilterDescriptor child : filters) { + String condition = buildWeFvFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(condition)) { + conditions.add(condition); + } + } + } else { + String leafCondition = buildWeFvLeafCondition(filter, paramMap, indexHolder); + if (StrUtil.isNotBlank(leafCondition)) { + conditions.add(leafCondition); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return "(" + String.join(logic, conditions) + ")"; + } + + private String buildWeFvLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapWeFvColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeWeFishQgcValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + boolean isDateField = "t1.tm".equals(column); + for (Object value : values) { + String paramKey = "weFvParam" + indexHolder[0]++; + paramMap.put(paramKey, value); + if (isDateField) { + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); + } else { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); + } + } else { + placeholders.add("#{map." + paramKey + "}"); + } + } + String prefix = "ni".equals(operator) ? "NOT " : ""; + return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; + } + String paramKey = "weFvParam" + indexHolder[0]++; + paramMap.put(paramKey, filter.getValue()); + boolean isDateField = "t1.tm".equals(column); + String valueExpr; + if (isDateField) { + String text = String.valueOf(filter.getValue()).trim(); + if (text.length() <= 10) { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } else { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + } else { + valueExpr = "#{map." + paramKey + "}"; + } + return switch (operator) { + case "lt", "lessthan" -> column + " < " + valueExpr; + case "lte", "lessthanorequals" -> column + " <= " + valueExpr; + case "gt", "greaterthan" -> column + " > " + valueExpr; + case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; + case "ne", "notequals" -> column + " <> " + valueExpr; + case "contains", "doesnotcontain", "startswith", "endswith" -> { + String pattern = switch (operator) { + case "contains" -> "%#{map." + paramKey + "}%"; + case "doesnotcontain" -> "%#{map." + paramKey + "}%"; + case "startswith" -> "#{map." + paramKey + "}%"; + case "endswith" -> "%#{map." + paramKey + "}"; + default -> "%#{map." + paramKey + "}%"; + }; + String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; + yield column + " " + likePrefix + "LIKE " + pattern; + } + default -> column + " = " + valueExpr; + }; + } + + private String mapWeFvColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field.toLowerCase()) { + case "dcpc" -> "t.dcpc"; + case "stcd" -> "t.stcd"; + case "tm" -> "t1.tm"; + case "flowrate" -> "t1.flow_rate"; + case "fid" -> "t1.fid"; + default -> null; + }; + } + + private String buildWeFvOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapWeFvColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; From 34be84057befdfaa3813e87d9798067e14ccea06 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 17:53:01 +0800 Subject: [PATCH 45/65] =?UTF-8?q?feat:=20=E7=8E=AF=E4=BF=9D=E8=AE=BE?= =?UTF-8?q?=E6=96=BD=E7=82=B9=E5=87=BB=E6=8F=8F=E7=82=B9=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E6=9C=89=E6=95=B0=E6=8D=AE=E7=9A=84=E5=B9=B4?= =?UTF-8?q?=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 6 +++ .../qgc_eng/eq/service/EngEqDataService.java | 2 + .../eq/service/impl/EngEqDataServiceImpl.java | 44 +++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java index 66190642..8ff8bc00 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java @@ -162,4 +162,10 @@ public class EngEqDataController { public ResponseResult getQecRateCount(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(engEqDataService.qecRateCount(dataSourceRequest)); } + + @PostMapping("/operat/default/year") + @Operation(summary = "环保设施点击描点默认展示有数据的年份,不包含过鱼设施描点") + public ResponseResult getDefaultYear(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(engEqDataService.getDefaultYear(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java index 7f0a0bf8..4bdafb61 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java @@ -59,4 +59,6 @@ public interface EngEqDataService { DataSourceResult getEvnmAutoMonitorList(DataSourceRequest dataSourceRequest); DataSourceResult qecRateCount(DataSourceRequest dataSourceRequest); + + DataSourceResult getDefaultYear(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index 124541a0..e0582bb7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -5805,4 +5805,48 @@ public class EngEqDataServiceImpl implements EngEqDataService { default -> null; }; } + + @Override + public DataSourceResult getDefaultYear(DataSourceRequest dataSourceRequest) { + DataSourceResult dataSourceResult = new DataSourceResult<>(); + List resultList = new ArrayList<>(); + dataSourceResult.setData(resultList); + dataSourceResult.setTotal(resultList.size()); + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String sttpCode = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "sttpCode"); + if (StrUtil.isBlank(stcd) || StrUtil.isBlank(sttpCode)) { + return dataSourceResult; + } + + Map paramMap = new HashMap<>(); + paramMap.put("stcd", stcd); + + String sql = switch (sttpCode) { + case "DW" -> "SELECT MAX(TM) AS TM FROM SD_DW_R WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0"; + case "EQ" -> "SELECT MAX(TM) AS TM FROM SD_EQ_R WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0"; + case "FB" -> "SELECT MAX(TM) AS TM FROM SD_ENGFR_R WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0"; + case "VA" -> "SELECT MAX(TM) AS TM FROM SD_VA_R WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0"; + case "VP" -> "SELECT MAX(TM) AS TM FROM SD_VP_R WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0"; + default -> ""; + }; + + if (StrUtil.isBlank(sql)) { + return dataSourceResult; + } + + List> allList = microservicDynamicSQLMapper.getAllList(sql, paramMap); + if (CollUtil.isEmpty(allList)) { + return dataSourceResult; + } + Map map = allList.get(0); + if (map == null) { + return dataSourceResult; + } + Object tm = map.getOrDefault("TM", ""); + if (tm != null && StrUtil.isNotBlank(tm.toString())) { + resultList.add(tm.toString()); + } + return dataSourceResult; + } } From cbb93ec8eca3e6cf59bb1d4ce2c644843fa7e880 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 18:16:59 +0800 Subject: [PATCH 46/65] =?UTF-8?q?fix:=20=E6=B0=B4=E7=94=9F=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5-=E6=B5=81=E9=80=9F=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?&=E6=8F=90=E5=8F=96=E5=85=AC=E5=85=B1=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wte/service/impl/WeFishServiceImpl.java | 172 +------------ .../platform/utils/QgcQueryWrapperUtil.java | 238 ++++++++++++++++++ 2 files changed, 250 insertions(+), 160 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index bc54e635..35996aa1 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -1627,7 +1627,6 @@ public class WeFishServiceImpl implements WeFishService { @Override public DataSourceResult getWeFvR(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); - GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); Map paramMap = new HashMap<>(); StringBuilder sql = new StringBuilder(); @@ -1636,46 +1635,28 @@ public class WeFishServiceImpl implements WeFishService { .append("INNER JOIN SD_WEFV_R t1 ON t.ID = t1.WER_ID ") .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t1.IS_DELETED, 0) = 0 "); - String filterSql = buildWeFvFilterCondition( + String filterSql = QgcQueryWrapperUtil.buildFilterCondition( dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, - new int[]{0} + new int[]{0}, + this::mapWeFvColumn ); if (StrUtil.isNotBlank(filterSql)) { sql.append("AND ").append(filterSql).append(" "); } DataSourceResult result = new DataSourceResult<>(); - if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { - String groupBy = KendoUtil.getGroupBy(dataSourceRequest); - if (StrUtil.isNotBlank(groupBy)) { - List groupFields = new ArrayList<>(); - for (GroupingInfo item : groupInfos) { - if (item != null && StrUtil.isNotBlank(item.getSelector())) { - groupFields.add(item.getSelector()); - } - } - StringBuilder temp = new StringBuilder(); - temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); - if (groupInfos.length > 1) { - temp.append("count"); - } else { - temp.append("count_").append(String.join("_", groupFields)); - } - String groupedSql = temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); - List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); - if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { - result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); - } else { - result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); - } - result.setTotal((long) rows.size()); - result.setAggregates(new HashMap<>()); - return result; - } + String groupSql = QgcQueryWrapperUtil.buildGroupSql(dataSourceRequest, sql); + if (StrUtil.isNotBlank(groupSql)) { + List> rows = microservicDynamicSQLMapper.getAllList(groupSql, paramMap); + return QgcQueryWrapperUtil.buildGroupResult(dataSourceRequest, rows); } - sql.append(buildWeFvOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + sql.append(QgcQueryWrapperUtil.buildOrderBySql( + dataSourceRequest == null ? null : dataSourceRequest.getSort(), + this::mapWeFvColumn, + "t1.TM DESC NULLS LAST, t.STCD ASC" + )); Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); @@ -1687,113 +1668,6 @@ public class WeFishServiceImpl implements WeFishService { return result; } - private String buildWeFvFilterCondition(DataSourceRequest.FilterDescriptor filter, - Map paramMap, - int[] indexHolder) { - if (filter == null) { - return ""; - } - List conditions = new ArrayList<>(); - List filters = filter.getFilters(); - if (CollUtil.isNotEmpty(filters)) { - for (DataSourceRequest.FilterDescriptor child : filters) { - String condition = buildWeFvFilterCondition(child, paramMap, indexHolder); - if (StrUtil.isNotBlank(condition)) { - conditions.add(condition); - } - } - } else { - String leafCondition = buildWeFvLeafCondition(filter, paramMap, indexHolder); - if (StrUtil.isNotBlank(leafCondition)) { - conditions.add(leafCondition); - } - } - if (conditions.isEmpty()) { - return ""; - } - String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; - return "(" + String.join(logic, conditions) + ")"; - } - - private String buildWeFvLeafCondition(DataSourceRequest.FilterDescriptor filter, - Map paramMap, - int[] indexHolder) { - String column = mapWeFvColumn(filter.getField()); - if (StrUtil.isBlank(column)) { - return ""; - } - String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); - if ("isnull".equals(operator)) { - return column + " IS NULL"; - } - if ("isnotnull".equals(operator)) { - return column + " IS NOT NULL"; - } - if ("isempty".equals(operator)) { - return "(" + column + " IS NULL OR " + column + " = '')"; - } - if ("isnotempty".equals(operator)) { - return "(" + column + " IS NOT NULL AND " + column + " <> '')"; - } - if ("in".equals(operator) || "ni".equals(operator)) { - List values = normalizeWeFishQgcValues(filter.getValue()); - if (values.isEmpty()) { - return ""; - } - List placeholders = new ArrayList<>(); - boolean isDateField = "t1.tm".equals(column); - for (Object value : values) { - String paramKey = "weFvParam" + indexHolder[0]++; - paramMap.put(paramKey, value); - if (isDateField) { - String text = String.valueOf(value).trim(); - if (text.length() <= 10) { - placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); - } else { - placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); - } - } else { - placeholders.add("#{map." + paramKey + "}"); - } - } - String prefix = "ni".equals(operator) ? "NOT " : ""; - return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; - } - String paramKey = "weFvParam" + indexHolder[0]++; - paramMap.put(paramKey, filter.getValue()); - boolean isDateField = "t1.tm".equals(column); - String valueExpr; - if (isDateField) { - String text = String.valueOf(filter.getValue()).trim(); - if (text.length() <= 10) { - valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; - } else { - valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; - } - } else { - valueExpr = "#{map." + paramKey + "}"; - } - return switch (operator) { - case "lt", "lessthan" -> column + " < " + valueExpr; - case "lte", "lessthanorequals" -> column + " <= " + valueExpr; - case "gt", "greaterthan" -> column + " > " + valueExpr; - case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; - case "ne", "notequals" -> column + " <> " + valueExpr; - case "contains", "doesnotcontain", "startswith", "endswith" -> { - String pattern = switch (operator) { - case "contains" -> "%#{map." + paramKey + "}%"; - case "doesnotcontain" -> "%#{map." + paramKey + "}%"; - case "startswith" -> "#{map." + paramKey + "}%"; - case "endswith" -> "%#{map." + paramKey + "}"; - default -> "%#{map." + paramKey + "}%"; - }; - String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; - yield column + " " + likePrefix + "LIKE " + pattern; - } - default -> column + " = " + valueExpr; - }; - } - private String mapWeFvColumn(String field) { if (StrUtil.isBlank(field)) { return null; @@ -1808,28 +1682,6 @@ public class WeFishServiceImpl implements WeFishService { }; } - private String buildWeFvOrderBySql(List sorts) { - if (CollUtil.isEmpty(sorts)) { - return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; - } - List orderByParts = new ArrayList<>(); - for (DataSourceRequest.SortDescriptor sort : sorts) { - if (sort == null || StrUtil.isBlank(sort.getField())) { - continue; - } - String column = mapWeFvColumn(sort.getField()); - if (StrUtil.isBlank(column)) { - continue; - } - String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; - orderByParts.add(column + " " + direction + " NULLS LAST"); - } - if (orderByParts.isEmpty()) { - return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; - } - return " ORDER BY " + String.join(", ", orderByParts); - } - private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; diff --git a/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java b/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java index 3554573d..62a60bab 100644 --- a/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java +++ b/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java @@ -37,6 +37,11 @@ public class QgcQueryWrapperUtil { return FIELDNULL.contains(columName) ? "00000000-0000-0000-0000-000000000000" : null; } + @FunctionalInterface + public interface ColumnMapper { + String apply(String field); + } + public static String getFilterFieldValue(DataSourceLoadOptionsBase loadOptions, String fieldName) { try { JsonElement jsonElement = (new JsonParser()).parse(JSONUtil.toJsonStr(loadOptions.getFilter())); @@ -702,6 +707,239 @@ public class QgcQueryWrapperUtil { } + + + public static String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + ColumnMapper columnMapper) { + if (filter == null) { + return ""; + } + List conditions = new ArrayList<>(); + List filters = filter.getFilters(); + if (CollectionUtil.isNotEmpty(filters)) { + for (DataSourceRequest.FilterDescriptor child : filters) { + String condition = buildFilterCondition(child, paramMap, indexHolder, columnMapper); + if (StrUtil.isNotBlank(condition)) { + conditions.add(condition); + } + } + } else { + String leafCondition = buildLeafCondition(filter, paramMap, indexHolder, columnMapper); + if (StrUtil.isNotBlank(leafCondition)) { + conditions.add(leafCondition); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return "(" + String.join(logic, conditions) + ")"; + } + + private static String buildLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + ColumnMapper columnMapper) { + String column = columnMapper.apply(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + boolean isDateField = isDateColumn(column); + for (Object value : values) { + String paramKey = "param" + indexHolder[0]++; + paramMap.put(paramKey, value); + if (isDateField) { + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); + } else { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); + } + } else { + placeholders.add("#{map." + paramKey + "}"); + } + } + String prefix = "ni".equals(operator) ? "NOT " : ""; + return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; + } + String paramKey = "param" + indexHolder[0]++; + paramMap.put(paramKey, filter.getValue()); + boolean isDateField = isDateColumn(column); + String valueExpr; + if (isDateField) { + String text = String.valueOf(filter.getValue()).trim(); + if (text.length() <= 10) { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } else { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + } else { + valueExpr = "#{map." + paramKey + "}"; + } + return switch (operator) { + case "lt", "lessthan" -> column + " < " + valueExpr; + case "lte", "lessthanorequals" -> column + " <= " + valueExpr; + case "gt", "greaterthan" -> column + " > " + valueExpr; + case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; + case "ne", "notequals" -> column + " <> " + valueExpr; + case "contains", "doesnotcontain", "startswith", "endswith" -> { + String pattern = switch (operator) { + case "contains" -> "%#{map." + paramKey + "}%"; + case "doesnotcontain" -> "%#{map." + paramKey + "}%"; + case "startswith" -> "#{map." + paramKey + "}%"; + case "endswith" -> "%#{map." + paramKey + "}"; + default -> "%#{map." + paramKey + "}%"; + }; + String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; + yield column + " " + likePrefix + "LIKE " + pattern; + } + default -> column + " = " + valueExpr; + }; + } + + private static List normalizeValues(Object value) { + List result = new ArrayList<>(); + if (value == null) { + return result; + } + if (value instanceof List) { + for (Object item : (List) value) { + if (item != null && StrUtil.isNotBlank(item.toString())) { + result.add(item); + } + } + } else if (StrUtil.isNotBlank(value.toString())) { + result.add(value); + } + return result; + } + + private static boolean isDateColumn(String column) { + if (StrUtil.isBlank(column)) { + return false; + } + String lowerColumn = column.toLowerCase(); + return lowerColumn.contains(".tm") || lowerColumn.contains(".time") || lowerColumn.contains(".date"); + } + + public static String buildOrderBySql(List sorts, + ColumnMapper columnMapper, + String defaultOrderBy) { + if (CollectionUtil.isEmpty(sorts)) { + return StrUtil.isNotBlank(defaultOrderBy) ? " ORDER BY " + defaultOrderBy : ""; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = columnMapper.apply(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return StrUtil.isNotBlank(defaultOrderBy) ? " ORDER BY " + defaultOrderBy : ""; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + + public static String buildGroupSql(DataSourceRequest dataSourceRequest, StringBuilder sql) { + if (CollectionUtil.isEmpty(dataSourceRequest.getGroup())) { + return null; + } + String groupBy = KendoUtil.getGroupBy(dataSourceRequest); + if (StrUtil.isBlank(groupBy)) { + return null; + } + List groupFields = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor item : dataSourceRequest.getGroup()) { + if (item != null && StrUtil.isNotBlank(item.getField())) { + groupFields.add(item.getField()); + } + } + StringBuilder temp = new StringBuilder(); + temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); + if (groupFields.size() > 1) { + temp.append("count"); + } else { + temp.append("count_").append(String.join("_", groupFields)); + } + return temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); + } + + public static DataSourceResult buildGroupResult(DataSourceRequest dataSourceRequest, + List> rows) { + DataSourceResult result = new DataSourceResult<>(); + List groupingInfos = convertToGroupingInfo(dataSourceRequest.getGroup()); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, groupingInfos)); + } else { + result.setData((List) (List) new GroupHelper().group(rows, groupingInfos)); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private static List convertToGroupingInfo(List groupDescriptors) { + List groupingInfos = new ArrayList<>(); + if (CollectionUtil.isEmpty(groupDescriptors)) { + return groupingInfos; + } + for (DataSourceRequest.GroupDescriptor groupDescriptor : groupDescriptors) { + GroupingInfo groupingInfo = new GroupingInfo(); + groupingInfo.setSelector(groupDescriptor.getField()); + String dir = groupDescriptor.getDir(); + String normalizedDir = StrUtil.isBlank(dir) ? "" : dir.toLowerCase(); + if ("des".equals(normalizedDir)) { + normalizedDir = "desc"; + } + if (StrUtil.isBlank(normalizedDir)) { + groupingInfo.setDesc(false); + } else if (normalizedDir.equals("asc")) { + groupingInfo.setDesc(false); + } else if (normalizedDir.equals("desc")) { + groupingInfo.setDesc(true); + } + groupingInfo.setNeedSortFlag(groupDescriptor.getNeedSortFlag()); + List aggregateDescriptors = groupDescriptor.getAggregates(); + if (CollectionUtil.isNotEmpty(aggregateDescriptors)) { + for (DataSourceRequest.AggregateDescriptor aggregateDescriptor : aggregateDescriptors) { + SummaryInfo summaryInfo = new SummaryInfo(); + summaryInfo.setSelector(aggregateDescriptor.getField()); + summaryInfo.setSummaryType(aggregateDescriptor.getAggregate()); + groupingInfo.getSummaryInfos().add(summaryInfo); + } + } + groupingInfos.add(groupingInfo); + } + return groupingInfos; + } + static { FIELDNULL.add("parentId"); } From e0b8dd2e49a81fc6fa62dfb1a19537898b518ee3 Mon Sep 17 00:00:00 2001 From: lilin <18811154576@163.com> Date: Wed, 1 Jul 2026 18:19:37 +0800 Subject: [PATCH 47/65] =?UTF-8?q?=E5=9C=B0=E5=9B=BE=E5=9B=BE=E4=BE=8B?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MapLegendController.java | 10 +++ .../mapLayer/mapper/MsMapmoduleBMapper.java | 24 +++++++ .../service/IMapLegendBizService.java | 9 +++ .../service/impl/MapLegendBizServiceImpl.java | 67 +++++++++++++++++++ .../controller/MapmoduleBController.java | 40 +++++------ 5 files changed, 128 insertions(+), 22 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java index bb5830c7..87e3187a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/controller/MapLegendController.java @@ -196,4 +196,14 @@ public class MapLegendController { List tree = mapLegendBizService.getMapLegendTree(flag); return ResponseResult.successData(tree); } + + /** + * 地图图例列表 + */ + @Operation(summary = "地图图例列表") + @GetMapping("/getModuleMapLegendList") + public ResponseResult getModuleMapLegendList(@RequestParam(required = false) String moduleId) { + List list = mapLegendBizService.getModuleMapLegendList(moduleId); + return ResponseResult.successData(list); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java index e219ae10..d0858123 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/mapper/MsMapmoduleBMapper.java @@ -87,4 +87,28 @@ public interface MsMapmoduleBMapper extends BaseMapper { + "") List getModuleMapLegendList(@Param("moduleId") String moduleId, @Param("sid") String sid, @Param("templateId") String templateId); + + + /** + * 查询模块关联的图例列表(单参数版本,用于地图图例管理页面) + */ + @Select("") + List getModuleMapLegendList(@Param("moduleId") String moduleId); + } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java index 30d35833..23874190 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/IMapLegendBizService.java @@ -30,4 +30,13 @@ public interface IMapLegendBizService { */ List getModuleMapLegendList(String moduleId, String systemId, String templateId); + /** + * 根据模块ID获取模块关联的图例列表(单参数版本) + * + * @param moduleId 模块ID + * @return 图例列表 + */ + List getModuleMapLegendList(String moduleId); + + } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java index cdc7a489..5ca81ae0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendBizServiceImpl.java @@ -8,6 +8,7 @@ import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper; import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendBizService; import com.yfd.platform.qgc_sys.mapLayer.service.IMapLegendService; import jakarta.annotation.Resource; +import cn.hutool.core.collection.CollectionUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -142,4 +143,70 @@ public class MapLegendBizServiceImpl implements IMapLegendBizService { .sorted(Comparator.comparing(MapLegendVo::getPSort, Comparator.nullsLast(Integer::compareTo))) .collect(Collectors.toList()); } + + @Override + public List getModuleMapLegendList(String moduleId) { + List list = new ArrayList<>(); + // 通过 JOIN 查询 MS_MAPLEGEND_B 和 MS_MAPMODULE_B(单参数版本) + List bbiMapLegendList = msMapmoduleBMapper.getModuleMapLegendList(moduleId); + + if (bbiMapLegendList == null || bbiMapLegendList.isEmpty()) { + return list; + } + + // 收集父级ID,查询父级图例的layerCode + Set parentIdList = bbiMapLegendList.stream() + .map(MapLegendVo::getParentId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Map layerCodeMap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(parentIdList)) { + List parentLegendList = legendService.lambdaQuery() + .in(MsMaplegendB::getId, parentIdList) + .list(); + layerCodeMap = parentLegendList.stream() + .filter(item -> item.getLayerCode() != null) + .collect(Collectors.toMap(MsMaplegendB::getId, MsMaplegendB::getLayerCode, (v1, v2) -> v1)); + } + + // 按父级分组 + Map> collect = bbiMapLegendList.stream() + .collect(Collectors.groupingBy(MapLegendVo::getParentName)); + + // 遍历 + Map finalLayerCodeMap = layerCodeMap; + collect.forEach((str, mapLegendVoList) -> { + MapLegendVo mapLegendVo = new MapLegendVo(); + mapLegendVo.setName(str); + mapLegendVo.setPSort(mapLegendVoList.get(0).getPSort()); + mapLegendVo.setLayerCode(finalLayerCodeMap.get(mapLegendVoList.get(0).getParentId())); + // 按子级分组名分组 + Map> collect1 = mapLegendVoList.stream() + .collect(Collectors.groupingBy(MapLegendVo::getGroupName)); + List childrenList = new ArrayList<>(); + for (String groupNameStr : collect1.keySet()) { + List list1 = collect1.get(groupNameStr); + // 如果子级和父级名称相同,则不用子级 + if (groupNameStr.equalsIgnoreCase(str)) { + childrenList = list1; + } else { + MapLegendVo mapLegendVoChild = new MapLegendVo(); + mapLegendVoChild.setName(groupNameStr); + if (null != list1 && list1.size() > 0) { + mapLegendVoChild.setPSort(list1.get(0).getPSort()); + } + mapLegendVoChild.setChildrenList(list1); + childrenList.add(mapLegendVoChild); + } + } + List collect2 = childrenList.stream() + .sorted(Comparator.comparing(MapLegendVo::getPSort, Comparator.nullsLast(Integer::compareTo))) + .collect(Collectors.toList()); + mapLegendVo.setChildrenList(collect2); + list.add(mapLegendVo); + }); + return list.stream() + .sorted(Comparator.comparing(MapLegendVo::getPSort, Comparator.nullsLast(Integer::compareTo))) + .collect(Collectors.toList()); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java index 0ddd61ef..e0b8ba83 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapcfg/controller/MapmoduleBController.java @@ -3,6 +3,7 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.config.ResponseResult; @@ -13,6 +14,7 @@ import com.yfd.platform.qgc_sys.mapcfg.entity.MapmoduleVo; import com.yfd.platform.system.domain.SysMenu; import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.utils.DataSourceRequestUtil; +import com.yfd.platform.utils.QgcQueryWrapperUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -43,12 +45,16 @@ public class MapmoduleBController { @Operation(summary = "条件过滤数据列表") @PostMapping("/GetKendoList") public ResponseResult getKendoList(@RequestBody DataSourceRequest dataSourceRequest) { - // 构建查询条件 + // 1. 构建查询条件 QueryWrapper wrapper = DataSourceRequestUtil.buildQueryWrapper( dataSourceRequest, MsMapmoduleB.class); - // 执行分页查询 - Page page = DataSourceRequestUtil.getPage(dataSourceRequest); + // 2. 分页参数处理(与 getMsstbprptList 完全一致) + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null + : (Page) QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + + // 3. 执行分页查询 Page resultPage; if (page != null) { resultPage = mapmoduleBService.page(page, wrapper); @@ -59,60 +65,50 @@ public class MapmoduleBController { resultPage.setTotal(list.size()); } - // 构建 Kendo 数据源结果 + // 4. 构建 Kendo 数据源结果 DataSourceResult dataSourceResult = new DataSourceResult<>(); List dataList = resultPage.getRecords(); dataSourceResult.setData(dataList); dataSourceResult.setTotal(resultPage.getTotal()); - // 翻译字典值(原有逻辑,可能处理其他字段) + // 5. 翻译与额外字段填充(原有逻辑保持不变) if (dataList != null && !dataList.isEmpty()) { mapmoduleBService.translateDict(dataList); - // ----- 新增:填充 moduleName ----- - // 1. 先收集需要从数据库查询的 moduleId(排除 "tycd") Set needQueryIds = dataList.stream() .map(MsMapmoduleB::getModuleId) - .filter(id -> id != null && !"tycd".equals(id)) // 过滤掉 "tycd" + .filter(id -> id != null && !"tycd".equals(id)) .collect(Collectors.toSet()); Map menuNameMap = new HashMap<>(); if (!needQueryIds.isEmpty()) { - // 查询 SYS_MENU 表(假设实体为 SysMenu,Mapper 为 sysMenuMapper) List menus = sysMenuMapper.selectList( new LambdaQueryWrapper() - .in(SysMenu::getId, needQueryIds) // 注意 id 类型需匹配 + .in(SysMenu::getId, needQueryIds) ); menuNameMap = menus.stream() .collect(Collectors.toMap( - menu -> String.valueOf(menu.getId()), // 统一转为字符串 + menu -> String.valueOf(menu.getId()), SysMenu::getName )); } - // 2. 遍历 dataList 设置 moduleName for (MsMapmoduleB entity : dataList) { + // 填充 moduleName String moduleId = entity.getModuleId(); if (moduleId == null) { entity.setModuleName(null); } else if ("tycd".equals(moduleId)) { - // 特殊处理:固定为 "通用菜单" entity.setModuleName("通用菜单"); + entity.setChecked(1); } else { - // 从查询结果中获取 entity.setModuleName(menuNameMap.get(moduleId)); - // 如果 menuNameMap 中不存在,则置 null(或保留原值,视业务而定) - if (entity.getModuleName() == null) { - entity.setModuleName(null); // 或者 entity.setModuleName(""); - } } - } - // ========== 2. 处理 systemName 特殊值 ========== - for (MsMapmoduleB entity : dataList) { + + // 特殊 systemName if ("qgc".equals(entity.getSystemId())) { entity.setSystemName("qgc"); } - // 其他 systemId 保留字典翻译的结果 } } From 03fb75980f69be9dcc6e45f0f8236f9dcde0934a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=87=AF?= <2448379534@qq.com> Date: Wed, 1 Jul 2026 18:23:41 +0800 Subject: [PATCH 48/65] =?UTF-8?q?=E9=A6=96=E9=A1=B5=EF=BC=8C=E7=94=9F?= =?UTF-8?q?=E6=80=81=E8=B0=83=E6=9F=A5=EF=BC=8C=E6=99=BA=E8=83=BD=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E9=A1=B5=E9=9D=A2=E7=BA=BF=E4=B8=8A=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5=EF=BC=8C=E4=BA=8C=E7=BA=A7=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.env.development | 2 +- frontend/src/api/home/index.ts | 99 + frontend/src/api/mapModal/index.ts | 2 +- frontend/src/api/stdc/index.ts | 61 +- frontend/src/api/stll/index.ts | 7 + frontend/src/api/yldc/index.ts | 7 + frontend/src/api/zngj/index.ts | 91 + frontend/src/assets/svg/diwenshuijianhuan.svg | 4 + frontend/src/assets/svg/guojiashuiwenzhan.svg | 16 + frontend/src/assets/svg/guojiashuizhizhan.svg | 13 + .../src/assets/svg/liuliangjiancezhan.svg | 6 + frontend/src/assets/svg/qixiangzhan.svg | 16 + frontend/src/assets/svg/qixidi.svg | 9 + .../src/assets/svg/shipinjiankongshebei.svg | 4 + frontend/src/assets/svg/shuizhijiancezhan.svg | 1 + .../src/assets/svg/zengzhizhanshuizhizhan.svg | 9 + frontend/src/assets/svg/zijianshuiwenzhan.svg | 16 + .../src/components/MapModal/column.config.ts | 98 +- .../MapModal/components/BasicInfo.vue | 10 + .../src/components/MapModal/setting.config.ts | 53 +- .../src/components/SidePanelItem/index.vue | 14 +- .../components/developStatusChart/index.vue | 323 ++- .../components/engEnvironmentData/index.vue | 116 +- .../alongFishMod/TwoLayers/Yanchengyulei.vue | 261 ++- frontend/src/modules/alongFishMod/index.vue | 6 +- .../modules/dianxingcuoshijieshao/index.vue | 490 ++++- .../modules/fishSurvey/FishVideo/index.vue | 4 +- .../TwoLayers/HuanbaoModTwoLayers.vue | 390 ++++ frontend/src/modules/huanbaoMod/index.vue | 269 ++- .../huanbaozidongjianceEJ/index.vue | 591 ++++++ .../src/modules/huanbaozdjcgzkzQK/index.vue | 301 +-- frontend/src/modules/jidiInfoMod/index.vue | 10 +- .../src/modules/liuyu/ai/spdzwaijc/index.vue | 146 +- .../ModeGaoJing.vue | 289 +++ .../shengtailiuliangxianshuju.vue | 146 +- .../shuizhijiancegaojing/ModeGaoJing.vue | 289 +++ .../shuizhijianceshuju.vue | 243 ++- .../xieFangFangShi/TwoLayer/STLLXFFS.vue | 118 +- .../TwoLayer/ModalYkzhbzdjcgz.vue | 6 +- .../ShengTaiLiuLiangDaBQKTwoLayer.vue | 6 +- .../src/modules/shengtaidabiaoMod/index.vue | 66 +- .../TwoLayer/ModalYkzhbzdjcgz.vue | 386 ++++ .../ShengTaiLiuLiangDaBQKTwoLayer.vue | 939 +++++++++ .../src/modules/shengtaidabiaoModJZ/index.vue | 439 +++++ .../TwoLayer/STLLXFFS.vue | 14 +- .../TwoLayer/STLLXFFS.vue | 796 ++++++++ .../modules/shengtaidabiaoTwoModJJ/index.vue | 675 +++++++ .../shuiShengShengTaiDiaoCha/index.vue | 619 ++++-- .../shuidianhuangjingjieruMod/DataTable.vue | 311 ++- .../TwoLayer/HuanJingSJJRQK.vue | 439 +++++ .../shuidianhuangjingjieruMod/index.vue | 100 +- .../shuishengshengtaijiance/SsstdcgkTk.vue | 5 +- .../modules/stllyanchengChangeModJJ/index.vue | 614 ++++++ .../yunXingGaoJIng/Aisbdbyx/AISBTK.vue | 1737 +++++++++++++++++ .../modules/yunXingGaoJIng/Aisbdbyx/index.vue | 181 +- frontend/src/shims.d.ts | 6 +- frontend/src/store/modules/jidiSelectEvent.ts | 6 +- frontend/src/utils/request.ts | 2 +- .../views/fish-survey/fishSurveyZhuanZhi.vue | 18 +- .../shuiShengShengTaiDiaoCha.vue | 75 +- .../shuiShengShengTaiDiaoCha/SSSTDCDB.vue | 441 +++++ .../shengTaiLiuLiangManZuQingKuangJiangJu.vue | 36 + 62 files changed, 11362 insertions(+), 1085 deletions(-) create mode 100644 frontend/src/api/zngj/index.ts create mode 100644 frontend/src/assets/svg/diwenshuijianhuan.svg create mode 100644 frontend/src/assets/svg/guojiashuiwenzhan.svg create mode 100644 frontend/src/assets/svg/guojiashuizhizhan.svg create mode 100644 frontend/src/assets/svg/liuliangjiancezhan.svg create mode 100644 frontend/src/assets/svg/qixiangzhan.svg create mode 100644 frontend/src/assets/svg/qixidi.svg create mode 100644 frontend/src/assets/svg/shipinjiankongshebei.svg create mode 100644 frontend/src/assets/svg/shuizhijiancezhan.svg create mode 100644 frontend/src/assets/svg/zengzhizhanshuizhizhan.svg create mode 100644 frontend/src/assets/svg/zijianshuiwenzhan.svg create mode 100644 frontend/src/modules/huanbaoMod/TwoLayers/HuanbaoModTwoLayers.vue create mode 100644 frontend/src/modules/huanbaozdjcgzkzQK/huanbaozidongjianceEJ/index.vue create mode 100644 frontend/src/modules/liuyu/yichangyujing/shengtailiuliangxianzhigaojing/ModeGaoJing.vue create mode 100644 frontend/src/modules/liuyu/yichangyujing/shuizhijiancegaojing/ModeGaoJing.vue create mode 100644 frontend/src/modules/shengtaidabiaoModJZ/TwoLayer/ModalYkzhbzdjcgz.vue create mode 100644 frontend/src/modules/shengtaidabiaoModJZ/TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue create mode 100644 frontend/src/modules/shengtaidabiaoModJZ/index.vue create mode 100644 frontend/src/modules/shengtaidabiaoTwoModJJ/TwoLayer/STLLXFFS.vue create mode 100644 frontend/src/modules/shengtaidabiaoTwoModJJ/index.vue create mode 100644 frontend/src/modules/shuidianhuangjingjieruMod/TwoLayer/HuanJingSJJRQK.vue create mode 100644 frontend/src/modules/stllyanchengChangeModJJ/index.vue create mode 100644 frontend/src/modules/yunXingGaoJIng/Aisbdbyx/AISBTK.vue create mode 100644 frontend/src/views/shengTaiDiaoCha/shuiShengShengTaiDiaoCha/SSSTDCDB.vue create mode 100644 frontend/src/views/shengTaiLiuLiang/shengTaiLiuLiangManZuQingKuangJiangJu.vue diff --git a/frontend/.env.development b/frontend/.env.development index 95ce05a0..6d37ed54 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -7,7 +7,7 @@ VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台' VITE_APP_PORT = 3000 VITE_APP_BASE_API = '/dev-api' # 本地环境 -VITE_APP_BASE_URL = 'http://localhost:8093' +# VITE_APP_BASE_URL = 'http://10.84.121.122:8093' # 测试环境 # VITE_APP_BASE_URL = 'http://172.16.21.142:8093' # VITE_APP_BASE_URL = 'http://172.16.21.142:8096' diff --git a/frontend/src/api/home/index.ts b/frontend/src/api/home/index.ts index 0ead2e2c..6c3732c4 100644 --- a/frontend/src/api/home/index.ts +++ b/frontend/src/api/home/index.ts @@ -8,3 +8,102 @@ export function getBaseWbsb(data: any) { data: data }); } + +// 水电开发及环境监测 - 获取列表数据 +export function getVmsstbprptKendoList(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList', + method: 'post', + data: data + }); +} + +// 环保设施建设情况 +export function environmentalProtectionConstruction(data: any) { + return request({ + url: '/api/wmp-env-server/env/operat/GetKendoListCust', + method: 'post', + data: data + }); +} + +// 环保设施弹框表格 +export function envOpdGetKendoListCust(data: any) { + return request({ + url: '/api/wmp-env-server/env/oped/GetKendoListCust', + method: 'post', + data: data + }); +} + +// 获取基地列表 +export function getBaseList(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/wbsb/GetKendoList', + method: 'post', + data: data + }); +} + +// 获取设施介绍列表 +export function getMsstbprptKendoList(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList', + method: 'post', + data: data + }); +} + +// 环保自动监测工作开展情况 +export function baseEvnmAutoMonitorGetKendoListCust(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/evnmAutoMonitor/GetKendoListCust', + method: 'post', + data: data + }); +} + +// 环保自动监测弹窗列表 +export function vmsstbprptGetKendoList(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList', + method: 'post', + data: data + }); +} + +// 获取基本信息 +export function baseMsstbprptGetKendoList(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList', + method: 'post', + data: data + }); +} + +// 降水量实时数据 +export function getBaseStbprpDataPPTNR(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/stbprpData/GetKendoListCust?tbCode=PPTN_R', + method: 'post', + data: data + }); +} + +// 气温气压实时数据 +export function getBaseStbprpDataTMPR(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/stbprpData/GetKendoListCust?tbCode=TMP_R', + method: 'post', + data: data + }); +} + +// 风速风向实时数据 +export function getBaseStbprpDataWNDR(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/stbprpData/GetKendoListCust?tbCode=WND_R', + method: 'post', + data: data + }); +} diff --git a/frontend/src/api/mapModal/index.ts b/frontend/src/api/mapModal/index.ts index 1cb7afb2..3a4a1ecb 100644 --- a/frontend/src/api/mapModal/index.ts +++ b/frontend/src/api/mapModal/index.ts @@ -547,7 +547,7 @@ export function getFlowDischargeYear(data: any) { } export function getFlowDischargeList(code: string, data: any) { return request({ - url: `/apo/dec-lygk-base-server/base/stbprpData/GetKendoListCust?tbCode=${code}`, + url: `/api/dec-lygk-base-server/base/stbprpData/GetKendoListCust?tbCode=${code}`, method: 'post', data }); diff --git a/frontend/src/api/stdc/index.ts b/frontend/src/api/stdc/index.ts index ce9c8d6e..db86bca5 100644 --- a/frontend/src/api/stdc/index.ts +++ b/frontend/src/api/stdc/index.ts @@ -3,16 +3,16 @@ import request from '@/utils/request'; //水生生态调查情况-下拉选择框 export function wbsbGetKendoList(data: any) { return request({ - url: '/api/dec-lygk-base-server/base/wbsb/GetKendoList', + url: '/eq/wbsb/GetKendoList', method: 'post', data }); } -// 水生生态调查情况-获取默认年份 +// 水生生态调查情况-获取默认年份 export function getDftYear(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/year/qgc/GetKendoListCust', + url: '/wte/we/fisht/year/qgc/GetKendoListCust', method: 'post', data }); @@ -21,7 +21,7 @@ export function getDftYear(data: any) { // 水生生态调查情况-获取统计数据 export function getWeFisht(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/statics/GetKendoListCust', + url: '/wte/we/fisht/statics/GetKendoListCust', method: 'post', data }); @@ -30,7 +30,7 @@ export function getWeFisht(data: any) { // 水生生态调查概况-表格数据接口 export function getWeStaticsSecond(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/statics/getWeStaticsSecond', + url: '/wte/we/fisht/statics/getWeStaticsSecond', method: 'post', data }); @@ -39,7 +39,7 @@ export function getWeStaticsSecond(data: any) { // 沿程鱼类变化-图表数据接口 export function fishChanges2(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/stat/GetKendoListCust', + url: '/wte/we/fisht/stat/GetKendoListCust', method: 'post', data }); @@ -48,7 +48,7 @@ export function fishChanges2(data: any) { // 沿程鱼类变化-详情表格接口 export function fishDetail(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/detail/GetKendoListCust', + url: '/wte/we/fisht/detail/GetKendoListCust', method: 'post', data }); @@ -57,7 +57,7 @@ export function fishDetail(data: any) { // 沿程鱼类变化-Tab数量统计接口 export function getTabNum(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/statTab/GetKendoListCust', + url: '/wte/we/fisht/statTab/GetKendoListCust', method: 'post', data }); @@ -66,11 +66,11 @@ export function getTabNum(data: any) { // 沿程鱼类变化-获取断面列表 export function getStcdList(data: any) { return request({ - url: '/api/dec-lygk-base-server/base/vmsstbprpt/noWqDtinType0Auth/GetKendoList', + url: '/eq/base/vmsstbprpt/GetKendoList', method: 'post', data: { filter: data, - orders: JSON.stringify({ siteStepSort: 'asc' }) + orders: { siteStepSort: 'asc' } } }); } @@ -78,7 +78,16 @@ export function getStcdList(data: any) { // 沿程鱼类变化-基地模式详情表格接口 export function fishQgcDetail(data: any) { return request({ - url: '/api/wmp-env-server/env/we/fisht/qgcDetail/GetKendoListCust', + url: '/wte/we/fisht/qgcDetail/GetKendoListCust', + method: 'post', + data + }); +} + +// 水生生态调查-鱼类列表统计 +export function getFishListStat(data: any) { + return request({ + url: '/wte/we/fishList/stat/qgc/GetKendoListCust', method: 'post', data }); @@ -87,7 +96,7 @@ export function fishQgcDetail(data: any) { // 陆生生态监测情况-获取统计数据 export function getEvnmAutoMonitor(data: any) { return request({ - url: '/api/dec-lygk-base-server/base/evnmAutoMonitor/GetKendoListCust', + url: '/wte/base/evnmAutoMonitor/GetKendoListCust', method: 'post', data }); @@ -96,7 +105,7 @@ export function getEvnmAutoMonitor(data: any) { // 陆生生态监测-红外相机信息表格 export function getVmsstbprptList(data: any) { return request({ - url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList', + url: '/wte/vmsstbprpt/GetKendoList', method: 'post', data }); @@ -105,7 +114,7 @@ export function getVmsstbprptList(data: any) { // 陆生生态监测-重点陆生动物表格 export function getTetSpecList(data: any) { return request({ - url: '/api/wmp-env-server/te/tet/spec/GetKendoListCust', + url: '/wte/te/tet/spec/GetKendoListCust', method: 'post', data }); @@ -114,7 +123,7 @@ export function getTetSpecList(data: any) { // 野生动物监测-获取运行数据 export function getWvaData(data: any) { return request({ - url: '/api/wmp-env-server/env/wva/GetKendoListCust', + url: '/wte/wva/GetKendoListCust', method: 'post', data }); @@ -123,7 +132,7 @@ export function getWvaData(data: any) { // 野生动物监测-获取默认数据 export function getWvaDftData(data: any) { return request({ - url: '/api/wmp-env-server/env/wva/default/GetKendoListCust', + url: '/wte/wva/default/GetKendoListCust', method: 'post', data }); @@ -132,7 +141,25 @@ export function getWvaDftData(data: any) { // 野生动物监测-获取默认年份列表 export function getWvaDftTm(data: any) { return request({ - url: '/api/wmp-env-server/env/wva/year/GetKendoListCust', + url: '/wte/wva/year/GetKendoListCust', + method: 'post', + data + }); +} + +// 水生生态调查对比-获取断面和批次列表 +export function getFishtKendoList(data: any) { + return request({ + url: '/wte/we/fisht/GetKendoListCust', + method: 'post', + data + }); +} + +// 水生生态调查对比-获取对比柱状图数据 +export function getCompareBar(data: any) { + return request({ + url: '/wte/we/compareBar/GetKendoListCust', method: 'post', data }); diff --git a/frontend/src/api/stll/index.ts b/frontend/src/api/stll/index.ts index 58db464a..bfa8ced7 100644 --- a/frontend/src/api/stll/index.ts +++ b/frontend/src/api/stll/index.ts @@ -39,6 +39,13 @@ export function vmsstbprptGetKendoList(queryParams: any) { data: queryParams }); } +export function vmsstbprptGetKendoList1(queryParams: any) { + return request({ + url: '/eq/vmsstbprpt/GetKendoList', + method: 'post', + data: queryParams + }); +} //生态流量达标情况 export function eqqecRateCount(queryParams: any) { return request({ diff --git a/frontend/src/api/yldc/index.ts b/frontend/src/api/yldc/index.ts index 4643b2f1..3282a2ac 100644 --- a/frontend/src/api/yldc/index.ts +++ b/frontend/src/api/yldc/index.ts @@ -15,6 +15,13 @@ export function msstbprptGetKendoList(data: any) { data }); } +export function VDmsstbprptGetKendoList(data: any) { + return request({ + url: '/vd/msstbprpt/GetKendoList', + method: 'post', + data + }); +} //获取鱼类介绍 export function fishDicGetKendoList(data: any) { return request({ diff --git a/frontend/src/api/zngj/index.ts b/frontend/src/api/zngj/index.ts new file mode 100644 index 00000000..c7b1bc6b --- /dev/null +++ b/frontend/src/api/zngj/index.ts @@ -0,0 +1,91 @@ +import request from '@/utils/request'; + +// AI识别大坝环境-获取统计数据(Tab数量) +export function getAisbdbyxList(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/qgcDmRun/GetKendoListCust', + method: 'post', + data + }); +} + +// AI识别大坝环境-获取饼图+表格数据 +export function getAiChartTable(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/GetKendoListCust', + method: 'post', + data + }); +} + +// AI识别大坝环境-获取电站列表 +export function getAiRstcd(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/qgc/aiRstcd/GetKendoListCust', + method: 'post', + data + }); +} + +// AI识别过鱼设施运行-获取统计数据 +export function getAiGyssList(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/qgcProtect/GetKendoListCust', + method: 'post', + data + }); +} + +// 生态流量低于限值告警-获取统计数据 +export function getStllGaojingList(data: any) { + return request({ + url: '/api/wmp-env-server/env/warn/stcd/eng/GetKendoListCust', + method: 'post', + data + }); +} + +// 生态流量低于限值告警-获取表格详情数据 +export function getStllGaojingDetail(data: any) { + return request({ + url: '/api/wmp-env-server/env/warn/stcd/GetKendoListCust', + method: 'post', + data + }); +} + +// 水质监测数据告警-获取统计数据 +export function getShuizhiGaojingList(data: any) { + return request({ + url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList', + method: 'post', + data + }); +} + +// AI识别大坝环境-获取漂浮物/清漂日历数据 +export function getAiPfwRecord(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/qgc/aiPfwRecord/GetKendoListCust', + method: 'post', + data + }); +} + +// AI识别大坝环境-获取叠梁门日历数据 +export function getAiRecord(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/qgc/aiRecord/GetKendoListCust', + method: 'post', + data + }); +} + +// AI识别大坝环境-获取日历详情视频数据 +export function getAiFile(data: any) { + return request({ + url: '/api/wmp-env-server/env/ai/com/qgc/aiFile/GetKendoListCust', + method: 'post', + data + }); +} diff --git a/frontend/src/assets/svg/diwenshuijianhuan.svg b/frontend/src/assets/svg/diwenshuijianhuan.svg new file mode 100644 index 00000000..334378b6 --- /dev/null +++ b/frontend/src/assets/svg/diwenshuijianhuan.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/guojiashuiwenzhan.svg b/frontend/src/assets/svg/guojiashuiwenzhan.svg new file mode 100644 index 00000000..ac788c8e --- /dev/null +++ b/frontend/src/assets/svg/guojiashuiwenzhan.svg @@ -0,0 +1,16 @@ + + + guojiashuiwenzhan + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/guojiashuizhizhan.svg b/frontend/src/assets/svg/guojiashuizhizhan.svg new file mode 100644 index 00000000..8244b65f --- /dev/null +++ b/frontend/src/assets/svg/guojiashuizhizhan.svg @@ -0,0 +1,13 @@ + + + guojiashuizhizhan + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/liuliangjiancezhan.svg b/frontend/src/assets/svg/liuliangjiancezhan.svg new file mode 100644 index 00000000..8575ff7b --- /dev/null +++ b/frontend/src/assets/svg/liuliangjiancezhan.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/qixiangzhan.svg b/frontend/src/assets/svg/qixiangzhan.svg new file mode 100644 index 00000000..35374b96 --- /dev/null +++ b/frontend/src/assets/svg/qixiangzhan.svg @@ -0,0 +1,16 @@ + + + qixiangzhan + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/qixidi.svg b/frontend/src/assets/svg/qixidi.svg new file mode 100644 index 00000000..ea3b599c --- /dev/null +++ b/frontend/src/assets/svg/qixidi.svg @@ -0,0 +1,9 @@ + + + qixidi + + + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/shipinjiankongshebei.svg b/frontend/src/assets/svg/shipinjiankongshebei.svg new file mode 100644 index 00000000..74cbd7ce --- /dev/null +++ b/frontend/src/assets/svg/shipinjiankongshebei.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/shuizhijiancezhan.svg b/frontend/src/assets/svg/shuizhijiancezhan.svg new file mode 100644 index 00000000..0925a2c4 --- /dev/null +++ b/frontend/src/assets/svg/shuizhijiancezhan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/svg/zengzhizhanshuizhizhan.svg b/frontend/src/assets/svg/zengzhizhanshuizhizhan.svg new file mode 100644 index 00000000..7632b476 --- /dev/null +++ b/frontend/src/assets/svg/zengzhizhanshuizhizhan.svg @@ -0,0 +1,9 @@ + + + zengzhizhanshuizhizhan + + + + + + \ No newline at end of file diff --git a/frontend/src/assets/svg/zijianshuiwenzhan.svg b/frontend/src/assets/svg/zijianshuiwenzhan.svg new file mode 100644 index 00000000..9114c677 --- /dev/null +++ b/frontend/src/assets/svg/zijianshuiwenzhan.svg @@ -0,0 +1,16 @@ + + + zijianshuiwenzhan + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/components/MapModal/column.config.ts b/frontend/src/components/MapModal/column.config.ts index e4e1b39d..f40cef4d 100644 --- a/frontend/src/components/MapModal/column.config.ts +++ b/frontend/src/components/MapModal/column.config.ts @@ -3288,6 +3288,45 @@ const DwSixPointColumns: Array = [ url: '' } ]; +//DW +const DwPointColumnsyuan: Array = [ + { + name: '基本属性', + visible: false, + ruleTips: '', + type: '', + url: '' + }, + { + name: '设施名称', + filed: 'stnm', + visible: true, + type: 'input', + url: '' + }, + + { + name: '站址', + filed: 'stlc', + visible: true, + type: 'select', + url: '' + }, + { + name: '所属流域', + filed: 'hbrvcdName', + visible: true, + type: 'select', + url: '' + }, + { + name: '所属电站', + filed: 'ennm', + visible: true, + type: 'select', + url: '' + }, +]; //夹岩双层取水 const DwOnePointColumns: Array = [ { @@ -4145,8 +4184,7 @@ const EQPointColumns7: Array = [ visible: true, type: 'select', url: '' - }, - + } ]; //阶段属性 const basicFilterColumns: Array = [ @@ -4831,6 +4869,58 @@ const tableColumns5: Array = [ setting: {} } ]; +//气象监测 +const MMColumns: Array = [ + { + name: '基本属性', + visible: false, + ruleTips: '', + type: '', + url: '' + }, { + name: '测站名称', + filed: 'stnm', + visible: true, + type: 'input', + url: '' + }, + { + name: '测站类型', + filed: 'sttpName', + visible: true, + type: 'select', + url: '' + }, + { + name: '站址', + filed: 'addvcdName', + visible: true, + type: 'input', + url: '' + }, + { + name: '所属流域', + filed: 'hbrvcdName', + visible: true, + type: 'select', + url: '' + }, + { + name: '所在水系', + filed: 'addvcdName', + visible: true, + type: 'input', + url: '' + }, + { + name: '建成日期', + filed: 'jcdt', + visible: true, + type: 'date', + format: 'YYYY-MM-DD', + url: '' + }, +]; //生态流量 const EcologicalFlowColumns: Array = []; @@ -4873,6 +4963,7 @@ export { DwFivePointColumns, DwSixPointColumns, DwOnePointColumns, + DwPointColumnsyuan, EQPointColumns2, EQPointColumns5, EQPointColumns3, @@ -4886,5 +4977,6 @@ export { tableColumns2, tableColumns3, tableColumns4, - tableColumns5 + tableColumns5, + MMColumns }; diff --git a/frontend/src/components/MapModal/components/BasicInfo.vue b/frontend/src/components/MapModal/components/BasicInfo.vue index fcdaa8ef..c66884fa 100644 --- a/frontend/src/components/MapModal/components/BasicInfo.vue +++ b/frontend/src/components/MapModal/components/BasicInfo.vue @@ -142,6 +142,8 @@ import { DwFivePointColumns, DwSixPointColumns, DwOnePointColumns, + DwPointColumnsyuan, + MMColumns, StinfoAiVidoPointColumns } from '../column.config'; import { useModelStore } from '@/store/modules/model'; @@ -318,6 +320,14 @@ const columnsConfig = ref([ { type: 'ZQ', columns: FhZQPointColumns + }, + { + type: 'DW', + columns: DwPointColumnsyuan + }, + { + type:'MM', + columns:MMColumns } //DW_1 diff --git a/frontend/src/components/MapModal/setting.config.ts b/frontend/src/components/MapModal/setting.config.ts index aeea96a7..a8231528 100644 --- a/frontend/src/components/MapModal/setting.config.ts +++ b/frontend/src/components/MapModal/setting.config.ts @@ -199,14 +199,14 @@ const ENGEQTabs: Array = [ ].filter(Boolean); // // 水电站生态流量 - 江局单独看 √ -// const ENGEQTabsJuangJu: Array = [ -// { -// name: '生态流量', -// key: 'EcologicalFlow', -// type: 'EcologicalFlow' -// }, - -// ].filter(Boolean) +const ENGEQTabsJuangJu: Array = [ + { + name: '生态流量', + key: 'EcologicalFlow', + type: 'EcologicalFlow', + default: true + } +].filter(Boolean); // //生态流量泄放设施 √ const EQTabs: Array = [ { @@ -310,9 +310,8 @@ const FPTabs1: Array = [ name: '基础信息', key: 'basicInfo', type: 'basic', - default: true, // 默认显示 - url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo', - + default: true, // 默认显示 + url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo' }, { name: '实时视频', @@ -956,15 +955,23 @@ const CommonTabs: any = [ } ]; -// // 气象站 -// const WeatherTabs: any = [ -// { -// name: '基础信息', -// key: 'basicInfo', -// type: 'basic', -// url: '/bbi/siteBipc/getSiteBasicInfo' -// } -// ] +// 气象站 +const WeatherTabs: any = [ + { + name: '基础信息', + key: 'basicInfo', + type: 'basic', + url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo', + default: true // 默认显示 + }, + { + name: '监测数据', + key: '', + type: '', + url: '' + }, + +] // const WaterQualityMonitoring: any = [ // { @@ -1033,6 +1040,8 @@ const handleTabs = (modaldata: any) => { const sttp = modaldata?.sttp ? modaldata?.sttp.toUpperCase() : ''; console.log('sttp', sttp); switch (sttp) { + case 'ENGJJ': + return ENGEQTabsJuangJu; case 'ENG': if (modaldata?.eqtp == 'QEC') { return ENGEQTabs; @@ -1223,8 +1232,8 @@ const handleTabs = (modaldata: any) => { // } // case 'WE': // return WETabs - // case 'MM': - // return WeatherTabs + case 'MM': + return WeatherTabs // case 'WARN': // return WaterQualityMonitoring // case 'AI': diff --git a/frontend/src/components/SidePanelItem/index.vue b/frontend/src/components/SidePanelItem/index.vue index abbfc6d5..e8dd8708 100644 --- a/frontend/src/components/SidePanelItem/index.vue +++ b/frontend/src/components/SidePanelItem/index.vue @@ -47,7 +47,6 @@
-
@@ -78,7 +77,7 @@ >
-
+
@@ -190,6 +189,7 @@ interface SelectConfig { value?: string | undefined; options?: SelectProps['options']; width?: string; + minWidth?: string; } // 定义组件名(便于调试和递归) @@ -248,7 +248,8 @@ const props = defineProps({ show: false, value: undefined, options: [], - width: '' + width: '', + minWidth: '' }) }, moreSelect: { @@ -661,7 +662,7 @@ const handleTreeSelect = (selectedKeys: string | string[], info: any) => { } moreSelectValue.value = selectedValue; - // + // // 保存选中节点的额外属性(如 lgtd、lttd 等) if (info && typeof info === 'object') { selectedNodeExtra.value = { @@ -690,7 +691,6 @@ const handleTreeExpand = (keys: string[]) => { // 下拉选择框事件处理 const handleChange = (value: string) => { - // Handle change }; diff --git a/frontend/src/components/developStatusChart/index.vue b/frontend/src/components/developStatusChart/index.vue index 5b0fd9fb..235a8a25 100644 --- a/frontend/src/components/developStatusChart/index.vue +++ b/frontend/src/components/developStatusChart/index.vue @@ -1,49 +1,29 @@ - + \ No newline at end of file + diff --git a/frontend/src/components/engEnvironmentData/index.vue b/frontend/src/components/engEnvironmentData/index.vue index f95868b1..77bc1cd0 100644 --- a/frontend/src/components/engEnvironmentData/index.vue +++ b/frontend/src/components/engEnvironmentData/index.vue @@ -1,9 +1,6 @@ \ No newline at end of file + const baseFilters: any[] = [ + { field: 'sttpCode', operator: 'eq', dataType: 'string', value: 'ENG' }, + { field: 'bldsttCcode', operator: 'in', dataType: 'string', value: ['1', '2'] } + ]; + if (baseid.value !== 'all') { + baseFilters.unshift({ field: 'baseId', operator: 'eq', dataType: 'string', value: baseid.value }); + } + + const params1 = { + filter: { + logic: 'and', + filters: [ + ...baseFilters, + { field: 'prsc', operator: 'in', dataType: 'string', value: ['1', '2', '3'] } + ] + } + }; + + const params2 = { + filter: { + logic: 'and', + filters: [ + ...baseFilters, + { field: 'runState', operator: 'eq', dataType: 'number', value: 4 }, + { field: 'dtin', operator: 'eq', dataType: 'number', value: 1 } + ] + } + }; + + const params3 = { + filter: { + logic: 'and', + filters: [ + ...baseFilters, + { field: 'prsc', operator: 'in', dataType: 'string', value: ['1', '2', '3'] }, + { field: 'dtinEnv', operator: 'in', dataType: 'string', value: ['2'] } + ] + } + }; + + try { + dataLoading.value = true; + const [res1, res2, res3] = await Promise.all([ + getVmsstbprptKendoList(params1), + getVmsstbprptKendoList(params2), + getVmsstbprptKendoList(params3) + ]); + + const record = { one: 0, two: 0, three: 0 }; + const responses = [res1, res2, res3]; + responses.forEach((res, index) => { + const total = res?.data?.total ?? 0; + switch (index) { + case 0: + record.one = total; + break; + case 1: + record.two = total; + break; + case 2: + record.three = total; + break; + } + }); + data.value = record; + // debugger + } catch (error) { + console.error('EngEnvironmentData getData error:', error); + } finally { + dataLoading.value = false; + } +}; + +const handleItemClick = (name: string) => { + emit('item-click', { name }); +}; + +watch( + () => JidiSelectEventStore.selectedItem, + newVal => { + if (newVal && newVal.wbsCode) { + baseid.value = newVal.wbsCode; + getData(); + } + }, + { deep: true, immediate: true } +); + diff --git a/frontend/src/modules/alongFishMod/TwoLayers/Yanchengyulei.vue b/frontend/src/modules/alongFishMod/TwoLayers/Yanchengyulei.vue index 8d7f6e9f..6b43cfe6 100644 --- a/frontend/src/modules/alongFishMod/TwoLayers/Yanchengyulei.vue +++ b/frontend/src/modules/alongFishMod/TwoLayers/Yanchengyulei.vue @@ -3,15 +3,22 @@
- - + + + > + + {{ opt.label }} + + @@ -20,21 +27,35 @@ v-model:value="formState.rvcd" placeholder="请选择" style="width: 150px" - :options="lyOptions" @change="handleRvcdChange" - /> + > + + {{ opt.label }} + + - + @@ -57,11 +78,20 @@ - - + +
- + -