using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MilitaryTrainingManagement.Authorization; using MilitaryTrainingManagement.Models.DTOs; using MilitaryTrainingManagement.Models.Entities; using MilitaryTrainingManagement.Models.Enums; using MilitaryTrainingManagement.Services.Interfaces; namespace MilitaryTrainingManagement.Controllers; /// /// 人员管理控制器 /// [Authorize] public class PersonnelController : BaseApiController { private readonly IPersonnelService _personnelService; private readonly IFileUploadService _fileUploadService; private readonly IOrganizationalAuthorizationService _authorizationService; public PersonnelController( IPersonnelService personnelService, IFileUploadService fileUploadService, IOrganizationalAuthorizationService authorizationService) { _personnelService = personnelService; _fileUploadService = fileUploadService; _authorizationService = authorizationService; } /// /// 根据出生年月计算年龄 /// private int CalculateAge(string? birthDate) { if (string.IsNullOrWhiteSpace(birthDate)) return 25; // 如果没有出生年月,返回默认值25岁 try { // birthDate格式为 "YYYY-MM" var parts = birthDate.Split('-'); if (parts.Length != 2) return 25; if (!int.TryParse(parts[0], out var year) || !int.TryParse(parts[1], out var month)) return 25; var birthDateTime = new DateTime(year, month, 1); var today = DateTime.Today; var age = today.Year - birthDateTime.Year; // 如果今年的生日还没到,年龄减1 if (today.Month < birthDateTime.Month) age--; return age > 0 ? age : 25; // 确保年龄为正数 } catch { return 25; // 解析失败返回默认值 } } /// /// 获取人员列表(基于层级权限控制) /// [HttpGet] public async Task GetPersonnel( [FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 10, [FromQuery] string? status = null) { var unitId = GetCurrentUnitId(); var userLevel = GetCurrentUnitLevel(); if (unitId == null || userLevel == null) { return Unauthorized(); } var allPersonnel = await _personnelService.GetVisiblePersonnelAsync(unitId.Value, userLevel.Value); // 状态筛选 if (!string.IsNullOrEmpty(status) && Enum.TryParse(status, out var statusFilter)) { allPersonnel = allPersonnel.Where(p => p.Status == statusFilter); } var totalCount = allPersonnel.Count(); var items = allPersonnel .Skip((pageNumber - 1) * pageSize) .Take(pageSize) .Select(MapToResponse) .ToList(); return Ok(new { items, totalCount, pageNumber, pageSize, totalPages = (int)Math.Ceiling(totalCount / (double)pageSize) }); } /// /// 映射人员实体到响应DTO /// private static PersonnelResponse MapToResponse(Personnel personnel) { return new PersonnelResponse { Id = personnel.Id, Name = personnel.Name, PhotoPath = personnel.PhotoPath, Position = personnel.Position, Rank = personnel.Rank, Gender = personnel.Gender, IdNumber = personnel.IdNumber, ProfessionalTitle = personnel.ProfessionalTitle, EducationLevel = personnel.EducationLevel, Age = personnel.Age, Height = personnel.Height, ContactInfo = personnel.ContactInfo, Hometown = personnel.Hometown, TrainingParticipation = personnel.TrainingParticipation, Achievements = personnel.Achievements, SupportingDocuments = personnel.SupportingDocuments, Ethnicity = personnel.Ethnicity, PoliticalStatus = personnel.PoliticalStatus, BirthDate = personnel.BirthDate, EnlistmentDate = personnel.EnlistmentDate, Specialty = personnel.Specialty, SubmittedByUnitId = personnel.SubmittedByUnitId, SubmittedByUnitName = personnel.SubmittedByUnit?.Name, ApprovedLevel = personnel.ApprovedLevel, ApprovedByUnitId = personnel.ApprovedByUnitId, ApprovedByUnitName = personnel.ApprovedByUnit?.Name, Status = personnel.Status, SubmittedAt = personnel.SubmittedAt, ApprovedAt = personnel.ApprovedAt, PendingUpgradeByUnitId = personnel.PendingUpgradeByUnitId }; } /// /// 获取待审批的人员列表 /// [HttpGet("pending-approval")] public async Task GetPendingApproval() { var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } var personnel = await _personnelService.GetPendingApprovalPersonnelAsync(unitId.Value); return Ok(personnel); } [HttpGet("{id}")] public async Task GetById(int id) { var personnel = await _personnelService.GetByIdAsync(id); if (personnel == null) { return NotFound(); } // 检查访问权限 var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } var hasAccess = await _authorizationService.CanAccessUnitAsync( unitId.Value, personnel.SubmittedByUnitId); if (!hasAccess) { return Forbid(); } return Ok(MapToResponse(personnel)); } /// /// 提交人员数据(包含文件上传和验证) /// [HttpPost("submit")] public async Task SubmitPersonnel([FromForm] SubmitPersonnelRequest request, IFormFile? photo, IFormFile? supportingDocument) { var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } var personnel = new Personnel { Name = request.Name, Unit = request.Unit, Position = request.Position, Rank = request.Rank, Gender = "男", // 默认值 IdNumber = request.IdNumber, ProfessionalTitle = request.ProfessionalTitle, EducationLevel = request.EducationLevel, Age = CalculateAge(request.BirthDate), // 根据出生年月计算年龄 Height = null, ContactInfo = null, Hometown = request.Hometown, TrainingParticipation = request.TrainingParticipation, Achievements = request.Achievements, Ethnicity = request.Ethnicity, PoliticalStatus = request.PoliticalStatus, BirthDate = request.BirthDate, EnlistmentDate = request.EnlistmentDate, Specialty = request.Specialty, SubmittedByUnitId = unitId.Value }; try { var created = await _personnelService.SubmitPersonnelAsync(personnel, photo, supportingDocument); return CreatedAtAction(nameof(GetById), new { id = created.Id }, created); } catch (ArgumentException ex) { return BadRequest(ex.Message); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [HttpPost] public async Task Create([FromForm] CreatePersonnelRequest request, IFormFile? photo, IFormFile? supportingDocuments) { // 调试:打印接收到的数据 Console.WriteLine($"接收到的数据: Name={request.Name}, Position={request.Position}, Rank={request.Rank}"); // 返回详细的验证错误 if (!ModelState.IsValid) { Console.WriteLine("模型验证失败:"); foreach (var key in ModelState.Keys) { var modelErrors = ModelState[key]?.Errors; if (modelErrors != null && modelErrors.Count > 0) { Console.WriteLine($" {key}: {string.Join(", ", modelErrors.Select(e => e.ErrorMessage))}"); } } var errors = ModelState .Where(x => x.Value?.Errors.Count > 0) .ToDictionary( kvp => kvp.Key, kvp => kvp.Value?.Errors.Select(e => e.ErrorMessage).ToArray() ); return BadRequest(new { message = "验证失败", errors }); } var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } var personnel = new Personnel { Name = request.Name, Unit = request.Unit, Position = request.Position, Rank = request.Rank, Gender = "男", // 默认值 IdNumber = request.IdNumber, ProfessionalTitle = request.ProfessionalTitle, EducationLevel = request.EducationLevel, Age = CalculateAge(request.BirthDate), // 根据出生年月计算年龄 Height = null, ContactInfo = null, Hometown = request.Hometown, TrainingParticipation = request.TrainingParticipation, Achievements = request.Achievements, Ethnicity = request.Ethnicity, PoliticalStatus = request.PoliticalStatus, BirthDate = request.BirthDate, EnlistmentDate = request.EnlistmentDate, Specialty = request.Specialty, SubmittedByUnitId = unitId.Value }; try { var created = await _personnelService.SubmitPersonnelAsync(personnel, photo, supportingDocuments); return CreatedAtAction(nameof(GetById), new { id = created.Id }, created); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } catch (InvalidOperationException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 更新人员信息(仅限未审批的人员) /// [HttpPut("{id}")] public async Task Update(int id, [FromForm] UpdatePersonnelRequest request, IFormFile? photo, IFormFile? supportingDocuments) { var personnel = await _personnelService.GetByIdAsync(id); if (personnel == null) { return NotFound(); } // 检查是否可以修改 var canModify = await _personnelService.CanModifyPersonnelAsync(id); if (!canModify) { return BadRequest("已审批的人员记录不能直接修改,请使用修改申请功能"); } // 检查权限 var unitId = GetCurrentUnitId(); if (unitId == null || personnel.SubmittedByUnitId != unitId.Value) { return Forbid(); } // 更新人员信息 personnel.Name = request.Name; personnel.Position = request.Position; personnel.Rank = request.Rank; personnel.Gender = request.Gender; personnel.ProfessionalTitle = request.ProfessionalTitle; personnel.EducationLevel = request.EducationLevel; personnel.Age = request.Age; personnel.Height = request.Height; personnel.ContactInfo = request.ContactInfo; personnel.Hometown = request.Hometown; personnel.TrainingParticipation = request.TrainingParticipation; personnel.Achievements = request.Achievements; // 处理照片上传 if (photo != null) { if (!string.IsNullOrEmpty(personnel.PhotoPath)) { await _fileUploadService.DeleteFileAsync(personnel.PhotoPath); } personnel.PhotoPath = await _fileUploadService.UploadPhotoAsync(photo); } // 处理文档上传 if (supportingDocuments != null) { var documentPath = await _fileUploadService.UploadDocumentAsync(supportingDocuments); if (string.IsNullOrEmpty(personnel.SupportingDocuments)) { personnel.SupportingDocuments = documentPath; } else { personnel.SupportingDocuments += ";" + documentPath; } } var updated = await _personnelService.UpdateAsync(personnel); return Ok(updated); } /// /// 请求修改已审批的人员记录 /// [HttpPost("{id}/request-modification")] public async Task RequestModification(int id, [FromBody] PersonnelModificationRequest request) { var userId = GetCurrentUserId(); if (userId == null) { return Unauthorized(); } try { var personnel = new Personnel { Name = request.ModifiedPersonnel.Name, Position = request.ModifiedPersonnel.Position, Rank = request.ModifiedPersonnel.Rank, Gender = request.ModifiedPersonnel.Gender, ProfessionalTitle = request.ModifiedPersonnel.ProfessionalTitle, EducationLevel = request.ModifiedPersonnel.EducationLevel, Age = request.ModifiedPersonnel.Age, Height = request.ModifiedPersonnel.Height, ContactInfo = request.ModifiedPersonnel.ContactInfo, Hometown = request.ModifiedPersonnel.Hometown, TrainingParticipation = request.ModifiedPersonnel.TrainingParticipation, Achievements = request.ModifiedPersonnel.Achievements }; var approvalRequest = await _personnelService.RequestPersonnelModificationAsync( id, userId.Value, request.Reason, personnel); return Ok(approvalRequest); } catch (ArgumentException ex) { return BadRequest(ex.Message); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } /// /// 上传人员照片 /// [HttpPost("{id}/photo")] public async Task UploadPhoto(int id, IFormFile file) { var personnel = await _personnelService.GetByIdAsync(id); if (personnel == null) { return NotFound("人员记录不存在"); } try { // 删除旧照片 if (!string.IsNullOrEmpty(personnel.PhotoPath)) { await _fileUploadService.DeleteFileAsync(personnel.PhotoPath); } var photoPath = await _fileUploadService.UploadPhotoAsync(file); personnel.PhotoPath = photoPath; await _personnelService.UpdateAsync(personnel); return Ok(new { photoPath }); } catch (ArgumentException ex) { return BadRequest(ex.Message); } } /// /// 上传支持文档 /// [HttpPost("{id}/documents")] public async Task UploadDocument(int id, IFormFile file) { var personnel = await _personnelService.GetByIdAsync(id); if (personnel == null) { return NotFound("人员记录不存在"); } try { var documentPath = await _fileUploadService.UploadDocumentAsync(file); // 追加到现有文档列表(用分号分隔) if (string.IsNullOrEmpty(personnel.SupportingDocuments)) { personnel.SupportingDocuments = documentPath; } else { personnel.SupportingDocuments += ";" + documentPath; } await _personnelService.UpdateAsync(personnel); return Ok(new { documentPath }); } catch (ArgumentException ex) { return BadRequest(ex.Message); } } /// /// 验证照片格式 /// [HttpPost("validate-photo")] public async Task ValidatePhoto(IFormFile file) { var result = await _fileUploadService.ValidatePhotoAsync(file); if (result.IsValid) { return Ok(new { isValid = true, width = result.Width, height = result.Height }); } return BadRequest(new { isValid = false, error = result.ErrorMessage }); } /// /// 审批人员 /// [HttpPost("{id}/approve")] [Authorize(Policy = "BattalionLevel")] // 营级及以上权限 public async Task Approve(int id) { var unitId = GetCurrentUnitId(); var userId = GetCurrentUserId(); if (unitId == null || userId == null) { return Unauthorized(); } // 检查审批权限 var canApprove = await _personnelService.CanApprovePersonnelAsync(userId.Value, id); if (!canApprove) { return StatusCode(403, new { message = "您没有权限审批此人员" }); } try { // 不传递level参数,让服务层根据人员所在单位自动确定等级 var personnel = await _personnelService.ApproveAsync(id, unitId.Value); return Ok(MapToResponse(personnel)); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 拒绝人员 /// [HttpPost("{id}/reject")] [Authorize(Policy = "BattalionLevel")] // 营级及以上权限 public async Task Reject(int id, [FromBody] RejectPersonnelRequest request) { var userId = GetCurrentUserId(); if (userId == null) { return Unauthorized(); } // 检查审批权限 var canApprove = await _personnelService.CanApprovePersonnelAsync(userId.Value, id); if (!canApprove) { return StatusCode(403, new { message = "您没有权限拒绝此人员" }); } var personnel = await _personnelService.RejectAsync(id, userId.Value); return Ok(personnel); } /// /// 批量审批人员 /// [HttpPost("batch-approve")] [Authorize(Policy = "RegimentLevel")] // 团级及以上权限 public async Task BatchApprove([FromBody] BatchApprovePersonnelRequest request) { var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } try { var approvedPersonnel = await _personnelService.BatchApprovePersonnelAsync( request.PersonnelIds, unitId.Value, request.Level); return Ok(new { approvedCount = approvedPersonnel.Count(), approvedPersonnel = approvedPersonnel }); } catch (ArgumentException ex) { return BadRequest(ex.Message); } } /// /// 批量拒绝人员 /// [HttpPost("batch-reject")] [Authorize(Policy = "RegimentLevel")] // 团级及以上权限 public async Task BatchReject([FromBody] BatchRejectPersonnelRequest request) { var userId = GetCurrentUserId(); if (userId == null) { return Unauthorized(); } try { var rejectedPersonnel = await _personnelService.BatchRejectPersonnelAsync( request.PersonnelIds, userId.Value, request.Reason); return Ok(new { rejectedCount = rejectedPersonnel.Count(), rejectedPersonnel = rejectedPersonnel }); } catch (ArgumentException ex) { return BadRequest(ex.Message); } } /// /// 跨层级人员转移 /// [HttpPost("{id}/transfer")] [Authorize(Policy = "BattalionLevel")] // 营级及以上权限 public async Task TransferPersonnel(int id, [FromBody] TransferPersonnelRequest request) { var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } try { var personnel = await _personnelService.TransferPersonnelAsync( id, request.TargetUnitId, unitId.Value); return Ok(personnel); } catch (ArgumentException ex) { return BadRequest(ex.Message); } catch (UnauthorizedAccessException ex) { return Forbid(ex.Message); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } /// /// 获取人员审批历史 /// [HttpGet("{id}/approval-history")] public async Task GetApprovalHistory(int id) { var personnel = await _personnelService.GetByIdAsync(id); if (personnel == null) { return NotFound(); } // 检查访问权限 var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } var hasAccess = await _authorizationService.CanAccessUnitAsync( unitId.Value, personnel.SubmittedByUnitId); if (!hasAccess) { return Forbid(); } var history = await _personnelService.GetPersonnelApprovalHistoryAsync(id); return Ok(history); } /// /// 删除人员记录 /// [HttpDelete("{id}")] public async Task Delete(int id) { var personnel = await _personnelService.GetByIdAsync(id); if (personnel == null) { return NotFound(new { message = "人员记录不存在" }); } // 检查权限:只有提交单位或上级单位可以删除 var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } // 检查是否是提交单位 if (personnel.SubmittedByUnitId != unitId.Value) { // 检查是否有上级权限 var hasAccess = await _authorizationService.CanAccessUnitAsync( unitId.Value, personnel.SubmittedByUnitId); if (!hasAccess) { return Forbid(); } } // 只能删除待审批状态的人员 if (personnel.Status != PersonnelStatus.Pending) { return BadRequest(new { message = "只能删除待审批状态的人员记录" }); } try { await _personnelService.DeleteAsync(id); return NoContent(); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 发起向上申报请求 /// [HttpPost("{id}/request-upgrade")] [Authorize(Policy = "BattalionLevel")] // 营级及以上权限 public async Task RequestUpgrade(int id) { var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } try { var personnel = await _personnelService.RequestUpgradeAsync(id, unitId.Value); return Ok(MapToResponse(personnel)); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 审批向上申报请求 /// [HttpPost("{id}/approve-upgrade")] [Authorize(Policy = "BattalionLevel")] // 营级及以上权限 public async Task ApproveUpgrade(int id) { var unitId = GetCurrentUnitId(); if (unitId == null) { return Unauthorized(); } try { var personnel = await _personnelService.ApproveUpgradeAsync(id, unitId.Value); return Ok(MapToResponse(personnel)); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } }