From 46902f2a7cfaf230dcb73435f458f7fef1d41ef1 Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 30 Jul 2026 11:49:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=B1=BC=E7=97=85=E9=98=B2=E6=B2=BB?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=88=97=E8=A1=A8?= 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/FbFishdpacRVo.java | 79 ++++++ .../qgc_env/fb/service/FbStationService.java | 36 +-- .../fb/service/impl/FbStationServiceImpl.java | 255 ++++++++++++++++++ 4 files changed, 346 insertions(+), 30 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbFishdpacRVo.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 f849743f..71aeb46f 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 @@ -137,6 +137,12 @@ public class FbStationController { return ResponseResult.successData(fbStationService.getFishbreedRList(dataSourceRequest)); } + @PostMapping("/fishdpacr/GetKendoListCust") + @Operation(summary = "鱼病防治记录列表") + public ResponseResult getFishdpacRKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getFishdpacRList(dataSourceRequest)); + } + @PostMapping("/bsmfr/qgc/GetKendoListCust") @Operation(summary = "(全过程)增殖站二级页面: 亲鱼选配与培育->亲鱼信息") public ResponseResult getBsmfrQgcKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbFishdpacRVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbFishdpacRVo.java new file mode 100644 index 00000000..dd97385c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbFishdpacRVo.java @@ -0,0 +1,79 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 鱼病防治记录表 VO + */ +@Data +public class FbFishdpacRVo { + + /** 主键 */ + private String id; + + /** 设施编码 */ + private String stcd; + + /** 鱼池编号 */ + private String fpnum; + + /** 鱼种类 */ + private String ftp; + + /** 平均体重(g) */ + private BigDecimal weight; + + /** 发病症状 */ + private String symptoms; + + /** 鱼药种类 */ + private String fishdrugtype; + + /** 用药方法 */ + private Integer method; + + /** 用药剂量(mg/kg) */ + private BigDecimal dose; + + /** 用药天数(d) */ + private BigDecimal days; + + /** 治疗效果 */ + private Integer treateffect; + + /** 记录人 */ + private String recorder; + + /** 日期 */ + private Date tm; + + /** 附件ID */ + private String fid; + + /** 备注 */ + private String remark; + + /** 创建人 */ + private String recordUser; + + /** 创建时间 */ + private Date recordTime; + + /** 更新人 */ + private String modifyUser; + + /** 更新时间 */ + private Date modifyTime; + + /** 是否已删除 */ + private Integer isDeleted; + + /** 删除人 */ + private String deleteUser; + + /** 删除时间 */ + private Date deleteTime; +} 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 e0bd8f73..da2ef0e6 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 @@ -2,36 +2,7 @@ package com.yfd.platform.qgc_env.fb.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; -import com.yfd.platform.qgc_env.fb.entity.vo.BreedStageVO; -import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbBsdeathRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbBsctmoBVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFbbwtRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFbcwqRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbBsrfiRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbOutfishRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishartinlRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishhatchrecRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishhatchproRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbScwemRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishbreedRVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRQgcVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRFishTableVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbEngFishVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFlDataVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishCountFinishVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishRunQgcVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishTypeStcdVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbFishTypeFinishVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbRelatedYrVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbMsfbrdmQgcVo; -import com.yfd.platform.qgc_env.fb.entity.vo.FbResearchVo; -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.FbTracingPointVo; -import com.yfd.platform.qgc_env.fb.entity.vo.TableVo; +import com.yfd.platform.qgc_env.fb.entity.vo.*; import java.util.List; import java.util.Map; @@ -156,4 +127,9 @@ public interface FbStationService { * 鱼苗和鱼种培育记录列表 */ DataSourceResult getFishbreedRList(DataSourceRequest dataSourceRequest); + + /** + * 鱼病防治记录列表 + */ + DataSourceResult getFishdpacRList(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 99170aff..80f8b9b0 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 @@ -24,6 +24,7 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbFishhatchrecRVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbFishhatchproRVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbScwemRVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbFishbreedRVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FbFishdpacRVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRQgcVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRFishHeadColumnVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRFishSummaryVo; @@ -8360,4 +8361,258 @@ public class FbStationServiceImpl implements FbStationService { } return value; } + + // ==================== 鱼病防治记录 (SD_FBFISHDPAC_R) ==================== + + @Override + public DataSourceResult getFishdpacRList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groups = loadOptions == null ? null : loadOptions.getGroup(); + if (groups != null && groups.length > 0) { + return queryFishdpacRGroupList(dataSourceRequest, loadOptions, groups); + } + return queryFishdpacRDetailList(dataSourceRequest, loadOptions); + } + + private DataSourceResult queryFishdpacRDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildFishdpacRDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildFishdpacRCoreSql()) + .append(") t WHERE 1 = 1 "); + String filterSql = buildFishdpacRFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildFishdpacROrderBySql(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, FbFishdpacRVo.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private DataSourceResult queryFishdpacRGroupList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions, + GroupingInfo[] groupInfos) { + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT * FROM (") + .append(buildFishdpacRCoreSql()) + .append(") t WHERE 1 = 1 "); + String filterSql = buildFishdpacRFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + String groupedSql = buildFishdpacRGroupSql(sql.toString(), + dataSourceRequest == null ? null : dataSourceRequest.getGroup()); + List> rows = microservicDynamicSQLMapper.pageAllList( + null, groupedSql, paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(dataSourceRequest == null ? false : dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup( + rows, groupInfos == null ? Collections.emptyList() : Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group( + rows, groupInfos == null ? Collections.emptyList() : Arrays.asList(groupInfos))); + } + result.setTotal(rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildFishdpacRCoreSql() { + return "SELECT ID AS id, " + + "STCD AS stcd, " + + "FPNUM AS fpnum, " + + "FTP AS ftp, " + + "WEIGHT AS weight, " + + "SYMPTOMS AS symptoms, " + + "FISHDRUGTYPE AS fishdrugtype, " + + "METHOD AS method, " + + "DOSE AS dose, " + + "DAYS AS days, " + + "TREATEFFECT AS treateffect, " + + "RECORDER AS recorder, " + + "TM AS tm, " + + "FID AS fid, " + + "REMARK AS remark, " + + "RECORD_USER AS recordUser, " + + "RECORD_TIME AS recordTime, " + + "MODIFY_USER AS modifyUser, " + + "MODIFY_TIME AS modifyTime, " + + "IS_DELETED AS isDeleted, " + + "DELETE_USER AS deleteUser, " + + "DELETE_TIME AS deleteTime " + + "FROM SD_FBFISHDPAC_R " + + "WHERE NVL(IS_DELETED, 0) = 0"; + } + + private String buildFishdpacRDetailSelectSql(List select) { + List fields = CollUtil.isEmpty(select) + ? List.of("id", "stcd", "fpnum", "ftp", "weight", "symptoms", + "fishdrugtype", "method", "dose", "days", "treateffect", "recorder", "tm", "fid", "remark", + "recordUser", "recordTime", "modifyUser", "modifyTime", "isDeleted", "deleteUser", "deleteTime") + : select; + List selectParts = new ArrayList<>(); + for (String field : fields) { + String column = mapFishdpacRColumn(field); + if (StrUtil.isNotBlank(column)) { + selectParts.add(column + " AS " + field); + } + } + if (selectParts.isEmpty()) { + selectParts.add("t.id AS id"); + } + return String.join(", ", selectParts); + } + + private String buildFishdpacRFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) return ""; + if (StrUtil.isNotBlank(filter.getField())) return buildFishdpacRLeafCondition(filter, paramMap, indexHolder); + if (CollUtil.isEmpty(filter.getFilters())) return ""; + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFishdpacRFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) conditions.add("(" + childSql + ")"); + } + if (conditions.isEmpty()) return ""; + return String.join("or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND ", conditions); + } + + private String buildFishdpacRLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapFishdpacRColumn(filter.getField()); + 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 = normalizeFishdpacRValues(value); + if (values.isEmpty()) return ""; + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "fdpP" + indexHolder[0]++; + paramMap.put(key, normalizeFishdpacRValue(filter.getField(), item)); + placeholders.add("#{map." + key + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) return ""; + String key = "fdpP" + indexHolder[0]++; + Object normalizedValue = normalizeFishdpacRValue(filter.getField(), 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 "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 + "}"; } + case "contains" -> { paramMap.put(key, "%" + normalizedValue + "%"); yield column + " LIKE #{map." + key + "}"; } + case "doesnotcontain" -> { paramMap.put(key, "%" + normalizedValue + "%"); yield column + " NOT 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 + "}"; } + default -> ""; + }; + } + + private String buildFishdpacROrderBySql(List sortDescriptors) { + if (CollUtil.isEmpty(sortDescriptors)) return " ORDER BY t.tm DESC"; + List parts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor descriptor : sortDescriptors) { + String column = mapFishdpacRColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) continue; + parts.add(column + ("desc".equalsIgnoreCase(descriptor.getDir()) ? " DESC" : " ASC")); + } + if (parts.isEmpty()) return " ORDER BY t.tm DESC"; + return " ORDER BY " + String.join(", ", parts); + } + + private String buildFishdpacRGroupSql(String baseSql, List groups) { + if (CollUtil.isEmpty(groups)) return baseSql; + List validGroups = groups.stream() + .filter(group -> StrUtil.isNotBlank(mapFishdpacRColumn(group.getField()))).toList(); + if (validGroups.isEmpty()) return baseSql; + List groupFields = validGroups.stream().map(DataSourceRequest.GroupDescriptor::getField).toList(); + StringBuilder sql = new StringBuilder("SELECT "); + for (int i = 0; i < groupFields.size(); i++) { + if (i > 0) sql.append(", "); + sql.append("t.").append(groupFields.get(i)).append(" AS ").append(groupFields.get(i)); + } + sql.append(", COUNT(1) AS \"aggregates.count\" FROM (").append(baseSql).append(") t GROUP BY "); + for (int i = 0; i < groupFields.size(); i++) { + if (i > 0) sql.append(", "); + sql.append("t.").append(groupFields.get(i)); + } + return sql.toString(); + } + + private String mapFishdpacRColumn(String field) { + return switch (field) { + case "id" -> "t.id"; + case "stcd" -> "t.stcd"; + case "fpnum" -> "t.fpnum"; + case "ftp" -> "t.ftp"; + case "weight" -> "t.weight"; + case "symptoms" -> "t.symptoms"; + case "fishdrugtype" -> "t.fishdrugtype"; + case "method" -> "t.method"; + case "dose" -> "t.dose"; + case "days" -> "t.days"; + case "treateffect" -> "t.treateffect"; + case "recorder" -> "t.recorder"; + case "tm" -> "t.tm"; + case "fid" -> "t.fid"; + case "remark" -> "t.remark"; + case "recordUser" -> "t.recordUser"; + case "recordTime" -> "t.recordTime"; + case "modifyUser" -> "t.modifyUser"; + case "modifyTime" -> "t.modifyTime"; + case "isDeleted" -> "t.isDeleted"; + case "deleteUser" -> "t.deleteUser"; + case "deleteTime" -> "t.deleteTime"; + default -> ""; + }; + } + + private List normalizeFishdpacRValues(Object value) { + List values = new ArrayList<>(); + if (value == null) return values; + if (value instanceof Collection collection) { values.addAll(collection); return values; } + if (value instanceof Object[] array) { values.addAll(Arrays.asList(array)); return values; } + String text = String.valueOf(value).trim(); + if (text.startsWith("[") && text.endsWith("]")) text = text.substring(1, text.length() - 1); + if (text.contains(",")) { + for (String item : text.split(",")) { + String trimmed = StrUtil.trim(item); + if (StrUtil.isNotBlank(trimmed)) values.add(trimmed); + } + return values; + } + values.add(value); + return values; + } + + private Object normalizeFishdpacRValue(String field, Object value) { + if (value == null) return null; + if (Set.of("tm", "recordTime", "modifyTime", "deleteTime").contains(field) && value instanceof String text) { + return parseDateTimeSafely(text); + } + return value; + } }