fix: 删除全过程鱼类放鱼明细数据&全过程鱼类放鱼数据明细
This commit is contained in:
parent
bb7ec04a38
commit
4c500b1fd8
@ -214,6 +214,12 @@ public class FbStationController {
|
|||||||
return ResponseResult.successData(fbStationService.getFishRunQgcKendoListCust(dataSourceRequest));
|
return ResponseResult.successData(fbStationService.getFishRunQgcKendoListCust(dataSourceRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/fishrun/qgc/detail/GetKendoListCust")
|
||||||
|
@Operation(summary = "全过程鱼类放鱼数据明细(细粒度,按站点+年份+鱼种下钻)")
|
||||||
|
public ResponseResult getFishRunQgcDetailKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||||
|
return ResponseResult.successData(fbStationService.getFishRunQgcDetailKendoListCust(dataSourceRequest));
|
||||||
|
}
|
||||||
|
|
||||||
@Log(module = "鱼类增殖站模块", value = "删除全过程鱼类放鱼数据")
|
@Log(module = "鱼类增殖站模块", value = "删除全过程鱼类放鱼数据")
|
||||||
@PostMapping("/fishrun/qgc/removeFishRunQgcData")
|
@PostMapping("/fishrun/qgc/removeFishRunQgcData")
|
||||||
@Operation(summary = "删除全过程鱼类放鱼数据(按站点+年份+鱼种)")
|
@Operation(summary = "删除全过程鱼类放鱼数据(按站点+年份+鱼种)")
|
||||||
@ -222,6 +228,14 @@ public class FbStationController {
|
|||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Log(module = "鱼类增殖站模块", value = "删除全过程鱼类放鱼明细数据")
|
||||||
|
@PostMapping("/fishrun/qgc/removeFishRunQgcDetailData")
|
||||||
|
@Operation(summary = "删除全过程鱼类放鱼明细数据(按明细ID批量)")
|
||||||
|
public ResponseResult removeFishRunQgcDetailData(@RequestBody List<String> ids) {
|
||||||
|
fbStationService.removeFishRunQgcDetailData(ids);
|
||||||
|
return ResponseResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/fishType/GetKendoListCust")
|
@PostMapping("/fishType/GetKendoListCust")
|
||||||
@Operation(summary = "增殖站鱼种完成情况统计")
|
@Operation(summary = "增殖站鱼种完成情况统计")
|
||||||
public ResponseResult getFishTypeKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
public ResponseResult getFishTypeKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||||
|
|||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.yfd.platform.qgc_env.fb.entity.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全过程鱼类放鱼数据明细(细粒度),对应 SD_RPIMNFISH_R 明细行。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "全过程鱼类放鱼数据明细")
|
||||||
|
public class FbFishRunQgcDetailVo {
|
||||||
|
|
||||||
|
@Schema(description = "明细ID (SD_RPIMNFISH_R.ID)")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "放流主表ID (SD_ENGFR_R.ID)")
|
||||||
|
private String rpimnId;
|
||||||
|
|
||||||
|
@Schema(description = "电站站码")
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
@Schema(description = "电站名称")
|
||||||
|
private String stnm;
|
||||||
|
|
||||||
|
@Schema(description = "放流年份 yyyy")
|
||||||
|
private String flyr;
|
||||||
|
|
||||||
|
@Schema(description = "鱼种类")
|
||||||
|
private String ftp;
|
||||||
|
|
||||||
|
@Schema(description = "鱼种类名称")
|
||||||
|
private String ftpName;
|
||||||
|
|
||||||
|
@Schema(description = "平均长度")
|
||||||
|
private BigDecimal fsZ;
|
||||||
|
|
||||||
|
@Schema(description = "平均体重")
|
||||||
|
private BigDecimal fwet;
|
||||||
|
|
||||||
|
@Schema(description = "计划放殖鱼数量")
|
||||||
|
private Long fcnt;
|
||||||
|
|
||||||
|
@Schema(description = "标记类型")
|
||||||
|
private String tagte;
|
||||||
|
|
||||||
|
@Schema(description = "标记数量")
|
||||||
|
private Long tagcnt;
|
||||||
|
|
||||||
|
@Schema(description = "鱼龄")
|
||||||
|
private String fage;
|
||||||
|
|
||||||
|
@Schema(description = "鱼类档案ID")
|
||||||
|
private String fid;
|
||||||
|
|
||||||
|
@Schema(description = "保护等级")
|
||||||
|
private String protectlvl;
|
||||||
|
|
||||||
|
@Schema(description = "亲本来源")
|
||||||
|
private String fa;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "放流时间")
|
||||||
|
private Date tm;
|
||||||
|
}
|
||||||
@ -21,6 +21,13 @@ public interface FbStationService {
|
|||||||
|
|
||||||
DataSourceResult<FbFishRunQgcVo> getFishRunQgcKendoListCust(DataSourceRequest dataSourceRequest);
|
DataSourceResult<FbFishRunQgcVo> getFishRunQgcKendoListCust(DataSourceRequest dataSourceRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询全过程鱼类放鱼数据明细(细粒度),用于聚合行下钻查看底层放鱼明细。
|
||||||
|
*
|
||||||
|
* @param dataSourceRequest 支持 stcd/flyr/ftp 等过滤条件与分页排序
|
||||||
|
*/
|
||||||
|
DataSourceResult<FbFishRunQgcDetailVo> getFishRunQgcDetailKendoListCust(DataSourceRequest dataSourceRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除全过程鱼类放鱼数据(按 站点+年份+鱼种 维度逻辑删除 SD_RPIMNFISH_R 明细)
|
* 批量删除全过程鱼类放鱼数据(按 站点+年份+鱼种 维度逻辑删除 SD_RPIMNFISH_R 明细)
|
||||||
*
|
*
|
||||||
@ -28,6 +35,13 @@ public interface FbStationService {
|
|||||||
*/
|
*/
|
||||||
boolean removeFishRunQgcData(List<FbFishRunQgcDeleteParam> params);
|
boolean removeFishRunQgcData(List<FbFishRunQgcDeleteParam> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按明细ID批量逻辑删除全过程鱼类放鱼数据,并记录操作日志。
|
||||||
|
*
|
||||||
|
* @param ids 明细ID列表(SD_RPIMNFISH_R.ID)
|
||||||
|
*/
|
||||||
|
boolean removeFishRunQgcDetailData(List<String> ids);
|
||||||
|
|
||||||
DataSourceResult<FbFishTypeFinishVo> getFishTypeKendoListCust(DataSourceRequest dataSourceRequest);
|
DataSourceResult<FbFishTypeFinishVo> getFishTypeKendoListCust(DataSourceRequest dataSourceRequest);
|
||||||
|
|
||||||
DataSourceResult<FbFishTypeStcdVo> getFishTypeStcdList(DataSourceRequest dataSourceRequest);
|
DataSourceResult<FbFishTypeStcdVo> getFishTypeStcdList(DataSourceRequest dataSourceRequest);
|
||||||
|
|||||||
@ -195,6 +195,74 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSourceResult<FbFishRunQgcDetailVo> getFishRunQgcDetailKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||||
|
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||||
|
String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd");
|
||||||
|
String flyr = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "flyr");
|
||||||
|
String ftp = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "ftp");
|
||||||
|
|
||||||
|
Map<String, Object> paramMap = new HashMap<>();
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
sql.append("SELECT det.ID AS id, ")
|
||||||
|
.append("run.ID AS rpimnId, ")
|
||||||
|
.append("run.STCD AS stcd, ")
|
||||||
|
.append("eng.ENNM AS stnm, ")
|
||||||
|
.append("TO_CHAR(run.TM, 'YYYY') AS flyr, ")
|
||||||
|
.append("det.FTP AS ftp, ")
|
||||||
|
.append(buildFishNameExpr("det.FTP")).append(" AS ftpName, ")
|
||||||
|
.append("det.FSZ AS fsZ, ")
|
||||||
|
.append("det.FWET AS fwet, ")
|
||||||
|
.append("det.FCNT AS fcnt, ")
|
||||||
|
.append("det.TAGTE AS tagte, ")
|
||||||
|
.append("det.TAGCNT AS tagcnt, ")
|
||||||
|
.append("det.FAGE AS fage, ")
|
||||||
|
.append("det.FID AS fid, ")
|
||||||
|
.append("det.PROTECTLVL AS protectlvl, ")
|
||||||
|
.append("det.FA AS fa, ")
|
||||||
|
.append("det.REMARK AS remark, ")
|
||||||
|
.append("run.TM AS tm ")
|
||||||
|
.append("FROM SD_RPIMNFISH_R det ")
|
||||||
|
.append("INNER JOIN SD_ENGFR_R run ON det.RPIMN_ID = run.ID AND NVL(run.IS_DELETED, 0) = 0 ")
|
||||||
|
.append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = run.STCD AND NVL(eng.IS_DELETED, 0) = 0 ")
|
||||||
|
.append(buildFishJoinSql("det.FTP", "eng.HBRVCD"))
|
||||||
|
.append("WHERE NVL(det.IS_DELETED, 0) = 0 ");
|
||||||
|
if (StrUtil.isNotBlank(stcd)) {
|
||||||
|
paramMap.put("detailStcd", stcd);
|
||||||
|
sql.append("AND run.STCD = #{map.detailStcd} ");
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(flyr)) {
|
||||||
|
paramMap.put("detailFlyr", flyr);
|
||||||
|
sql.append("AND TO_CHAR(run.TM, 'YYYY') = #{map.detailFlyr} ");
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(ftp)) {
|
||||||
|
paramMap.put("detailFtp", ftp);
|
||||||
|
sql.append("AND det.FTP = #{map.detailFtp} ");
|
||||||
|
}
|
||||||
|
String filterSql = buildFishRunQgcDetailFilterCondition(
|
||||||
|
dataSourceRequest == null ? null : dataSourceRequest.getFilter(),
|
||||||
|
paramMap,
|
||||||
|
new int[]{0}
|
||||||
|
);
|
||||||
|
if (StrUtil.isNotBlank(filterSql)) {
|
||||||
|
sql.append(" AND ").append(filterSql).append(" ");
|
||||||
|
}
|
||||||
|
sql.append(buildFishRunQgcDetailOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
|
||||||
|
|
||||||
|
Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
|
||||||
|
List<FbFishRunQgcDetailVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
|
||||||
|
page,
|
||||||
|
sql.toString(),
|
||||||
|
paramMap,
|
||||||
|
FbFishRunQgcDetailVo.class
|
||||||
|
);
|
||||||
|
DataSourceResult<FbFishRunQgcDetailVo> result = new DataSourceResult<>();
|
||||||
|
result.setData(list);
|
||||||
|
result.setTotal(page != null ? page.getTotal() : list.size());
|
||||||
|
result.setAggregates(new HashMap<>());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean removeFishRunQgcData(List<FbFishRunQgcDeleteParam> params) {
|
public boolean removeFishRunQgcData(List<FbFishRunQgcDeleteParam> params) {
|
||||||
@ -224,19 +292,67 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
" AND TO_CHAR(run.TM, 'YYYY') = ? )",
|
" AND TO_CHAR(run.TM, 'YYYY') = ? )",
|
||||||
resolveLogOperator(), param.getFtp(), param.getStcd(), param.getFlyr()
|
resolveLogOperator(), param.getFtp(), param.getStcd(), param.getFlyr()
|
||||||
);
|
);
|
||||||
recordFishRunDeleteLog(beforeRows, param, deleteCount);
|
recordFishRunDeleteLog(beforeRows, String.format("删除全过程鱼类放鱼数据(站点:%s,年份:%s,删除条数:%d)",
|
||||||
|
param.getStcd(), param.getFlyr(), deleteCount), deleteCount);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean removeFishRunQgcDetailData(List<String> ids) {
|
||||||
|
if (CollUtil.isEmpty(ids)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
List<String> distinctIds = ids.stream()
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (distinctIds.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 1. 查询删除前的明细行(含站点等信息, 用于记录日志)
|
||||||
|
List<Map<String, Object>> beforeRows = queryFishRunDetailRowsByIds(distinctIds);
|
||||||
|
// 2. 分批逻辑删除(ID IN, 防止超过数据库 IN 限制)
|
||||||
|
int deleteCount = 0;
|
||||||
|
for (List<String> part : CollUtil.split(distinctIds, 500)) {
|
||||||
|
deleteCount += batchSoftDeleteFishRunDetail(part);
|
||||||
|
}
|
||||||
|
// 3. 记录删除日志(每条明细一条主日志, 子日志挂对应主日志)
|
||||||
|
recordFishRunDeleteLog(beforeRows, String.format("删除全过程鱼类放鱼数据(明细删除,删除条数:%d)", deleteCount), deleteCount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private List<Map<String, Object>> queryFishRunDetailRows(FbFishRunQgcDeleteParam param) {
|
private List<Map<String, Object>> queryFishRunDetailRows(FbFishRunQgcDeleteParam param) {
|
||||||
String sql = "SELECT det.ID, det.RPIMN_ID, det.FTP, det.FSZ, det.FWET, det.FCNT, " +
|
String sql = "SELECT det.ID, det.RPIMN_ID, run.STCD, det.FTP, det.FSZ, det.FWET, det.FCNT, " +
|
||||||
"det.TAGTE, det.TAGCNT, det.FAGE, det.FID, det.PROTECTLVL, det.FA, det.REMARK " +
|
"det.TAGTE, det.TAGCNT, det.FAGE, det.FID, det.PROTECTLVL, det.FA, det.REMARK " +
|
||||||
"FROM SD_RPIMNFISH_R det " +
|
"FROM SD_RPIMNFISH_R det " +
|
||||||
"INNER JOIN SD_ENGFR_R run ON det.RPIMN_ID = run.ID AND NVL(run.IS_DELETED, 0) = 0 " +
|
"INNER JOIN SD_ENGFR_R run ON det.RPIMN_ID = run.ID AND NVL(run.IS_DELETED, 0) = 0 " +
|
||||||
"WHERE NVL(det.IS_DELETED, 0) = 0 " +
|
"WHERE NVL(det.IS_DELETED, 0) = 0 " +
|
||||||
" AND det.FTP = ? AND run.STCD = ? AND TO_CHAR(run.TM, 'YYYY') = ?";
|
" AND det.FTP = ? AND run.STCD = ? AND TO_CHAR(run.TM, 'YYYY') = ?";
|
||||||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, param.getFtp(), param.getStcd(), param.getFlyr());
|
return queryFishRunDetailRowsInternal(sql, param.getFtp(), param.getStcd(), param.getFlyr());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Map<String, Object>> queryFishRunDetailRowsByIds(List<String> ids) {
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
sql.append("SELECT det.ID, det.RPIMN_ID, run.STCD, det.FTP, det.FSZ, det.FWET, det.FCNT, ")
|
||||||
|
.append("det.TAGTE, det.TAGCNT, det.FAGE, det.FID, det.PROTECTLVL, det.FA, det.REMARK ")
|
||||||
|
.append("FROM SD_RPIMNFISH_R det ")
|
||||||
|
.append("INNER JOIN SD_ENGFR_R run ON det.RPIMN_ID = run.ID AND NVL(run.IS_DELETED, 0) = 0 ")
|
||||||
|
.append("WHERE NVL(det.IS_DELETED, 0) = 0 ")
|
||||||
|
.append(" AND det.ID IN (");
|
||||||
|
for (int i = 0; i < ids.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sql.append(", ");
|
||||||
|
}
|
||||||
|
sql.append("?");
|
||||||
|
}
|
||||||
|
sql.append(")");
|
||||||
|
return queryFishRunDetailRowsInternal(sql.toString(), ids.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Map<String, Object>> queryFishRunDetailRowsInternal(String sql, Object... args) {
|
||||||
|
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, args);
|
||||||
List<Map<String, Object>> normalized = new ArrayList<>();
|
List<Map<String, Object>> normalized = new ArrayList<>();
|
||||||
for (Map<String, Object> row : rows) {
|
for (Map<String, Object> row : rows) {
|
||||||
normalized.add(normalizeFishRunLogRow(row));
|
normalized.add(normalizeFishRunLogRow(row));
|
||||||
@ -244,6 +360,28 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int batchSoftDeleteFishRunDetail(List<String> ids) {
|
||||||
|
if (CollUtil.isEmpty(ids)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
sql.append("UPDATE SD_RPIMNFISH_R det ")
|
||||||
|
.append("SET det.IS_DELETED = 1, det.DELETE_USER = ?, det.DELETE_TIME = SYSDATE ")
|
||||||
|
.append("WHERE NVL(det.IS_DELETED, 0) = 0 ")
|
||||||
|
.append(" AND det.ID IN (");
|
||||||
|
List<Object> params = new ArrayList<>();
|
||||||
|
params.add(resolveLogOperator());
|
||||||
|
for (int i = 0; i < ids.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sql.append(", ");
|
||||||
|
}
|
||||||
|
sql.append("?");
|
||||||
|
params.add(ids.get(i));
|
||||||
|
}
|
||||||
|
sql.append(")");
|
||||||
|
return jdbcTemplate.update(sql.toString(), params.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> normalizeFishRunLogRow(Map<String, Object> row) {
|
private Map<String, Object> normalizeFishRunLogRow(Map<String, Object> row) {
|
||||||
Map<String, Object> normalized = new LinkedHashMap<>();
|
Map<String, Object> normalized = new LinkedHashMap<>();
|
||||||
if (row == null || row.isEmpty()) {
|
if (row == null || row.isEmpty()) {
|
||||||
@ -255,19 +393,20 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordFishRunDeleteLog(List<Map<String, Object>> rows, FbFishRunQgcDeleteParam param, int deleteCount) {
|
private void recordFishRunDeleteLog(List<Map<String, Object>> rows, String remark, int deleteCount) {
|
||||||
if (CollUtil.isEmpty(rows)) {
|
if (CollUtil.isEmpty(rows)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<MsOperationLogDetail> details = new ArrayList<>();
|
List<MsOperationLogDetail> details = new ArrayList<>();
|
||||||
for (Map<String, Object> row : rows) {
|
for (Map<String, Object> row : rows) {
|
||||||
|
String recordId = asString(row.get("ID"));
|
||||||
|
String stcd = asString(row.get("STCD"));
|
||||||
MsOperationLog mainLog = new MsOperationLog();
|
MsOperationLog mainLog = new MsOperationLog();
|
||||||
mainLog.setOperator(resolveLogOperator());
|
mainLog.setOperator(resolveLogOperator());
|
||||||
mainLog.setRecordId(String.valueOf(row.get("ID")));
|
mainLog.setRecordId(recordId);
|
||||||
mainLog.setOperateTime(new Date());
|
mainLog.setOperateTime(new Date());
|
||||||
mainLog.setTableName(FISH_RUN_DETAIL_TABLE_NAME);
|
mainLog.setTableName(FISH_RUN_DETAIL_TABLE_NAME);
|
||||||
mainLog.setRemark("删除全过程鱼类放鱼数据(站点:" + param.getStcd()
|
mainLog.setRemark(remark);
|
||||||
+ ",年份:" + param.getFlyr() + ",删除条数:" + deleteCount + ")");
|
|
||||||
msOperationLogMapper.insert(mainLog);
|
msOperationLogMapper.insert(mainLog);
|
||||||
for (Map.Entry<String, Object> entry : row.entrySet()) {
|
for (Map.Entry<String, Object> entry : row.entrySet()) {
|
||||||
if (StrUtil.isBlank(entry.getKey()) || entry.getValue() == null) {
|
if (StrUtil.isBlank(entry.getKey()) || entry.getValue() == null) {
|
||||||
@ -276,7 +415,7 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
MsOperationLogDetail detail = new MsOperationLogDetail();
|
MsOperationLogDetail detail = new MsOperationLogDetail();
|
||||||
detail.setMainId(mainLog.getId());
|
detail.setMainId(mainLog.getId());
|
||||||
detail.setTableName(FISH_RUN_DETAIL_TABLE_NAME);
|
detail.setTableName(FISH_RUN_DETAIL_TABLE_NAME);
|
||||||
detail.setStationCode(param.getStcd());
|
detail.setStationCode(stcd);
|
||||||
detail.setFieldCode(entry.getKey());
|
detail.setFieldCode(entry.getKey());
|
||||||
detail.setFieldMeaning(FISH_RUN_FIELD_MEANING_MAP.getOrDefault(entry.getKey(), entry.getKey()));
|
detail.setFieldMeaning(FISH_RUN_FIELD_MEANING_MAP.getOrDefault(entry.getKey(), entry.getKey()));
|
||||||
detail.setOldValueCode(formatFishRunLogValue(entry.getValue()));
|
detail.setOldValueCode(formatFishRunLogValue(entry.getValue()));
|
||||||
@ -290,6 +429,10 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String asString(Object value) {
|
||||||
|
return value == null ? null : String.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
private String resolveLogOperator() {
|
private String resolveLogOperator() {
|
||||||
try {
|
try {
|
||||||
return SecurityUtils.getCurrentUsername();
|
return SecurityUtils.getCurrentUsername();
|
||||||
@ -1412,6 +1555,184 @@ public class FbStationServiceImpl implements FbStationService {
|
|||||||
return " ORDER BY " + String.join(", ", orderByParts);
|
return " ORDER BY " + String.join(", ", orderByParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String mapFishRunQgcDetailColumn(String field) {
|
||||||
|
if (StrUtil.isBlank(field)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return switch (field) {
|
||||||
|
case "id" -> "det.ID";
|
||||||
|
case "rpimnId" -> "det.RPIMN_ID";
|
||||||
|
case "stcd" -> "run.STCD";
|
||||||
|
case "stnm" -> "eng.ENNM";
|
||||||
|
case "flyr" -> "TO_CHAR(run.TM, 'YYYY')";
|
||||||
|
case "ftp" -> "det.FTP";
|
||||||
|
case "ftpName" -> buildFishNameExpr("det.FTP");
|
||||||
|
case "fsZ" -> "det.FSZ";
|
||||||
|
case "fwet" -> "det.FWET";
|
||||||
|
case "fcnt" -> "det.FCNT";
|
||||||
|
case "tagte" -> "det.TAGTE";
|
||||||
|
case "tagcnt" -> "det.TAGCNT";
|
||||||
|
case "fage" -> "det.FAGE";
|
||||||
|
case "fid" -> "det.FID";
|
||||||
|
case "protectlvl" -> "det.PROTECTLVL";
|
||||||
|
case "fa" -> "det.FA";
|
||||||
|
case "remark" -> "det.REMARK";
|
||||||
|
case "tm" -> "run.TM";
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object normalizeFishRunQgcDetailValue(String field, Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ("fcnt".equals(field) || "tagcnt".equals(field)) {
|
||||||
|
try {
|
||||||
|
return Long.parseLong(String.valueOf(value).trim());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildFishRunQgcDetailFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||||
|
Map<String, Object> paramMap,
|
||||||
|
int[] indexHolder) {
|
||||||
|
if (filter == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(filter.getField())) {
|
||||||
|
return buildFishRunQgcDetailLeafCondition(filter, paramMap, indexHolder);
|
||||||
|
}
|
||||||
|
if (CollUtil.isEmpty(filter.getFilters())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
List<String> conditions = new ArrayList<>();
|
||||||
|
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
|
||||||
|
String childSql = buildFishRunQgcDetailFilterCondition(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 buildFishRunQgcDetailLeafCondition(DataSourceRequest.FilterDescriptor filter,
|
||||||
|
Map<String, Object> paramMap,
|
||||||
|
int[] indexHolder) {
|
||||||
|
// 这三个字段已在主 SQL 中作为下钻条件处理,避免重复拼接
|
||||||
|
if ("stcd".equalsIgnoreCase(filter.getField()) || "flyr".equalsIgnoreCase(filter.getField())
|
||||||
|
|| "ftp".equalsIgnoreCase(filter.getField())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String column = mapFishRunQgcDetailColumn(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)) {
|
||||||
|
List<Object> values = normalizeQgcBsmfRValues(filter.getValue());
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
List<String> placeholders = new ArrayList<>();
|
||||||
|
for (Object value : values) {
|
||||||
|
String key = "fishRunQgcDetailP" + indexHolder[0]++;
|
||||||
|
paramMap.put(key, normalizeFishRunQgcDetailValue(filter.getField(), value));
|
||||||
|
placeholders.add("#{map." + key + "}");
|
||||||
|
}
|
||||||
|
return column + " IN (" + String.join(", ", placeholders) + ")";
|
||||||
|
}
|
||||||
|
Object value = filter.getValue();
|
||||||
|
if (value == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String key = "fishRunQgcDetailP" + indexHolder[0]++;
|
||||||
|
Object normalizedValue = normalizeFishRunQgcDetailValue(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, "%" + 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 buildFishRunQgcDetailOrderBySql(List<DataSourceRequest.SortDescriptor> sorts) {
|
||||||
|
if (CollUtil.isEmpty(sorts)) {
|
||||||
|
return " ORDER BY run.TM DESC, det.ID DESC";
|
||||||
|
}
|
||||||
|
List<String> orderByParts = new ArrayList<>();
|
||||||
|
for (DataSourceRequest.SortDescriptor sort : sorts) {
|
||||||
|
if (sort == null || StrUtil.isBlank(sort.getField())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String column = mapFishRunQgcDetailColumn(sort.getField());
|
||||||
|
if (StrUtil.isBlank(column)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC";
|
||||||
|
orderByParts.add(column + " " + direction);
|
||||||
|
}
|
||||||
|
if (orderByParts.isEmpty()) {
|
||||||
|
return " ORDER BY run.TM DESC, det.ID DESC";
|
||||||
|
}
|
||||||
|
return " ORDER BY " + String.join(", ", orderByParts);
|
||||||
|
}
|
||||||
|
|
||||||
private Date[] parseFishRunFlyrRange(String flyrFilter) {
|
private Date[] parseFishRunFlyrRange(String flyrFilter) {
|
||||||
if (StrUtil.isBlank(flyrFilter)) {
|
if (StrUtil.isBlank(flyrFilter)) {
|
||||||
return new Date[]{null, null};
|
return new Date[]{null, null};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user