using Foxel.Controllers; using Foxel.Models; using Foxel.Models.Response.Face; using Foxel.Models.Response.Picture; using Foxel.Services.Management; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Foxel.Api.Management; [Authorize(Roles = "Administrator")] [Route("api/management/face")] public class FaceManagementController( IFaceManagementService faceManagementService, IFaceClusteringService faceClusteringService, ILogger logger) : BaseApiController { /// /// 获取所有用户的人脸聚类列表 /// [HttpGet("clusters")] public async Task>>> GetAllFaceClusters( [FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] int? userId = null) { try { var result = userId.HasValue ? await faceManagementService.GetUserFaceClustersAsync(userId.Value, page, pageSize) : await faceManagementService.GetFaceClustersAsync(page, pageSize); return Success(result, "获取人脸聚类列表成功"); } catch (Exception ex) { logger.LogError(ex, "管理员获取人脸聚类列表失败"); return Error>("获取人脸聚类列表失败", 500); } } /// /// 根据聚类获取图片(管理员可查看所有) /// [HttpGet("clusters/{clusterId}/pictures")] public async Task>>> GetPicturesByCluster( int clusterId, [FromQuery] int page = 1, [FromQuery] int pageSize = 20) { try { var result = await faceManagementService.GetPicturesByClusterAsync(clusterId, page, pageSize); return Success(result, "获取聚类图片成功"); } catch (KeyNotFoundException) { return Error>("找不到指定的人脸聚类", 404); } catch (Exception ex) { logger.LogError(ex, "管理员获取聚类图片失败: ClusterId={ClusterId}", clusterId); return Error>("获取聚类图片失败", 500); } } /// /// 更新人脸聚类信息(管理员) /// [HttpPut("clusters/{clusterId}")] public async Task>> UpdateCluster( int clusterId, [FromBody] UpdateClusterRequest request) { try { var result = await faceManagementService.UpdateClusterAsync( clusterId, request.PersonName, request.Description); return Success(result, "更新聚类信息成功"); } catch (KeyNotFoundException) { return Error("找不到指定的人脸聚类", 404); } catch (Exception ex) { logger.LogError(ex, "管理员更新聚类信息失败: ClusterId={ClusterId}", clusterId); return Error("更新聚类信息失败", 500); } } /// /// 开始全局人脸聚类(管理员) /// [HttpPost("clusters/analyze")] public async Task>> StartGlobalFaceClustering([FromQuery] int? userId = null) { try { if (userId.HasValue) { await faceClusteringService.ClusterUserFacesAsync(userId.Value); } else { await faceClusteringService.ClusterFacesAsync(); } return Success(true, "人脸聚类任务已开始"); } catch (Exception ex) { logger.LogError(ex, "管理员启动人脸聚类失败"); return Error("启动人脸聚类失败", 500); } } /// /// 合并聚类(管理员) /// [HttpPost("clusters/{targetClusterId}/merge")] public async Task>> MergeClusters( int targetClusterId, [FromBody] MergeClustersRequest request) { try { var result = await faceManagementService.MergeClustersAsync( request.SourceClusterId, targetClusterId); return Success(result, "合并聚类成功"); } catch (KeyNotFoundException ex) { return Error(ex.Message, 404); } catch (Exception ex) { logger.LogError(ex, "管理员合并聚类失败"); return Error("合并聚类失败", 500); } } /// /// 删除聚类(管理员) /// [HttpDelete("clusters/{clusterId}")] public async Task>> DeleteCluster(int clusterId) { try { var result = await faceManagementService.DeleteClusterAsync(clusterId); return Success(result, "删除聚类成功"); } catch (KeyNotFoundException) { return Error("找不到指定的人脸聚类", 404); } catch (Exception ex) { logger.LogError(ex, "管理员删除聚类失败: ClusterId={ClusterId}", clusterId); return Error("删除聚类失败", 500); } } /// /// 从聚类中移除人脸(管理员) /// [HttpDelete("faces/{faceId}/cluster")] public async Task>> RemoveFaceFromCluster(int faceId) { try { var result = await faceManagementService.RemoveFaceFromClusterAsync(faceId); return Success(result, "移除人脸成功"); } catch (Exception ex) { logger.LogError(ex, "管理员移除人脸失败: FaceId={FaceId}", faceId); return Error("移除人脸失败", 500); } } /// /// 获取人脸聚类统计信息 /// [HttpGet("statistics")] public async Task>> GetClusterStatistics() { try { var result = await faceManagementService.GetClusterStatisticsAsync(); return Success(result, "获取统计信息成功"); } catch (Exception ex) { logger.LogError(ex, "获取聚类统计信息失败"); return Error("获取统计信息失败", 500); } } } public record UpdateClusterRequest { public string? PersonName { get; set; } public string? Description { get; set; } } public record MergeClustersRequest { public int SourceClusterId { get; set; } } public record FaceClusterStatistics { public int TotalClusters { get; set; } public int TotalFaces { get; set; } public int UnclusteredFaces { get; set; } public int NamedClusters { get; set; } public Dictionary ClustersByUser { get; set; } = new(); }