attachmentIds) {
+ for (String id : attachmentIds) {
+ if (StrUtil.isNotBlank(id)) {
+ attachmentUploadService.deleteFile(id);
+ }
+ }
+ }
+}
diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/SdFpssR.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/SdFpssR.java
index 7688ff15..a3f303f4 100644
--- a/backend/src/main/java/com/yfd/platform/qgc_base/domain/SdFpssR.java
+++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/SdFpssR.java
@@ -1,8 +1,11 @@
package com.yfd.platform.qgc_base.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 com.fasterxml.jackson.annotation.JsonFormat;
+import com.yfd.platform.annotation.FieldChinese;
import lombok.Data;
import java.io.Serializable;
@@ -24,121 +27,159 @@ public class SdFpssR implements Serializable {
* 主键ID
*/
@TableId(type = IdType.ASSIGN_UUID)
+ @FieldChinese("主键ID")
private String id;
/**
* 过鱼设施编码
*/
+ @FieldChinese("过鱼设施编码")
private String stcd;
/**
* 填报时间
*/
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @FieldChinese("填报时间")
private Date tm;
/**
* 鱼种类
*/
+ @FieldChinese("鱼种类")
private String ftp;
+ @TableField(exist = false)
+ private String ftpName;
+
/**
* 鱼类规格,单位:cm
*/
+ @FieldChinese("鱼类规格")
private String fsz;
/**
* 过鱼数量,单位:尾
*/
+ @FieldChinese("过鱼数量")
private Integer fcnt;
/**
* 平均体重,单位:g
*/
+ @FieldChinese("平均体重")
private String fwet;
/**
* 开始日期
*/
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @FieldChinese("开始日期")
private Date strdt;
/**
* 结束日期
*/
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @FieldChinese("结束日期")
private Date enddt;
/**
* 游向:0=上行,1=下行,2=上行折返,3=下行折返
*/
+ @FieldChinese("游向")
private Integer direction;
/**
* 当日运行次数
*/
+ @FieldChinese("当日运行次数")
private Integer rcnt;
/**
* 过鱼设施引用流量
*/
+ @FieldChinese("过鱼设施引用流量")
private BigDecimal fq;
/**
* 过鱼图片文件路径
*/
+ @FieldChinese("过鱼图片文件路径")
private String picpth;
/**
* 过鱼视频文件路径
*/
+ @FieldChinese("过鱼视频文件路径")
private String vdpth;
/**
* 年份:数据时间,精确到年
*/
+ @FieldChinese("年份")
private Integer yr;
/**
* 主要月份
*/
+ @FieldChinese("主要月份")
private String mouth;
/**
* 创建人
*/
+ @FieldChinese("创建人")
private String recordUser;
/**
* 创建时间
*/
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @FieldChinese("创建时间")
private Date recordTime;
/**
* 更新人
*/
+ @FieldChinese("更新人")
private String modifyUser;
/**
* 更新时间
*/
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @FieldChinese("更新时间")
private Date modifyTime;
/**
* 是否已删除:0=未删除 1=已删除
*/
+ @FieldChinese("是否已删除")
private Integer isDeleted;
/**
* 删除人
*/
+ @FieldChinese("删除人")
private String deleteUser;
/**
* 删除时间
*/
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @FieldChinese("删除时间")
private Date deleteTime;
/**
* 是否鱼苗(0否 1是)
*/
+ @FieldChinese("是否鱼苗")
private Integer isfs;
-}
\ No newline at end of file
+ /**
+ * 水温:单位:℃
+ */
+ @FieldChinese("水温")
+ private BigDecimal wtmp;
+}
diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssRService.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssRService.java
index 1af560d0..4e4864ab 100644
--- a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssRService.java
+++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssRService.java
@@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yfd.platform.qgc_base.domain.SdFpssR;
+import java.util.List;
+import java.util.Map;
+
/**
*
* 过鱼设施人工数据表 服务类
@@ -15,4 +18,19 @@ public interface ISdFpssRService extends IService {
* 分页查询过鱼数据
*/
Page queryPageList(Page page, String stcd, Integer yr, String ftp);
-}
\ No newline at end of file
+
+ /**
+ * 新增过鱼数据
+ */
+ boolean add(SdFpssR entity, String source);
+
+ /**
+ * 修改过鱼数据(按前端 patch 显式更新字段,含 null 置空)
+ */
+ boolean update(Map engInfoPatch, String source) throws Exception;
+
+ /**
+ * 删除过鱼数据(逻辑删除)
+ */
+ boolean delete(List ids, String source);
+}
diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssRServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssRServiceImpl.java
index 597aeb99..7d9dff9d 100644
--- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssRServiceImpl.java
+++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssRServiceImpl.java
@@ -1,15 +1,27 @@
package com.yfd.platform.qgc_base.service.impl;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.qgc_base.domain.SdFpssR;
import com.yfd.platform.qgc_base.mapper.SdFpssRMapper;
+import com.yfd.platform.qgc_base.service.IMsOperationLogService;
import com.yfd.platform.qgc_base.service.ISdFpssRService;
+import com.yfd.platform.utils.CodeToNameMetadataBo;
+import com.yfd.platform.utils.DictCodeToNameConverter;
+import com.yfd.platform.utils.SecurityUtils;
+import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
*
@@ -19,6 +31,30 @@ import java.util.Date;
@Service
public class SdFpssRServiceImpl extends ServiceImpl implements ISdFpssRService {
+ private static final String TABLE_NAME = "SD_FPSS_R";
+
+ @Resource
+ private IMsOperationLogService msOperationLogService;
+
+ @Resource
+ private DictCodeToNameConverter dictCodeToNameConverter;
+
+ @Resource
+ private PatchUpdateHelper patchUpdateHelper;
+
+ private static final Set TRANSIENT_FIELDS = Set.of("ftpName", "serialVersionUID");
+
+ /**
+ * 代码转名称元数据配置列表
+ */
+ private static final List CODE_TO_NAME_META_LIST = new ArrayList<>();
+
+ static {
+ CODE_TO_NAME_META_LIST.add(CodeToNameMetadataBo.builder().codeProperty("ftp").modifyProperty("ftpName")
+ .dictType("DYNAMIC").dictSource("SD_FISHDICTORY_B").codeColumn("ID").nameColumn("NAME")
+ .filter("NVL(IS_DELETED, 0) = 0 AND NVL(ENABLE, 1) = 1").build());
+ }
+
@Override
public Page queryPageList(Page page, String stcd, Integer yr, String ftp) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
@@ -35,7 +71,9 @@ public class SdFpssRServiceImpl extends ServiceImpl impl
wrapper.eq(SdFpssR::getIsDeleted, 0);
wrapper.orderByDesc(SdFpssR::getRecordTime);
- return page(page, wrapper);
+ Page result = page(page, wrapper);
+ dictCodeToNameConverter.convertCodeToName(result, CODE_TO_NAME_META_LIST);
+ return result;
}
@Override
@@ -51,14 +89,50 @@ public class SdFpssRServiceImpl extends ServiceImpl impl
return super.updateById(entity);
}
-// @Override
-// public boolean removeById(Object id) {
-// SdFpssR entity = getById(id);
-// if (entity != null) {
-// entity.setIsDeleted(1);
-// entity.setDeleteTime(new Date());
-// return updateById(entity);
-// }
-// return false;
-// }
-}
\ No newline at end of file
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public boolean add(SdFpssR entity, String source) {
+ if (entity == null || StrUtil.isBlank(entity.getStcd())) {
+ throw new com.yfd.platform.common.exception.BizException("过鱼设施编码不能为空");
+ }
+ boolean result = this.save(entity);
+ if (result) {
+ dictCodeToNameConverter.convertCodeToName(entity, CODE_TO_NAME_META_LIST);
+ msOperationLogService.recordAddDetailLog(entity.getId(), TABLE_NAME, entity, source, CODE_TO_NAME_META_LIST);
+ }
+ return result;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public boolean update(Map engInfoPatch, String source) throws Exception {
+ return patchUpdateHelper.execute(this, engInfoPatch, source, TABLE_NAME, SdFpssR.class,
+ TRANSIENT_FIELDS, CODE_TO_NAME_META_LIST, "id");
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public boolean delete(List ids, String source) {
+ if (ids == null || ids.isEmpty()) {
+ return false;
+ }
+ int count = 0;
+ for (String id : ids) {
+ SdFpssR entity = this.getById(id);
+ if (entity == null) {
+ continue;
+ }
+ LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
+ wrapper.eq(SdFpssR::getId, id);
+ wrapper.set(SdFpssR::getIsDeleted, 1);
+ wrapper.set(SdFpssR::getDeleteUser, SecurityUtils.getCurrentUsername());
+ wrapper.set(SdFpssR::getDeleteTime, new Date());
+ if (this.update(wrapper)) {
+ dictCodeToNameConverter.convertCodeToName(entity, CODE_TO_NAME_META_LIST);
+ msOperationLogService.recordDeleteDetailLog(id, TABLE_NAME, entity, source, CODE_TO_NAME_META_LIST);
+ count++;
+ }
+ }
+ return count > 0;
+ }
+}
diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java
index de386059..3eb2be97 100644
--- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java
+++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java
@@ -982,7 +982,7 @@ public class FpBuildServiceImpl implements FpBuildService {
columnMap.put("jbtxcs", "fp.JBTXCS");
columnMap.put("isUp", "fp.IS_UP");
columnMap.put("isDown", "fp.IS_DOWN");
- columnMap.put("mway", "NULL");
+ columnMap.put("mway", "fp.MWAY");
columnMap.put("mwayName", "NULL");
columnMap.put("remark", "fp.REMARK");
columnMap.put("vlsr", "fp.VLSR");
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 126f32dd..26a7de22 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
@@ -53,6 +53,12 @@ public class VapConstructionController {
return ResponseResult.successData(vpConstructionService.processBasinVplntKendoList(dataSourceRequest));
}
+ @PostMapping("/bcount/GetKendoListCust")
+ @Operation(summary = "流域-珍稀植物园运行数据统计(SD_VP_R 按种类聚合)")
+ public ResponseResult getBasinCountKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
+ return ResponseResult.successData(vpConstructionService.processBasinCountKendoList(dataSourceRequest));
+ }
+
@PostMapping("/wva/GetKendoListCust")
@Operation(summary = "野生动物监测情况")
public ResponseResult getWvaKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinCountVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinCountVo.java
new file mode 100644
index 00000000..c3c0dd48
--- /dev/null
+++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinCountVo.java
@@ -0,0 +1,59 @@
+package com.yfd.platform.qgc_env.vap.entity.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 流域-珍稀植物园运行数据统计 VO(对应旧系统 CountVplnt/BasinVplnt 统计)
+ */
+@Data
+@Schema(description = "流域-珍稀植物园运行数据统计")
+public class VpBasinCountVo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "植物园编码")
+ private String stcd;
+
+ @Schema(description = "所属电站编码")
+ private String rstcd;
+
+ @Schema(description = "电站名称")
+ private String ennm;
+
+ @Schema(description = "基地编码")
+ private String baseId;
+
+ @Schema(description = "基地名称")
+ private String baseName;
+
+ @Schema(description = "保护种类ID")
+ private String plantId;
+
+ @Schema(description = "分类:1=花 2=草 3=树")
+ private BigDecimal unit;
+
+ @Schema(description = "保护种类名称")
+ private String name;
+
+ @Schema(description = "年份")
+ private String year;
+
+ @Schema(description = "总数量")
+ private BigDecimal tecnt;
+
+ @Schema(description = "存活数量")
+ private BigDecimal surnum;
+
+ @Schema(description = "移栽规模")
+ private BigDecimal transplant;
+
+ @Schema(description = "种植要求")
+ private BigDecimal plantask;
+
+ @Schema(description = "存活率(%)")
+ private String rate;
+}
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 5a368a86..d9e8facc 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
@@ -4,6 +4,7 @@ import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.common.DataSourceResult;
import com.yfd.platform.qgc_env.vap.entity.vo.FhvapBuiltPointVo;
import com.yfd.platform.qgc_env.vap.entity.vo.WvaPointVo;
+import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinCountVo;
import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinIntDetailVo;
import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinVplntVo;
import com.yfd.platform.qgc_env.vap.entity.vo.VpVarVo;
@@ -23,6 +24,8 @@ public interface VpConstructionService {
DataSourceResult processBasinVplntKendoList(DataSourceRequest dataSourceRequest);
+ DataSourceResult processBasinCountKendoList(DataSourceRequest dataSourceRequest);
+
DataSourceResult processWvaKendoList(DataSourceRequest dataSourceRequest);
DataSourceResult processVacKendoList(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 2126f855..958dfd6a 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
@@ -11,6 +11,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper;
import com.yfd.platform.common.PageInfo;
import com.yfd.platform.qgc_env.vap.entity.vo.FhvapBuiltPointVo;
import com.yfd.platform.qgc_env.vap.entity.vo.WvaPointVo;
+import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinCountVo;
import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinIntDetailVo;
import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinVplntVo;
import com.yfd.platform.qgc_env.vap.entity.vo.VpConstructionSituationVo;
@@ -185,6 +186,63 @@ public class VpConstructionServiceImpl implements VpConstructionService {
return queryBasinVplntGroupList(dataSourceRequest, loadOptions);
}
+ @Override
+ public DataSourceResult processBasinCountKendoList(DataSourceRequest dataSourceRequest) {
+ DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
+ String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd");
+ String baseId = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId");
+ String rstcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd");
+ String tm = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "tm");
+
+ StringBuilder sqlB = new StringBuilder();
+ sqlB.append("SELECT r.STCD AS stcd, " +
+ "MAX(t.RSTCD) AS rstcd, " +
+ "MAX(t.ENNM) AS ennm, " +
+ "MAX(t.BASE_ID) AS baseId, " +
+ "MAX(t.BASE_NAME) AS baseName, " +
+ "r.PLANT_ID AS plantId, " +
+ "r.TYPE AS unit, " +
+ "b.NAME AS name, ");
+ if (StrUtil.isNotBlank(tm)) {
+ sqlB.append(" '").append(tm).append("' AS year, ");
+ }
+ sqlB.append("SUM(r.TECNT) AS tecnt, SUM(r.SURNUM) AS surnum, SUM(r.TRANSPLANT) AS transplant, SUM(r.PLANTASK) AS plantask, " +
+ "CASE WHEN SUM(r.TRANSPLANT) != 0 THEN TO_CHAR(ROUND(SUM(r.SURNUM) / SUM(r.TRANSPLANT) * 100, 2)) ELSE '-' END AS rate " +
+ "FROM SD_VP_R r " +
+ "INNER JOIN V_MS_STBPRP_T t ON r.STCD = t.STCD AND t.DATA_SOURCE = 'SD_VP_B_H' " +
+ "LEFT JOIN SD_VPBASIC_B b ON r.PLANT_ID = b.ID " +
+ "WHERE NVL(r.IS_DELETED, 0) = 0 AND NVL(t.IS_DELETED, 0) = 0 ");
+
+ Map paramMap = new HashMap<>();
+ if (StrUtil.isNotBlank(baseId)) {
+ sqlB.append(" AND t.BASE_ID = #{map.baseId} ");
+ paramMap.put("baseId", baseId);
+ }
+ if (StrUtil.isNotBlank(stcd)) {
+ sqlB.append(" AND t.STCD = #{map.stcd} ");
+ paramMap.put("stcd", stcd);
+ }
+ if (StrUtil.isNotBlank(rstcd)) {
+ sqlB.append(" AND t.RSTCD = #{map.rstcd} ");
+ paramMap.put("rstcd", rstcd);
+ }
+ if (StrUtil.isNotBlank(tm)) {
+ sqlB.append(" AND TO_CHAR(r.TM, 'yyyy') = #{map.tm} ");
+ paramMap.put("tm", tm);
+ }
+ sqlB.append("GROUP BY r.STCD, r.PLANT_ID, b.NAME, r.TYPE");
+
+ Page> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
+ List list = microservicDynamicSQLMapper.pageAllListWithResultType(
+ page, sqlB.toString(), paramMap, VpBasinCountVo.class
+ );
+ DataSourceResult result = new DataSourceResult<>();
+ result.setData(list);
+ result.setTotal(page != null ? page.getTotal() : list.size());
+ result.setAggregates(new HashMap<>());
+ return result;
+ }
+
private DataSourceResult queryBasinVplntDetailList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
StringBuilder sql = new StringBuilder();