diff --git a/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java b/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java index ef26c1a..04a67cc 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java @@ -47,11 +47,7 @@ public class FishDraftDataController { @Operation(summary = "分页查询过鱼数据") public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { Page page = KendoUtil.getPage(dataSourceRequest); - DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); - String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); - String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status"); - String ftp = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "ftp"); - Page result = fishDraftDataService.queryPageList(page, stcd, status, ftp); + Page result = fishDraftDataService.queryPageList(page, dataSourceRequest); return ResponseResult.successData(result); } diff --git a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java index a0ece5f..cfcca39 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java @@ -2,6 +2,7 @@ package com.yfd.platform.data.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.data.domain.FishDraftData; import java.util.List; @@ -16,7 +17,7 @@ public interface IFishDraftDataService extends IService { /** * 分页查询草稿数据 */ - Page queryPageList(Page page, String stcd, String status, String ftp); + Page queryPageList(Page page, DataSourceRequest dataSourceRequest); /** * 根据审批批次ID查询 diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java index 736838a..2abf0ec 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java @@ -2,11 +2,14 @@ package com.yfd.platform.data.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.common.DataSourceLoadOptionsBase; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.mapper.FishDraftDataMapper; import com.yfd.platform.data.service.IApprovalChangeLogService; import com.yfd.platform.data.service.IApprovalMainService; import com.yfd.platform.data.service.IFishDraftDataService; +import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,14 +36,16 @@ public class FishDraftDataServiceImpl extends ServiceImpl queryPageList(Page page, String stcd, String status, String ftp) { - return this.page(page, this.lambdaQuery() - .eq(StringUtils.hasText(stcd), FishDraftData::getStcd, stcd) - .eq(StringUtils.hasText(status), FishDraftData::getStatus, status) - .like(StringUtils.hasText(ftp), FishDraftData::getFtp, ftp) - .eq(FishDraftData::getDeletedFlag, 0) - .orderByDesc(FishDraftData::getTm) - .getWrapper()); + public Page queryPageList(Page page, DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd"); + String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId"); + String direction = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "direction"); + String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status"); + + StringBuilder sql = new StringBuilder(); + return null; } @Override diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java index c39e6a0..25d4586 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java @@ -1,17 +1,19 @@ package com.yfd.platform.env.controller; import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.annotation.Log; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.env.domain.SdFishDictoryB; import com.yfd.platform.env.service.ISdFishDictoryBService; +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.Arrays; import java.util.List; /** @@ -27,30 +29,35 @@ public class SdFishDictoryBController { @Resource private ISdFishDictoryBService sdFishDictoryBService; - @GetMapping("/queryPageList") - @Operation(summary = "分页查询鱼类字典列表") - public ResponseResult queryPageList( - @RequestParam(required = false) String name, - @RequestParam(required = false) String code, - @RequestParam(required = false) Integer type, - @RequestParam(required = false) Integer rare, - @RequestParam(defaultValue = "1") Long pageNum, - @RequestParam(defaultValue = "10") Long pageSize) { - Page page = new Page<>(pageNum, pageSize); - Page result = sdFishDictoryBService.selectPage(name, code, type, rare, page); - return ResponseResult.successData(result); + @PostMapping("/queryPageList") + @Operation(summary = "分页查询鱼类字典列表(支持动态过滤和排序)") + public ResponseResult queryPageList(@RequestBody DataSourceRequest request) { + Page page = DataSourceRequestUtil.executeQuery( + request, + SdFishDictoryB.class, + sdFishDictoryBService + ); + return ResponseResult.successData(page); } - @GetMapping("/list") - @Operation(summary = "查询所有鱼类字典") - public ResponseResult list() { - return ResponseResult.successData(sdFishDictoryBService.list()); + @PostMapping("/list") + @Operation(summary = "查询鱼类字典列表(支持动态过滤和排序,不分页)") + public ResponseResult list(@RequestBody DataSourceRequest request) { + List list = DataSourceRequestUtil.executeList( + request, + SdFishDictoryB.class, + sdFishDictoryBService + ); + return ResponseResult.successData(list); } @GetMapping("/listByName") @Operation(summary = "根据名称查询所有鱼类字典") - public ResponseResult listByName( @RequestParam(required = false) String name) { - return ResponseResult.successData(sdFishDictoryBService.list(new LambdaQueryWrapper().eq(StrUtil.isNotBlank( name),SdFishDictoryB::getName, name))); + public ResponseResult listByName(@RequestParam(required = false) String name) { + return ResponseResult.successData(sdFishDictoryBService.list( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(StrUtil.isNotBlank(name), SdFishDictoryB::getName, name) + )); } @GetMapping("/getById") diff --git a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java new file mode 100644 index 0000000..08e156f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java @@ -0,0 +1,302 @@ +package com.yfd.platform.utils; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +public class DataSourceRequestUtil { + + private static final Pattern SAFE_IDENTIFIER = Pattern.compile("^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$"); + + public static Page getPage(DataSourceRequest request) { + if (request == null) { + return null; + } + int take = request.getTake(); + int skip = request.getSkip(); + if (take <= 0) { + return null; + } + Page page = new Page<>(); + page.setSize((long) take); + page.setCurrent(skip / take + 1L); + return page; + } + + public static QueryWrapper buildWrapper(DataSourceRequest request, Class entityClass) { + return buildWrapper(request, entityClass, null, null); + } + + public static QueryWrapper buildWrapper(DataSourceRequest request, Class entityClass, + Map fieldMapping, + List excludeFields) { + QueryWrapper wrapper = new QueryWrapper<>(); + + if (request == null || entityClass == null) { + return wrapper; + } + + List excludes = excludeFields != null ? excludeFields : new ArrayList<>(); + + applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and"); + + applySort(request.getSort(), wrapper, entityClass); + + return wrapper; + } + + public static QueryWrapper buildQueryWrapper(DataSourceRequest request, Class entityClass) { + return buildQueryWrapper(request, entityClass, null, null); + } + + public static QueryWrapper buildQueryWrapper(DataSourceRequest request, Class entityClass, + Map fieldMapping, + List excludeFields) { + QueryWrapper wrapper = new QueryWrapper<>(); + + if (request == null || entityClass == null) { + return wrapper; + } + + List excludes = excludeFields != null ? excludeFields : new ArrayList<>(); + + applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and"); + + applySort(request.getSort(), wrapper, entityClass); + + return wrapper; + } + + public static Page executeQuery(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service) { + return executeQuery(request, entityClass, service, null, null); + } + + public static Page executeQuery(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service, + Map fieldMapping, + List excludeFields) { + if (request == null || service == null) { + return new Page<>(); + } + + QueryWrapper wrapper = buildQueryWrapper(request, entityClass, fieldMapping, excludeFields); + Page page = getPage(request); + + if (page != null) { + return service.page(page, wrapper); + } else { + List list = service.list(wrapper); + Page resultPage = new Page<>(); + resultPage.setRecords(list); + resultPage.setTotal(list.size()); + resultPage.setSize((long) list.size()); + resultPage.setCurrent(1L); + return resultPage; + } + } + + public static List executeList(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service) { + return executeList(request, entityClass, service, null, null); + } + + public static List executeList(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service, + Map fieldMapping, + List excludeFields) { + if (request == null || service == null) { + return new ArrayList<>(); + } + + QueryWrapper wrapper = buildQueryWrapper(request, entityClass, fieldMapping, excludeFields); + return service.list(wrapper); + } + + private static void applyFilters(DataSourceRequest.FilterDescriptor filter, + QueryWrapper wrapper, + Class entityClass, + Map fieldMapping, + List excludeFields, + String parentLogic) { + if (filter == null) { + return; + } + + List filters = filter.getFilters(); + if (CollectionUtil.isEmpty(filters)) { + String field = filter.getField(); + if (StrUtil.isBlank(field)) { + return; + } + + if (excludeFields.contains(field)) { + return; + } + + String columnName = getColumnName(field, entityClass, fieldMapping); + Object value = filter.getValue(); + String operator = filter.getOperator(); + + applySingleCondition(wrapper, columnName, operator, value); + return; + } + + if (filters.size() == 1) { + applyFilters(filters.get(0), wrapper, entityClass, fieldMapping, excludeFields, parentLogic); + return; + } + + String logic = filter.getLogic(); + boolean isAnd = "and".equalsIgnoreCase(logic); + + List> conditionGroups = new ArrayList<>(); + List logics = new ArrayList<>(); + + for (int i = 0; i < filters.size(); i++) { + QueryWrapper subWrapper = new QueryWrapper<>(); + applyFilters(filters.get(i), subWrapper, entityClass, fieldMapping, excludeFields, logic); + if (hasConditions(subWrapper)) { + conditionGroups.add(subWrapper); + if (i > 0) { + logics.add(isAnd ? "and" : "or"); + } + } + } + + for (int i = 0; i < conditionGroups.size(); i++) { + if (i == 0) { + mergeWrapper(wrapper, conditionGroups.get(i)); + } else { + String lgc = logics.get(i - 1); + if ("or".equalsIgnoreCase(lgc)) { + wrapper.or(); + } + mergeWrapper(wrapper, conditionGroups.get(i)); + } + } + } + + private static boolean hasConditions(QueryWrapper wrapper) { + return wrapper instanceof QueryWrapper && !wrapper.getExpression().getNormal().isEmpty(); + } + + private static void mergeWrapper(QueryWrapper target, QueryWrapper source) { + target.getExpression().getNormal().addAll(source.getExpression().getNormal()); + } + + private static void applySingleCondition(QueryWrapper wrapper, String columnName, + String operator, Object value) { + if (columnName == null) { + return; + } + + String op = operator != null ? operator.trim().toLowerCase() : "eq"; + + switch (op) { + case "eq" -> wrapper.eq(columnName, value); + case "neq", "<>" -> wrapper.ne(columnName, value); + case "gt" -> wrapper.gt(columnName, value); + case "gte", ">=" -> wrapper.ge(columnName, value); + case "lt" -> wrapper.lt(columnName, value); + case "lte", "<=" -> wrapper.le(columnName, value); + case "contains" -> wrapper.like(columnName, value); + case "notcontains" -> wrapper.notLike(columnName, value); + case "startswith" -> wrapper.likeRight(columnName, value); + case "endswith" -> wrapper.likeLeft(columnName, value); + case "isnull" -> wrapper.isNull(columnName); + case "isnotnull" -> wrapper.isNotNull(columnName); + case "isempty" -> wrapper.eq(columnName, ""); + case "isnotempty" -> wrapper.ne(columnName, ""); + case "in" -> { + if (value instanceof Iterable) { + wrapper.in(columnName, (Iterable) value); + } else if (value instanceof Object[]) { + wrapper.in(columnName, (Object[]) value); + } + } + case "ni", "notin" -> { + if (value instanceof Iterable) { + wrapper.notIn(columnName, (Iterable) value); + } else if (value instanceof Object[]) { + wrapper.notIn(columnName, (Object[]) value); + } + } + default -> wrapper.eq(columnName, value); + } + } + + private static void applySort(List sorts, + QueryWrapper wrapper, + Class entityClass) { + if (CollectionUtil.isEmpty(sorts)) { + return; + } + + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + + String columnName = getColumnName(sort.getField(), entityClass, null); + if (columnName == null) { + continue; + } + + String dir = sort.getDir(); + if ("desc".equalsIgnoreCase(dir)) { + wrapper.orderByDesc(columnName); + } else { + wrapper.orderByAsc(columnName); + } + } + } + + private static String getColumnName(String property, Class entityClass, + Map fieldMapping) { + if (property == null || property.isBlank()) { + return null; + } + + if (fieldMapping != null && fieldMapping.containsKey(property)) { + return fieldMapping.get(property); + } + + TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); + if (tableInfo == null) { + return requireSafeIdentifier(property); + } + + if (property.equals(tableInfo.getKeyProperty())) { + return tableInfo.getKeyColumn(); + } + + List fieldInfos = tableInfo.getFieldList().stream() + .filter(f -> property.equals(f.getProperty())) + .toList(); + + if (!fieldInfos.isEmpty()) { + return fieldInfos.get(0).getColumn(); + } + + return requireSafeIdentifier(property); + } + + private static String requireSafeIdentifier(String identifier) { + String id = identifier == null ? "" : identifier.trim(); + if (id.isEmpty() || !SAFE_IDENTIFIER.matcher(id).matches()) { + return id; + } + return id; + } +} \ No newline at end of file