Files
smartDriveEE/src/main/java/com/rj/controller/FaceDetectController.java
2025-10-09 16:15:39 +08:00

375 lines
17 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.rj.controller;
import com.rj.service.IFaceDetectLogService;
import com.rj.service.MinIOService;
import com.rj.utils.MinIOUrlGenerator;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
/**
* 图像检测控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/face-detect")
@Tag(name = "图像检测", description = "图像检测相关接口")
public class FaceDetectController {
@Autowired
private IFaceDetectLogService faceDetectLogService;
@Autowired
private MinIOService minioService;
@Autowired
private MinIOUrlGenerator urlGenerator;
/**
* 图像检测接口
*/
@PostMapping("/detect")
@Operation(summary = "图像检测", description = "检测图片中的图像信息")
public ResponseEntity<Map<String, Object>> detectFace(
@Parameter(description = "图片URL", required = true)
@RequestParam String imageUrl,
@Parameter(description = "所属人姓名", required = false)
@RequestParam(value = "ownerName", required = false) String ownerName,
@Parameter(description = "所属人电话", required = false)
@RequestParam(value = "ownerPhone", required = false) String ownerPhone,
@Parameter(description = "模型名称", required = false)
@RequestParam(value = "model", required = false) String model,
@Parameter(description = "头像名称", required = false)
@RequestParam(value = "avatarName", required = false) String avatarName) {
Map<String, Object> result = new HashMap<>();
try {
log.info("开始图像检测图片URL: {}", imageUrl);
// 执行图像检测
com.rj.entity.FaceDetectLog detectLog = faceDetectLogService.detectFaceAndSave(imageUrl, ownerName, ownerPhone, avatarName);
result.put("success", detectLog.getSuccess());
result.put("message", detectLog.getSuccess() ? "图像检测成功" : "图像检测失败");
result.put("imageUrl", imageUrl);
result.put("requestId", detectLog.getRequestId());
result.put("faceCount", detectLog.getFaceCount());
result.put("processingTimeMs", detectLog.getProcessingTimeMs());
result.put("ownerName", detectLog.getOwnerName());
result.put("ownerPhone", detectLog.getOwnerPhone());
result.put("avatarName", detectLog.getAvatarName());
if (!detectLog.getSuccess()) {
result.put("errorMessage", detectLog.getErrorMessage());
return ResponseEntity.badRequest().body(result);
}
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("图像检测失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "图像检测失败: " + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 图像检测接口JSON格式
*/
@PostMapping("/detect-json")
@Operation(summary = "图像检测(JSON)", description = "检测图片中的图像信息支持JSON请求体")
public ResponseEntity<Map<String, Object>> detectFaceJson(@RequestBody Map<String, String> requestBody) {
Map<String, Object> result = new HashMap<>();
try {
String imageUrl = requestBody.get("imageUrl");
String ownerName = requestBody.get("ownerName");
String ownerPhone = requestBody.get("ownerPhone");
String model = requestBody.get("model");
String avatarName = requestBody.get("avatarName");
if (imageUrl == null || imageUrl.trim().isEmpty()) {
result.put("success", false);
result.put("message", "图片URL不能为空");
return ResponseEntity.badRequest().body(result);
}
log.info("开始图像检测JSON图片URL: {}", imageUrl);
// 执行图像检测
com.rj.entity.FaceDetectLog detectLog = faceDetectLogService.detectFaceAndSave(imageUrl, ownerName, ownerPhone, avatarName, model);
result.put("success", detectLog.getSuccess());
result.put("message", detectLog.getSuccess() ? "图像检测成功" : "图像检测失败");
result.put("imageUrl", imageUrl);
result.put("requestId", detectLog.getRequestId());
result.put("faceCount", detectLog.getFaceCount());
result.put("processingTimeMs", detectLog.getProcessingTimeMs());
result.put("ownerName", detectLog.getOwnerName());
result.put("ownerPhone", detectLog.getOwnerPhone());
result.put("avatarName", detectLog.getAvatarName());
result.put("model", detectLog.getModel());
if (!detectLog.getSuccess()) {
result.put("errorMessage", detectLog.getErrorMessage());
return ResponseEntity.badRequest().body(result);
}
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("图像检测失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "图像检测失败: " + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 头衔上传接口
* 实现:文件上传 -> 生成短链接 -> 图像检测
*/
@PostMapping("/avatar/upload")
@Operation(summary = "头衔上传", description = "上传头像文件,生成短链接并进行图像检测")
public ResponseEntity<Map<String, Object>> uploadAvatar(
@Parameter(description = "头像文件", required = true)
@RequestParam("file") MultipartFile file,
@Parameter(description = "用户ID", required = false)
@RequestParam(value = "userId", required = false) String userId,
@Parameter(description = "所属人姓名", required = false)
@RequestParam(value = "ownerName", required = false) String ownerName,
@Parameter(description = "所属人电话", required = false)
@RequestParam(value = "ownerPhone", required = false) String ownerPhone,
@Parameter(description = "头像名称", required = false)
@RequestParam(value = "avatarName", required = false) String avatarName,
@Parameter(description = "模型名称", required = false)
@RequestParam(value = "model", required = false) String model,
@Parameter(description = "短链接有效期默认1小时", required = false)
@RequestParam(value = "expiresInSeconds", defaultValue = "3600") int expiresInSeconds) {
Map<String, Object> result = new HashMap<>();
try {
log.info("开始处理头衔上传,文件名: {}, 大小: {} bytes, 用户ID: {}",
file.getOriginalFilename(), file.getSize(), userId);
expiresInSeconds = 7*24*3600; // 默认7天
// 1. 验证文件
if (file.isEmpty()) {
result.put("success", false);
result.put("message", "文件不能为空");
return ResponseEntity.badRequest().body(result);
}
// 验证文件类型
String contentType = file.getContentType();
if (contentType == null || (!contentType.startsWith("image/"))) {
result.put("success", false);
result.put("message", "只支持图片文件格式");
return ResponseEntity.badRequest().body(result);
}
// 验证文件大小限制为10MB与Spring配置保持一致
if (file.getSize() > 10 * 1024 * 1024) {
result.put("success", false);
result.put("message", "文件大小不能超过10MB");
return ResponseEntity.badRequest().body(result);
}
// 2. 上传文件到MinIO
log.info("开始上传文件到MinIO...");
String fileUrl = minioService.uploadFile(file);
log.info("文件上传成功URL: {}", fileUrl);
// 3. 生成短链接临时访问URL
log.info("开始生成短链接,有效期: {}秒", expiresInSeconds);
String fileName = extractFileNameFromUrl(fileUrl);
MinIOUrlGenerator.UrlInfo urlInfo = urlGenerator.generateTempUrl(fileName, expiresInSeconds);
if (!urlInfo.isSuccess()) {
result.put("success", false);
result.put("message", "生成短链接失败: " + urlInfo.getErrorMessage());
return ResponseEntity.internalServerError().body(result);
}
String shortUrl = urlInfo.getUrl();
log.info("短链接生成成功: {}", shortUrl);
// 4. 进行图像检测
log.info("开始进行图像检测,使用模型: {}", model != null ? model : "默认模型");
com.rj.entity.FaceDetectLog detectLog = faceDetectLogService.detectFaceAndSave(shortUrl, ownerName, ownerPhone, avatarName, model);
// 5. 构建响应结果
result.put("success", true);
result.put("message", "头衔上传处理完成");
result.put("originalFileName", file.getOriginalFilename());
result.put("fileSize", file.getSize());
result.put("fileUrl", fileUrl);
result.put("shortUrl", shortUrl);
result.put("shortUrlExpiresAt", urlInfo.getFormattedExpiresAt());
result.put("shortUrlExpiresInSeconds", expiresInSeconds);
result.put("userId", userId);
result.put("ownerName", ownerName);
result.put("ownerPhone", ownerPhone);
result.put("avatarName", avatarName);
result.put("model", model);
// 图像检测结果
result.put("faceDetection", detectLog.toString());
if (!detectLog.getSuccess()) {
result.put("faceDetectionError", detectLog.getErrorMessage());
log.warn("图像检测失败: {}", detectLog.getErrorMessage());
} else {
log.info("图像检测成功,检测到 {} 张图像", detectLog.getFaceCount());
}
log.info("头衔上传处理完成文件URL: {}, 短链接: {}", fileUrl, shortUrl);
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("头衔上传处理失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "头衔上传处理失败: " + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 从URL中提取文件名
*/
private String extractFileNameFromUrl(String fileUrl) {
if (fileUrl == null || fileUrl.isEmpty()) {
return null;
}
// 从URL中提取文件名部分
// 例如: http://101.35.52.237:19005/car/filename.jpg -> filename.jpg
int lastSlashIndex = fileUrl.lastIndexOf('/');
if (lastSlashIndex != -1 && lastSlashIndex < fileUrl.length() - 1) {
return fileUrl.substring(lastSlashIndex + 1);
}
return fileUrl;
}
/**
* 分页查询图像检测日志
*/
@GetMapping("/logs")
@Operation(summary = "分页查询图像检测日志", description = "分页查询图像检测日志列表")
public ResponseEntity<Map<String, Object>> getLogs(
@Parameter(description = "页码", example = "1")
@RequestParam(defaultValue = "1") Integer current,
@Parameter(description = "每页大小", example = "10")
@RequestParam(defaultValue = "10") Integer size,
@Parameter(description = "是否成功")
@RequestParam(required = false) Boolean success,
@Parameter(description = "开始时间")
@RequestParam(required = false) String startTime,
@Parameter(description = "结束时间")
@RequestParam(required = false) String endTime,
@Parameter(description = "所有人姓名")
@RequestParam(required = false) String ownerName,
@Parameter(description = "所有人电话")
@RequestParam(required = false) String ownerPhone,
@Parameter(description = "头像名字")
@RequestParam(required = false) String avatarName) {
Map<String, Object> result = new HashMap<>();
try {
com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.rj.entity.FaceDetectLog> page =
faceDetectLogService.getPageList(current, size, success, startTime, endTime, ownerName, ownerPhone, avatarName);
result.put("success", true);
result.put("message", "查询成功");
result.put("data", page.getRecords());
result.put("total", page.getTotal());
result.put("current", page.getCurrent());
result.put("size", page.getSize());
result.put("pages", page.getPages());
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("查询图像检测日志失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "查询失败: " + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 根据ID查询图像检测日志详情
*/
@GetMapping("/logs/{id}")
@Operation(summary = "查询日志详情", description = "根据ID查询图像检测日志详情")
public ResponseEntity<Map<String, Object>> getLogById(
@Parameter(description = "日志ID", required = true)
@PathVariable Long id) {
Map<String, Object> result = new HashMap<>();
try {
log.info("查询图像检测日志详情ID: {}", id);
com.rj.entity.FaceDetectLog log = faceDetectLogService.getById(id);
if (log != null) {
result.put("success", true);
result.put("message", "查询成功");
result.put("data", log);
} else {
result.put("success", false);
result.put("message", "日志不存在");
}
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("查询日志详情失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "查询失败: " + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 查询图像检测统计信息
*/
@GetMapping("/statistics")
@Operation(summary = "查询统计信息", description = "查询图像检测统计信息")
public ResponseEntity<Map<String, Object>> getStatistics(
@Parameter(description = "开始时间")
@RequestParam(required = false) String startTime,
@Parameter(description = "结束时间")
@RequestParam(required = false) String endTime) {
Map<String, Object> result = new HashMap<>();
try {
Map<String, Object> statistics = faceDetectLogService.getStatistics(startTime, endTime);
result.put("success", true);
result.put("message", "查询成功");
result.put("data", statistics);
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("查询统计信息失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "查询失败: " + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
}