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 });
}
}
}