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 3007f7e6..e40ea660 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -210,6 +210,14 @@ public class SwaggerConfig { .build(); } + @Bean + public GroupedOpenApi groupEnvImeApi() { + return GroupedOpenApi.builder() + .group("3.12 智能装备") + .packagesToScan("com.yfd.platform.qgc_env.ime.controller") + .build(); + } + diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/ime/controller/ImeController.java b/backend/src/main/java/com/yfd/platform/qgc_env/ime/controller/ImeController.java new file mode 100644 index 00000000..1adfa227 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/ime/controller/ImeController.java @@ -0,0 +1,29 @@ +package com.yfd.platform.qgc_env.ime.controller; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_env.ime.service.ImeService; +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("/ime") +@Tag(name = "智能装备模块") +@Validated +public class ImeController { + + @Resource + private ImeService imeService; + + @PostMapping("/vmsstbprpt/GetKendoList") + @Operation(summary = "智能装备站点基础统计查询") + public ResponseResult getVmsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(imeService.getVmsstbprptList(dataSourceRequest)); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/ime/entity/vo/ImeVmsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/ime/entity/vo/ImeVmsstbprptVo.java new file mode 100644 index 00000000..2fbb3976 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/ime/entity/vo/ImeVmsstbprptVo.java @@ -0,0 +1,56 @@ +package com.yfd.platform.qgc_env.ime.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Schema(description = "智能装备站点基础统计查询") +public class ImeVmsstbprptVo { + + @Schema(description = "主键") + private String id; + + @Schema(description = "站类编码") + private String sttpCode; + + @Schema(description = "站点编码") + private String stcd; + + @Schema(description = "站点名称") + private String stnm; + + @Schema(description = "所属电站编码") + private String rstcd; + + @Schema(description = "所属电站名称") + private String ennm; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "流域编码") + private String hbrvcd; + + @Schema(description = "河流编码") + private String rvcd; + + @Schema(description = "站址/位置") + private String stlc; + + @Schema(description = "地形裁剪范围") + private String box; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "排序") + private Integer orderIndex; + + @Schema(description = "经度") + private BigDecimal lgtd; + + @Schema(description = "纬度") + private BigDecimal lttd; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/ime/service/ImeService.java b/backend/src/main/java/com/yfd/platform/qgc_env/ime/service/ImeService.java new file mode 100644 index 00000000..8c7449fd --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/ime/service/ImeService.java @@ -0,0 +1,10 @@ +package com.yfd.platform.qgc_env.ime.service; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.qgc_env.ime.entity.vo.ImeVmsstbprptVo; + +public interface ImeService { + + DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/ime/service/impl/ImeServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/ime/service/impl/ImeServiceImpl.java new file mode 100644 index 00000000..81264381 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/ime/service/impl/ImeServiceImpl.java @@ -0,0 +1,405 @@ +package com.yfd.platform.qgc_env.ime.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.GroupHelper; +import com.yfd.platform.common.GroupingInfo; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.qgc_env.ime.entity.vo.ImeVmsstbprptVo; +import com.yfd.platform.qgc_env.ime.service.ImeService; +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.List; +import java.util.Map; + +@Service +public class ImeServiceImpl implements ImeService { + + @Resource + private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + + @Override + public DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groups = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + String filterSql = buildImeVmsstbprptFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + + if (groups != null && groups.length > 0) { + return buildGroupedVmsstbprptResult(dataSourceRequest, groups, filterSql, paramMap); + } + return buildDetailVmsstbprptResult(dataSourceRequest, loadOptions, filterSql, paramMap); + } + + private DataSourceResult buildDetailVmsstbprptResult(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions, + String filterSql, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildImeVmsstbprptSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildImeVmsstbprptViewSql()) + .append(") t WHERE 1 = 1 "); + if (StrUtil.isNotBlank(filterSql)) { + sql.append("AND ").append(filterSql).append(" "); + } + sql.append(buildImeVmsstbprptOrderBySql(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, + ImeVmsstbprptVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult buildGroupedVmsstbprptResult(DataSourceRequest dataSourceRequest, + GroupingInfo[] groups, + String filterSql, + Map paramMap) { + List groupDescriptors = dataSourceRequest == null ? null : dataSourceRequest.getGroup(); + List selectItems = new ArrayList<>(); + if (CollUtil.isNotEmpty(groupDescriptors)) { + for (DataSourceRequest.GroupDescriptor descriptor : groupDescriptors) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapImeVmsstbprptColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + selectItems.add(column + " AS " + descriptor.getField()); + selectItems.add("COUNT(1) AS count_" + descriptor.getField()); + } + } + if (selectItems.isEmpty()) { + selectItems.add("t.sttpCode AS sttpCode"); + selectItems.add("COUNT(1) AS count_sttpCode"); + } + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildImeVmsstbprptViewSql()) + .append(") t ") + .append("WHERE 1 = 1 "); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + List groupByColumns = new ArrayList<>(); + if (CollUtil.isNotEmpty(groupDescriptors)) { + for (DataSourceRequest.GroupDescriptor descriptor : groupDescriptors) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapImeVmsstbprptColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)); + } else { + sql.append(" GROUP BY t.sttpCode "); + } + sql.append(buildImeVmsstbprptGroupOrderBySql(groupDescriptors)); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groups))); + result.setTotal((long) rows.size()); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groups))); + result.setTotal((long) rows.size()); + } + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildImeVmsstbprptGroupOrderBySql(List groups) { + if (CollUtil.isEmpty(groups)) { + return " ORDER BY t.sttpCode ASC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor group : groups) { + if (group == null || StrUtil.isBlank(group.getField())) { + continue; + } + String column = mapImeVmsstbprptColumn(group.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(group.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + direction); + } + if (orderItems.isEmpty()) { + return " ORDER BY t.sttpCode ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildImeVmsstbprptViewSql() { + return "SELECT " + + "src.STCD AS id, " + + "src.STTP_CODE AS sttpCode, " + + "src.STLC AS stlc, " + + "src.STCD AS stcd, " + + "src.STNM AS stnm, " + + "src.BOX AS box, " + + "src.RSTCD AS rstcd, " + + "src.ENNM AS ennm, " + + "src.BASE_ID AS baseId, " + + "src.BASE_NAME AS baseName, " + + "src.HBRVCD AS hbrvcd, " + + "src.RVCD AS rvcd, " + + "src.ORDER_INDEX AS orderIndex, " + + "src.LGTD AS lgtd, " + + "src.LTTD AS lttd " + + "FROM V_MS_STBPRP_T src " + + "WHERE 1=1 " + + "AND NVL(src.IS_DELETED, 0) = 0"; + } + + private String buildImeVmsstbprptSelectSql(List selectFields) { + Map columns = imeVmsstbprptFieldColumns(); + List selected = new ArrayList<>(); + if (CollUtil.isEmpty(selectFields)) { + selected.add("t.*"); + } else { + for (String field : selectFields) { + String column = columns.get(field); + if (StrUtil.isNotBlank(column)) { + selected.add(column); + } + } + } + if (selected.isEmpty()) { + selected.add("t.sttpCode AS sttpCode"); + selected.add("t.stnm AS stnm"); + selected.add("t.stcd AS stcd"); + } + return String.join(", ", selected); + } + + private Map imeVmsstbprptFieldColumns() { + Map columns = new LinkedHashMap<>(); + columns.put("id", "t.id AS id"); + columns.put("sttpCode", "t.sttpCode AS sttpCode"); + columns.put("stcd", "t.stcd AS stcd"); + columns.put("stnm", "t.stnm AS stnm"); + columns.put("rstcd", "t.rstcd AS rstcd"); + columns.put("ennm", "t.ennm AS ennm"); + columns.put("baseId", "t.baseId AS baseId"); + columns.put("hbrvcd", "t.hbrvcd AS hbrvcd"); + columns.put("rvcd", "t.rvcd AS rvcd"); + columns.put("orderIndex", "t.orderIndex AS orderIndex"); + columns.put("lgtd", "t.lgtd AS lgtd"); + columns.put("lttd", "t.lttd AS lttd"); + return columns; + } + + private String buildImeVmsstbprptFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildImeVmsstbprptLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildImeVmsstbprptFilterCondition(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 buildImeVmsstbprptLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapImeVmsstbprptColumn(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 = normalizeImeVmsstbprptValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object value : values) { + if (value == null || StrUtil.isBlank(String.valueOf(value).trim())) { + continue; + } + String key = "imeVmsstbprptP" + indexHolder[0]++; + paramMap.put(key, String.valueOf(value).trim()); + placeholders.add("#{map." + key + "}"); + } + if (placeholders.isEmpty()) { + return ""; + } + return column + ("ni".equals(operator) ? " NOT IN (" : " IN (") + String.join(", ", placeholders) + ")"; + } + Object rawValue = filter.getValue(); + if (rawValue == null || StrUtil.isBlank(String.valueOf(rawValue).trim())) { + return ""; + } + String key = "imeVmsstbprptP" + indexHolder[0]++; + String text = String.valueOf(rawValue).trim(); + return switch (operator) { + case "eq" -> { + paramMap.put(key, text); + yield column + " = #{map." + key + "}"; + } + case "neq" -> { + paramMap.put(key, text); + yield column + " <> #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, text); + yield column + " > #{map." + key + "}"; + } + case "gte" -> { + paramMap.put(key, text); + yield column + " >= #{map." + key + "}"; + } + case "lt" -> { + paramMap.put(key, text); + yield column + " < #{map." + key + "}"; + } + case "lte" -> { + paramMap.put(key, text); + yield column + " <= #{map." + key + "}"; + } + case "contains" -> { + paramMap.put(key, "%" + text + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + text + "%"); + yield column + " NOT LIKE #{map." + key + "}"; + } + default -> ""; + }; + } + + private String mapImeVmsstbprptColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "id" -> "t.id"; + case "sttpCode" -> "t.sttpCode"; + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "rstcd" -> "t.rstcd"; + case "ennm" -> "t.ennm"; + case "baseId" -> "t.baseId"; + case "hbrvcd" -> "t.hbrvcd"; + case "rvcd" -> "t.rvcd"; + case "orderIndex" -> "t.orderIndex"; + case "lgtd" -> "t.lgtd"; + case "lttd" -> "t.lttd"; + default -> null; + }; + } + + private String buildImeVmsstbprptOrderBySql(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 = mapImeVmsstbprptColumn(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 List normalizeImeVmsstbprptValues(Object value) { + List values = new ArrayList<>(); + appendImeVmsstbprptValues(values, value); + return values; + } + + private void appendImeVmsstbprptValues(List values, Object value) { + if (value == null) { + return; + } + if (value instanceof Iterable iterable) { + for (Object item : iterable) { + appendImeVmsstbprptValues(values, item); + } + return; + } + if (value.getClass().isArray()) { + Object[] array = (Object[]) value; + for (Object item : array) { + appendImeVmsstbprptValues(values, item); + } + return; + } + values.add(value); + } +} \ No newline at end of file