diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFpssrlRController.java b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFpssrlRController.java index 4883f43f..ae195913 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFpssrlRController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdFpssrlRController.java @@ -9,13 +9,17 @@ import com.yfd.platform.qgc_base.domain.SdEngInfoBHOperateRequest; import com.yfd.platform.qgc_base.domain.SdFpssrlR; import com.yfd.platform.qgc_base.domain.SdFpssrlRAiRequest; import com.yfd.platform.qgc_base.service.ISdFpssrlRService; +import com.yfd.platform.qgc_data.service.AttachmentUploadService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; 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.stream.Collectors; /** *

@@ -34,6 +38,9 @@ public class SdFpssrlRController { @Resource private ObjectMapper objectMapper; + @Resource + private AttachmentUploadService attachmentUploadService; + // ==================== CRUD 方法 ==================== @PostMapping("/queryPageList") @@ -90,34 +97,65 @@ public class SdFpssrlRController { // ==================== AI 设备识别数据上报接口 ==================== /** - * AI设备识别数据上报接口 - * 接收AI设备自动识别的过鱼数据并入库 + * AI设备图片/视频上传接口 + * 步骤1:先上传图片获取附件URL,再将URL填入数据上报接口 + */ + @PostMapping("/ai/uploadImage") + @Operation(summary = "AI设备图片上传") + public ResponseResult aiUploadImage(@RequestParam("file") MultipartFile file) { + if (file == null || file.isEmpty()) { + return ResponseResult.error("文件不能为空"); + } + try { + List files = new ArrayList<>(); + files.add(file); + List attachmentIds = attachmentUploadService.uploadMultipartFiles(files); + if (attachmentIds != null && !attachmentIds.isEmpty()) { + return ResponseResult.successData(attachmentIds); + } else { + return ResponseResult.error("图片上传失败"); + } + } catch (Exception e) { + log.error("AI图片上传失败", e); + return ResponseResult.error("图片上传失败: " + e.getMessage()); + } + } + + /** + * AI设备识别数据上报接口(支持单条和批量) + * 步骤2:上传完图片后,将附件ID填入JSON数组调用此接口 */ @PostMapping("/ai/report") - @Operation(summary = "AI设备识别数据上报") - public ResponseResult aiReport(@RequestBody SdFpssrlRAiRequest request) { - if (request == null) { + @Operation(summary = "AI设备识别数据上报(支持批量)") + public ResponseResult aiReport(@RequestBody List requests) { + if (requests == null || requests.isEmpty()) { return ResponseResult.error("请求数据不能为空"); } - if (request.getStcd() == null || request.getStcd().isEmpty()) { - return ResponseResult.error("过鱼设施编码(stcd)不能为空"); - } - if (request.getTm() == null) { - return ResponseResult.error("识别时间(tm)不能为空"); - } - if (request.getFtp() == null || request.getFtp().isEmpty()) { - return ResponseResult.error("鱼种类(ftp)不能为空"); + + // 逐条校验 + for (int i = 0; i < requests.size(); i++) { + SdFpssrlRAiRequest req = requests.get(i); + if (req == null) { + return ResponseResult.error("第" + (i + 1) + "条数据为空"); + } + if (req.getStcd() == null || req.getStcd().isEmpty()) { + return ResponseResult.error("第" + (i + 1) + "条过鱼设施编码(stcd)不能为空"); + } + if (req.getTm() == null) { + return ResponseResult.error("第" + (i + 1) + "条识别时间(tm)不能为空"); + } + if (req.getFtp() == null || req.getFtp().isEmpty()) { + return ResponseResult.error("第" + (i + 1) + "条鱼种类(ftp)不能为空"); + } } try { - SdFpssrlR entity = sdFpssrlRService.processAiReport(request); - if (entity != null) { - return ResponseResult.successData(entity.getId()); - } else { - return ResponseResult.error("数据保存失败"); - } + List result = sdFpssrlRService.processAiReportBatch(requests); +// List ids = result.stream().map(SdFpssrlR::getId).collect(Collectors.toList()); + log.info("AI批量上报成功,共{}条", result.size()); + return ResponseResult.success(); } catch (Exception e) { - log.error("AI识别数据上报失败", e); + log.error("AI识别数据批量上报失败", e); return ResponseResult.error("上报失败: " + e.getMessage()); } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssrlRService.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssrlRService.java index 4c129542..546fb5dc 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssrlRService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdFpssrlRService.java @@ -41,7 +41,12 @@ public interface ISdFpssrlRService extends IService { SdFpssrlR getById(String id); /** - * 处理AI设备上报的识别数据 + * 处理AI设备上报的单条识别数据 */ SdFpssrlR processAiReport(SdFpssrlRAiRequest request); + + /** + * 批量处理AI设备上报的识别数据 + */ + List processAiReportBatch(List requests); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssrlRServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssrlRServiceImpl.java index 04eb0406..4e431a88 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssrlRServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdFpssrlRServiceImpl.java @@ -18,6 +18,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -118,12 +119,26 @@ public class SdFpssrlRServiceImpl extends ServiceImpl processAiReportBatch(List requests) { + List results = new ArrayList<>(); + for (SdFpssrlRAiRequest req : requests) { + SdFpssrlR entity = processAiReport(req); + if (entity != null) { + results.add(entity); + } } - return result ? entity : null; + this.saveBatch(results); + return results; } }