Files
xgy-oa/klp-wms/src/main/java/com/klp/controller/WmsMultimodalController.java
2025-08-02 13:12:56 +08:00

309 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.klp.controller;
import com.klp.domain.MultimodalResult;
import com.klp.domain.MultimodalTask;
import com.klp.service.MultimodalService;
import com.klp.utils.ImageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
/**
* 多模态分析控制器
*/
@RestController
@RequestMapping("/multimodal")
public class WmsMultimodalController {
private static final Logger logger = LoggerFactory.getLogger(WmsMultimodalController.class);
@Autowired
private MultimodalService multimodalService;
/**
* 处理单个任务
* @param task 任务信息
* @return 分析结果
*/
@PostMapping("/process-task")
public ResponseEntity<MultimodalResult> processTask(@RequestBody MultimodalTask task) {
try {
logger.info("开始处理任务: {}", task.getTaskId());
// 验证图片路径
validateImagePaths(task.getImagePaths());
// 处理任务
MultimodalResult result = multimodalService.processTask(task);
logger.info("任务处理完成: {}", task.getTaskId());
return ResponseEntity.ok(result);
} catch (Exception e) {
logger.error("处理任务失败: {}", task.getTaskId(), e);
return ResponseEntity.badRequest().build();
}
}
/**
* 多轮投票处理任务
* @param task 任务信息
* @param rounds 投票轮数
* @return 分析结果
*/
@PostMapping("/process-task-voting")
public ResponseEntity<MultimodalResult> processTaskWithVoting(
@RequestBody MultimodalTask task,
@RequestParam(defaultValue = "3") int rounds) {
try {
logger.info("开始多轮投票处理任务: {}, 轮数: {}", task.getTaskId(), rounds);
// 验证图片路径
validateImagePaths(task.getImagePaths());
// 处理任务
MultimodalResult result = multimodalService.processTaskWithVoting(task, rounds);
logger.info("多轮投票任务处理完成: {}", task.getTaskId());
return ResponseEntity.ok(result);
} catch (Exception e) {
logger.error("多轮投票处理任务失败: {}", task.getTaskId(), e);
return ResponseEntity.badRequest().build();
}
}
/**
* 批量处理任务
* @param tasks 任务列表
* @return 分析结果列表
*/
@PostMapping("/process-tasks-batch")
public ResponseEntity<List<MultimodalResult>> processTasksBatch(@RequestBody List<MultimodalTask> tasks) {
try {
logger.info("开始批量处理任务,数量: {}", tasks.size());
// 验证所有任务的图片路径
for (MultimodalTask task : tasks) {
validateImagePaths(task.getImagePaths());
}
// 批量处理任务
List<MultimodalResult> results = multimodalService.processTasksBatch(tasks);
logger.info("批量任务处理完成,成功数量: {}", results.size());
return ResponseEntity.ok(results);
} catch (Exception e) {
logger.error("批量处理任务失败", e);
return ResponseEntity.badRequest().build();
}
}
/**
* 从目录处理任务模拟Python脚本的功能
* @param request 请求参数
* @return 处理结果
*/
@PostMapping("/process-from-directory")
public ResponseEntity<Map<String, Object>> processFromDirectory(@RequestBody Map<String, Object> request) {
try {
String time = (String) request.get("time");
String phoneName = (String) request.get("phoneName");
String projectRoot = (String) request.get("projectRoot");
logger.info("开始从目录处理任务: time={}, phoneName={}", time, phoneName);
// 构建路径
Path dataRoot = Paths.get(projectRoot, "data", phoneName);
Path resultDir = Paths.get(projectRoot, "result", phoneName);
Path tasksPath = Paths.get(projectRoot, "gen", phoneName, time, "tasks.json");
// 创建结果目录
Files.createDirectories(resultDir);
// 读取任务配置
if (!Files.exists(tasksPath)) {
throw new RuntimeException("任务配置文件不存在: " + tasksPath);
}
String tasksJson = new String(Files.readAllBytes(tasksPath));
List<Map<String, Object>> apps = parseJsonArray(tasksJson);
// 收集所有任务
List<MultimodalTask> allTasks = new ArrayList<>();
for (Map<String, Object> app : apps) {
String appName = (String) app.get("appName");
List<Map<String, Object>> taskList = (List<Map<String, Object>>) app.get("taskList");
if (taskList != null) {
for (Map<String, Object> taskData : taskList) {
String order = String.valueOf(taskData.get("order"));
Path folder = dataRoot.resolve(appName + "_task_" + order + "_result");
if (!Files.exists(folder)) {
logger.warn("目录不存在:{},跳过 Task#{}", folder, order);
continue;
}
// 获取有效图片
List<String> validImages = ImageUtils.getValidImageFiles(folder.toString());
if (validImages.isEmpty()) {
logger.warn("目录下无有效图片:{},跳过 Task#{}", folder, order);
continue;
}
// 创建任务对象
MultimodalTask task = new MultimodalTask(
appName,
(String) taskData.get("content"),
(String) taskData.get("taskCategory"),
(String) taskData.get("time"),
(String) taskData.get("security"),
folder.toString(),
(String) taskData.get("task_id"),
validImages
);
allTasks.add(task);
}
}
}
logger.info("收集到 {} 个任务", allTasks.size());
// 批量处理任务
List<MultimodalResult> results = multimodalService.processTasksBatch(allTasks);
// 按应用分组保存结果
Map<String, List<MultimodalResult>> appResults = results.stream()
.collect(Collectors.groupingBy(MultimodalResult::getAppName));
// 保存结果到文件
for (Map.Entry<String, List<MultimodalResult>> entry : appResults.entrySet()) {
String appName = entry.getKey();
List<MultimodalResult> appResultList = entry.getValue();
Path outFile = resultDir.resolve(appName + ".json");
// 读取现有结果
List<MultimodalResult> existing = new ArrayList<>();
if (Files.exists(outFile)) {
try {
String existingJson = new String(Files.readAllBytes(outFile));
existing = parseResultList(existingJson);
} catch (Exception e) {
logger.warn("读取现有结果文件失败: {}", outFile, e);
}
}
// 合并结果
existing.addAll(appResultList);
// 保存到文件
String jsonResult = convertToJson(existing);
Files.write(outFile, jsonResult.getBytes());
logger.info("保存结果: {} (总条目: {})", outFile, existing.size());
}
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("totalTasks", allTasks.size());
response.put("processedTasks", results.size());
response.put("resultDir", resultDir.toString());
return ResponseEntity.ok(response);
} catch (Exception e) {
logger.error("从目录处理任务失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
response.put("error", e.getMessage());
return ResponseEntity.badRequest().body(response);
}
}
/**
* 验证图片路径
* @param imagePaths 图片路径列表
*/
private void validateImagePaths(List<String> imagePaths) {
if (imagePaths == null || imagePaths.isEmpty()) {
throw new RuntimeException("图片路径列表不能为空");
}
for (String imagePath : imagePaths) {
if (!ImageUtils.isValidImageFile(imagePath)) {
throw new RuntimeException("无效的图片文件: " + imagePath);
}
}
}
/**
* 解析JSON数组
* @param json JSON字符串
* @return 对象列表
*/
private List<Map<String, Object>> parseJsonArray(String json) {
try {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
return mapper.readValue(json, List.class);
} catch (Exception e) {
throw new RuntimeException("解析JSON失败", e);
}
}
/**
* 解析结果列表
* @param json JSON字符串
* @return 结果列表
*/
private List<MultimodalResult> parseResultList(String json) {
try {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
return mapper.readValue(json,
mapper.getTypeFactory().constructCollectionType(List.class, MultimodalResult.class));
} catch (Exception e) {
throw new RuntimeException("解析结果JSON失败", e);
}
}
/**
* 转换为JSON字符串
* @param results 结果列表
* @return JSON字符串
*/
private String convertToJson(List<MultimodalResult> results) {
try {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
return mapper.writeValueAsString(results);
} catch (Exception e) {
throw new RuntimeException("转换为JSON失败", e);
}
}
/**
* 健康检查接口
* @return 健康状态
*/
@GetMapping("/health")
public ResponseEntity<Map<String, Object>> health() {
Map<String, Object> response = new HashMap<>();
response.put("status", "UP");
response.put("service", "Multimodal Analysis Service");
response.put("timestamp", new Date());
return ResponseEntity.ok(response);
}
}