fix: 优化逻辑

This commit is contained in:
tangwei 2026-08-14 13:49:00 +08:00
parent b203fe61eb
commit c967b5105f
6 changed files with 192 additions and 33 deletions

View File

@ -85,7 +85,7 @@ public class SecurityConfig {
.requestMatchers("/wq/**").permitAll()
// .requestMatchers("/wte/**").permitAll()
// .requestMatchers("/vd/**").permitAll()
// .requestMatchers("/vap/**").permitAll()
.requestMatchers("/vap/**").permitAll()
.requestMatchers("/fp/**").permitAll()
// .requestMatchers("/fpr/**").permitAll()
// .requestMatchers("/fh/**").permitAll()

View File

@ -18,9 +18,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -64,27 +62,66 @@ public class SdFpssrlRController {
@Log(module = "过鱼设施自动数据管理", value = "新增过鱼自动数据")
@PostMapping("/add")
@Operation(summary = "新增过鱼自动数据")
public ResponseResult add(@RequestBody SdEngInfoBHOperateRequest request) {
SdFpssrlR entity = request == null || request.getEngInfo() == null ? null
: objectMapper.convertValue(request.getEngInfo(), SdFpssrlR.class);
if (entity == null) {
return ResponseResult.error("数据不能为空");
public ResponseResult add(@RequestParam("data") String dataStr,
@RequestParam(value = "picFiles", required = false) List<MultipartFile> picFiles,
@RequestParam(value = "vdFiles", required = false) List<MultipartFile> vdFiles) {
try {
SdEngInfoBHOperateRequest request = objectMapper.readValue(dataStr, SdEngInfoBHOperateRequest.class);
SdFpssrlR entity = request == null || request.getEngInfo() == null ? null
: objectMapper.convertValue(request.getEngInfo(), SdFpssrlR.class);
if (entity == null) {
return ResponseResult.error("数据不能为空");
}
// 上传附件并设置到实体图片firstImgUrl视频videoUrl
applyUploadedFiles(entity, picFiles, vdFiles);
boolean result = sdFpssrlRService.add(entity, request.getSource());
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
} catch (Exception e) {
log.error("新增过鱼自动数据失败", e);
return ResponseResult.error("新增失败: " + e.getMessage());
}
boolean result = sdFpssrlRService.add(entity, request.getSource());
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@Log(module = "过鱼设施自动数据管理", value = "修改过鱼自动数据")
@PostMapping("/update")
@Operation(summary = "修改过鱼自动数据")
public ResponseResult update(@RequestBody SdEngInfoBHOperateRequest request) {
SdFpssrlR entity = request == null || request.getEngInfo() == null ? null
: objectMapper.convertValue(request.getEngInfo(), SdFpssrlR.class);
if (entity == null || entity.getId() == null) {
return ResponseResult.error("数据或ID不能为空");
public ResponseResult update(@RequestParam("data") String dataStr,
@RequestParam(value = "picFiles", required = false) List<MultipartFile> picFiles,
@RequestParam(value = "vdFiles", required = false) List<MultipartFile> vdFiles) {
try {
SdEngInfoBHOperateRequest request = objectMapper.readValue(dataStr, SdEngInfoBHOperateRequest.class);
Map<String, Object> engInfo = request == null ? null : request.getEngInfo();
if (engInfo == null || engInfo.get("id") == null) {
return ResponseResult.error("数据或ID不能为空");
}
// 获取修改前的实体用于后续清理被替换的旧附件
SdFpssrlR before = sdFpssrlRService.getById((String) engInfo.get("id"));
List<String> oldAttachmentIds = before != null ? collectAttachmentIds(before) : Collections.emptyList();
// 上传新附件并合并回 patch map仅当本次有文件上传时才覆盖对应字段
SdFpssrlR tempEntity = objectMapper.convertValue(engInfo, SdFpssrlR.class);
applyUploadedFiles(tempEntity, picFiles, vdFiles);
if (picFiles != null && !picFiles.isEmpty()) {
engInfo.put("firstImgUrl", tempEntity.getFirstImgUrl());
}
if (vdFiles != null && !vdFiles.isEmpty()) {
engInfo.put("videoUrl", tempEntity.getVideoUrl());
}
boolean result = sdFpssrlRService.update(engInfo, request.getSource());
if (result) {
// 清理被替换的旧附件
SdFpssrlR after = sdFpssrlRService.getById((String) engInfo.get("id"));
deleteReplacedFiles(oldAttachmentIds, collectAttachmentIds(after));
}
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
} catch (Exception e) {
log.error("修改过鱼自动数据失败", e);
return ResponseResult.error("修改失败: " + e.getMessage());
}
boolean result = sdFpssrlRService.update(entity, request.getSource());
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@Log(module = "过鱼设施自动数据管理", value = "删除过鱼自动数据")
@ -95,7 +132,21 @@ public class SdFpssrlRController {
if (ids == null || ids.isEmpty()) {
return ResponseResult.error("ID不能为空");
}
// 删除前先收集所有需要清理的附件ID
List<String> allAttachmentIds = new ArrayList<>();
for (String id : ids) {
SdFpssrlR entity = sdFpssrlRService.getById(id);
if (entity != null) {
allAttachmentIds.addAll(collectAttachmentIds(entity));
}
}
boolean result = sdFpssrlRService.delete(ids, request.getSource());
if (result) {
// 删除关联的附件
deleteAttachments(allAttachmentIds);
}
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
@ -169,7 +220,6 @@ public class SdFpssrlRController {
try {
List<SdFpssrlAiR> result = sdFpssrlRService.processAiReportBatch(requests);
// List<String> ids = result.stream().map(SdFpssrlR::getId).collect(Collectors.toList());
log.info("AI批量上报成功共{}条", result.size());
return ResponseResult.success();
} catch (Exception e) {
@ -177,4 +227,85 @@ public class SdFpssrlRController {
return ResponseResult.error("上报失败: " + e.getMessage());
}
}
// ==================== 附件处理辅助方法 ====================
/**
* 上传图片/视频附件并追加附件ID到 firstImgUrl/videoUrl 字段与已有ID以逗号拼接
*/
private void applyUploadedFiles(SdFpssrlR entity, List<MultipartFile> picFiles, List<MultipartFile> vdFiles) {
if (picFiles != null && !picFiles.isEmpty()) {
List<String> ids = attachmentUploadService.uploadMultipartFiles(picFiles);
if (!ids.isEmpty()) {
entity.setFirstImgUrl(mergeIds(entity.getFirstImgUrl(), ids));
}
}
if (vdFiles != null && !vdFiles.isEmpty()) {
List<String> ids = attachmentUploadService.uploadMultipartFiles(vdFiles);
if (!ids.isEmpty()) {
entity.setVideoUrl(mergeIds(entity.getVideoUrl(), ids));
}
}
}
/**
* 将新上传的附件ID列表追加到已有ID字符串后面逗号分隔
*/
private String mergeIds(String existing, List<String> ids) {
String newIds = ids.stream()
.filter(StrUtil::isNotBlank)
.collect(Collectors.joining(","));
if (StrUtil.isBlank(newIds)) {
return existing;
}
return StrUtil.isBlank(existing) ? newIds : existing + "," + newIds;
}
/**
* 收集实体中 firstImgUrl/videoUrl 字段的附件ID
*/
private List<String> collectAttachmentIds(SdFpssrlR entity) {
List<String> ids = new ArrayList<>();
if (entity == null) {
return ids;
}
if (StrUtil.isNotBlank(entity.getFirstImgUrl())) {
Arrays.stream(entity.getFirstImgUrl().split(","))
.map(String::trim)
.filter(StrUtil::isNotBlank)
.forEach(ids::add);
}
if (StrUtil.isNotBlank(entity.getVideoUrl())) {
Arrays.stream(entity.getVideoUrl().split(","))
.map(String::trim)
.filter(StrUtil::isNotBlank)
.forEach(ids::add);
}
return ids;
}
/**
* 删除被替换的旧附件old中有但new中没有的
*/
private void deleteReplacedFiles(List<String> oldIds, List<String> newIds) {
for (String oldId : oldIds) {
if (StrUtil.isBlank(oldId)) {
continue;
}
if (!newIds.contains(oldId)) {
attachmentUploadService.deleteFile(oldId);
}
}
}
/**
* 批量删除附件
*/
private void deleteAttachments(List<String> attachmentIds) {
for (String id : attachmentIds) {
if (StrUtil.isNotBlank(id)) {
attachmentUploadService.deleteFile(id);
}
}
}
}

View File

@ -8,6 +8,7 @@ import com.yfd.platform.qgc_base.domain.SdFpssrlR;
import com.yfd.platform.qgc_base.domain.SdFpssrlRAiRequest;
import java.util.List;
import java.util.Map;
/**
* <p>
@ -27,9 +28,9 @@ public interface ISdFpssrlRService extends IService<SdFpssrlR> {
boolean add(SdFpssrlR entity, String source);
/**
* 修改
* 修改按前端 patch 显式更新字段 null 置空
*/
boolean update(SdFpssrlR entity, String source);
boolean update(Map<String, Object> engInfoPatch, String source) throws Exception;
/**
* 删除逻辑删除

View File

@ -13,7 +13,9 @@ import com.yfd.platform.qgc_base.mapper.SdFpssrlAiRMapper;
import com.yfd.platform.qgc_base.mapper.SdFpssrlRMapper;
import com.yfd.platform.qgc_base.service.IMsOperationLogService;
import com.yfd.platform.qgc_base.service.ISdFpssrlRService;
import com.yfd.platform.utils.CodeToNameMetadataBo;
import com.yfd.platform.utils.DataSourceRequestUtil;
import com.yfd.platform.utils.DictCodeToNameConverter;
import com.yfd.platform.utils.SecurityUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -23,6 +25,8 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* <p>
@ -40,6 +44,26 @@ public class SdFpssrlRServiceImpl extends ServiceImpl<SdFpssrlRMapper, SdFpssrlR
@Resource
private SdFpssrlAiRMapper fpssrlAiRMapper;
@Resource
private DictCodeToNameConverter dictCodeToNameConverter;
@Resource
private PatchUpdateHelper patchUpdateHelper;
private static final Set<String> TRANSIENT_FIELDS = Set.of("stnm", "serialVersionUID");
/**
* 代码转名称元数据配置列表
*/
private static final List<CodeToNameMetadataBo> 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<SdFpssrlR> queryPageList(DataSourceRequest request) {
return DataSourceRequestUtil.executeQuery(request, SdFpssrlR.class, this);
@ -49,21 +73,18 @@ public class SdFpssrlRServiceImpl extends ServiceImpl<SdFpssrlRMapper, SdFpssrlR
@Transactional(rollbackFor = Exception.class)
public boolean add(SdFpssrlR entity, String source) {
boolean result = this.save(entity);
// if (result) {
// msOperationLogService.recordAddDetailLog(entity.getId(),TABLE_NAME, entity, source);
// }
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(SdFpssrlR entity, String source) {
// SdFpssrlR before = this.getById(entity.getId());
boolean result = this.updateById(entity);
// if (result && before != null) {
// msOperationLogService.recordModifyDetailLog(entity.getId(),TABLE_NAME, before, entity, source);
// }
return result;
public boolean update(Map<String, Object> engInfoPatch, String source) throws Exception {
return patchUpdateHelper.execute(this, engInfoPatch, source, TABLE_NAME, SdFpssrlR.class,
TRANSIENT_FIELDS, CODE_TO_NAME_META_LIST, "id");
}
@Override
@ -72,14 +93,14 @@ public class SdFpssrlRServiceImpl extends ServiceImpl<SdFpssrlRMapper, SdFpssrlR
if (ids == null || ids.isEmpty()) return false;
int count = 0;
for (String id : ids) {
// SdFpssrlR entity = getById(id);
SdFpssrlR entity = getById(id);
LambdaUpdateWrapper<SdFpssrlR> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(SdFpssrlR::getId, id);
wrapper.set(SdFpssrlR::getIsDeleted, 1);
wrapper.set(SdFpssrlR::getDeleteUser, SecurityUtils.getCurrentUsername());
wrapper.set(SdFpssrlR::getDeleteTime, new Date());
if (this.update(wrapper)) {
// msOperationLogService.recordDeleteDetailLog(id,TABLE_NAME, entity, source);
msOperationLogService.recordDeleteDetailLog(id,TABLE_NAME, entity, source);
count++;
}
}

View File

@ -105,6 +105,9 @@ public class FpFpssrlQueryVo {
@Schema(description = "站点分类编码")
private String stCode;
@Schema(description = "是否鱼苗")
private Integer isfs;
@Schema(description = "站点分类名称")
private String stName;
}

View File

@ -1534,6 +1534,7 @@ public class FpRunServiceImpl implements FpRunService {
"src.ID AS id, " +
"src.STCD AS stcd, " +
"src.STNM AS stnm, " +
"src.ISFS AS isfs, " +
"src.BASEID AS baseId, " +
"src.BASENAME AS baseName, " +
"src.RSTCD AS rstcd, " +
@ -1581,6 +1582,7 @@ public class FpRunServiceImpl implements FpRunService {
" COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " +
" t.FTP AS FISHID, " +
" t.FSZ AS FSZ, " +
" null AS ISFS, " +
" TO_CHAR(t.LENGTH) AS LENGTH, " +
" TO_CHAR(t.WIDTH) AS WIDTH, " +
" TO_CHAR(t.FISHSPEED) AS FISHSPEED, " +
@ -1639,6 +1641,7 @@ public class FpRunServiceImpl implements FpRunService {
" COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " +
" t.FTP AS FISHID, " +
" t.FSZ AS FSZ, " +
" t.ISFS AS ISFS, " +
" CAST(NULL AS VARCHAR2(50)) AS LENGTH, " +
" CAST(NULL AS VARCHAR2(50)) AS WIDTH, " +
" CAST(NULL AS VARCHAR2(50)) AS FISHSPEED, " +