diff --git a/src/MilitaryTrainingManagement/Controllers/PersonnelController.cs b/src/MilitaryTrainingManagement/Controllers/PersonnelController.cs
index 6c50110..396af82 100644
--- a/src/MilitaryTrainingManagement/Controllers/PersonnelController.cs
+++ b/src/MilitaryTrainingManagement/Controllers/PersonnelController.cs
@@ -139,7 +139,8 @@ public class PersonnelController : BaseApiController
ApprovedByUnitName = personnel.ApprovedByUnit?.Name,
Status = personnel.Status,
SubmittedAt = personnel.SubmittedAt,
- ApprovedAt = personnel.ApprovedAt
+ ApprovedAt = personnel.ApprovedAt,
+ PendingUpgradeByUnitId = personnel.PendingUpgradeByUnitId
};
}
@@ -738,4 +739,52 @@ public class PersonnelController : BaseApiController
}
}
+ ///
+ /// 发起向上申报请求
+ ///
+ [HttpPost("{id}/request-upgrade")]
+ [Authorize(Policy = "RegimentLevel")] // 团级及以上权限
+ 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 = "RegimentLevel")] // 团级及以上权限
+ 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 });
+ }
+ }
+
}
diff --git a/src/MilitaryTrainingManagement/Models/DTOs/PersonnelDTOs.cs b/src/MilitaryTrainingManagement/Models/DTOs/PersonnelDTOs.cs
index b951588..e056bd6 100644
--- a/src/MilitaryTrainingManagement/Models/DTOs/PersonnelDTOs.cs
+++ b/src/MilitaryTrainingManagement/Models/DTOs/PersonnelDTOs.cs
@@ -159,6 +159,7 @@ public class PersonnelResponse
public PersonnelStatus Status { get; set; }
public DateTime SubmittedAt { get; set; }
public DateTime? ApprovedAt { get; set; }
+ public int? PendingUpgradeByUnitId { get; set; } // 待向上申报的申报单位ID
}
///
diff --git a/src/MilitaryTrainingManagement/Models/Entities/Personnel.cs b/src/MilitaryTrainingManagement/Models/Entities/Personnel.cs
index e384099..6315f44 100644
--- a/src/MilitaryTrainingManagement/Models/Entities/Personnel.cs
+++ b/src/MilitaryTrainingManagement/Models/Entities/Personnel.cs
@@ -40,4 +40,8 @@ public class Personnel
public PersonnelStatus Status { get; set; } = PersonnelStatus.Pending;
public DateTime SubmittedAt { get; set; } = DateTime.UtcNow;
public DateTime? ApprovedAt { get; set; }
+
+ // 向上申报相关字段
+ public int? PendingUpgradeByUnitId { get; set; } // 发起向上申报的单位ID
+ public OrganizationalUnit? PendingUpgradeByUnit { get; set; }
}
diff --git a/src/MilitaryTrainingManagement/Program.cs b/src/MilitaryTrainingManagement/Program.cs
index 1bb45bc..781d59d 100644
--- a/src/MilitaryTrainingManagement/Program.cs
+++ b/src/MilitaryTrainingManagement/Program.cs
@@ -235,6 +235,9 @@ using (var scope = app.Services.CreateScope())
IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('Personnel') AND name = 'Specialty')
ALTER TABLE Personnel ADD Specialty nvarchar(200) NULL;
+
+ IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('Personnel') AND name = 'PendingUpgradeByUnitId')
+ ALTER TABLE Personnel ADD PendingUpgradeByUnitId INT NULL;
");
Console.WriteLine("Personnel 表列检查完成");
}
diff --git a/src/MilitaryTrainingManagement/Services/Implementations/PersonnelService.cs b/src/MilitaryTrainingManagement/Services/Implementations/PersonnelService.cs
index 6dccf49..67559f2 100644
--- a/src/MilitaryTrainingManagement/Services/Implementations/PersonnelService.cs
+++ b/src/MilitaryTrainingManagement/Services/Implementations/PersonnelService.cs
@@ -85,6 +85,7 @@ public class PersonnelService : IPersonnelService
{
var personnel = await _context.Personnel
.Include(p => p.SubmittedByUnit)
+ .Include(p => p.ApprovedByUnit)
.FirstOrDefaultAsync(p => p.Id == personnelId);
if (personnel == null)
throw new ArgumentException("人员记录不存在");
@@ -93,7 +94,9 @@ public class PersonnelService : IPersonnelService
if (approvedByUnit == null)
throw new ArgumentException("审批单位不存在");
- // 人员等级变更为审批单位的等级
+ var previousStatus = personnel.Status;
+ var previousLevel = personnel.ApprovedLevel;
+
PersonnelLevel actualLevel;
if (level.HasValue)
{
@@ -101,19 +104,40 @@ public class PersonnelService : IPersonnelService
}
else
{
- // 根据审批单位的层级确定人员等级
- actualLevel = (PersonnelLevel)(int)approvedByUnit.Level;
+ // 区分首次审批和向上申报两种场景
+ if (previousStatus == PersonnelStatus.Pending)
+ {
+ // 首次审批:人员等级根据提交单位的层级确定
+ // 例如:营级单位提交的人才,团级审批后应为"营级人才"
+ actualLevel = (PersonnelLevel)(int)personnel.SubmittedByUnit!.Level;
+
+ // 验证审批单位层级必须高于提交单位层级(数值越小层级越高)
+ var unitLevelValue = (int)approvedByUnit.Level;
+ var submittedUnitLevelValue = (int)personnel.SubmittedByUnit!.Level;
+ if (unitLevelValue >= submittedUnitLevelValue)
+ throw new ArgumentException("审批单位层级必须高于提交单位层级");
+ }
+ else if (previousStatus == PersonnelStatus.Approved)
+ {
+ // 向上申报:人员等级升级为上报单位(即之前的审批单位)的层级
+ // 例如:营级人才由团级向上申报,师级审批后应为"团级人才"
+ if (personnel.ApprovedByUnit == null)
+ throw new ArgumentException("无法确定上报单位");
+
+ actualLevel = (PersonnelLevel)(int)personnel.ApprovedByUnit.Level;
+
+ // 验证审批单位层级必须高于当前审批单位层级(数值越小层级越高)
+ var unitLevelValue = (int)approvedByUnit.Level;
+ var currentApprovedUnitLevelValue = (int)personnel.ApprovedByUnit.Level;
+ if (unitLevelValue >= currentApprovedUnitLevelValue)
+ throw new ArgumentException("审批单位层级必须高于当前审批单位层级");
+ }
+ else
+ {
+ throw new ArgumentException("该人员状态不允许审批");
+ }
}
- // 验证审批单位层级必须高于或等于人员等级(数值越小层级越高)
- var unitLevelValue = (int)approvedByUnit.Level;
- var personnelLevelValue = (int)actualLevel;
- if (unitLevelValue > personnelLevelValue)
- throw new ArgumentException("审批单位层级不足以审批该等级人才");
-
- var previousStatus = personnel.Status;
- var previousLevel = personnel.ApprovedLevel;
-
personnel.Status = PersonnelStatus.Approved;
personnel.ApprovedByUnitId = approvedByUnitId;
personnel.ApprovedLevel = actualLevel;
@@ -569,15 +593,20 @@ public class PersonnelService : IPersonnelService
if (user.OrganizationalUnitId == personnel.SubmittedByUnitId)
return false;
- // 如果是已审批的人员,检查当前用户单位是否比已审批单位层级更高
+ // 如果是已审批的人员(向上申报场景)
if (personnel.Status == PersonnelStatus.Approved && personnel.ApprovedByUnitId.HasValue)
{
// 用户单位层级必须高于已审批单位层级(数值越小层级越高)
if ((int)user.OrganizationalUnit!.Level >= (int)personnel.ApprovedByUnit!.Level)
return false;
+
+ // 向上申报场景:检查用户单位是否是当前审批单位的上级
+ var isParentOfApprovedUnit = await _organizationService.IsParentUnitAsync(
+ user.OrganizationalUnitId, personnel.ApprovedByUnitId.Value);
+ return isParentOfApprovedUnit;
}
- // 检查用户的组织单位是否是提交单位的上级
+ // 首次审批场景:检查用户的组织单位是否是提交单位的上级
var isParent = await _organizationService.IsParentUnitAsync(user.OrganizationalUnitId, personnel.SubmittedByUnitId);
return isParent;
@@ -619,4 +648,96 @@ public class PersonnelService : IPersonnelService
return user?.Id ?? 0; // 如果找不到用户,返回0作为系统操作
}
+
+ ///
+ /// 发起向上申报请求
+ ///
+ public async Task RequestUpgradeAsync(int personnelId, int requestByUnitId)
+ {
+ var personnel = await _context.Personnel
+ .Include(p => p.SubmittedByUnit)
+ .Include(p => p.ApprovedByUnit)
+ .FirstOrDefaultAsync(p => p.Id == personnelId);
+
+ if (personnel == null)
+ throw new ArgumentException("人员记录不存在");
+
+ if (personnel.Status != PersonnelStatus.Approved)
+ throw new ArgumentException("只有已审批的人员才能向上申报");
+
+ if (personnel.PendingUpgradeByUnitId.HasValue)
+ throw new ArgumentException("该人员已有待处理的向上申报请求");
+
+ var requestByUnit = await _context.OrganizationalUnits.FindAsync(requestByUnitId);
+ if (requestByUnit == null)
+ throw new ArgumentException("申报单位不存在");
+
+ // 验证申报单位必须是当前审批单位
+ if (personnel.ApprovedByUnitId != requestByUnitId)
+ throw new ArgumentException("只有当前审批单位才能发起向上申报");
+
+ // 师级人才不能再向上申报
+ if (personnel.ApprovedLevel == PersonnelLevel.Division)
+ throw new ArgumentException("师级人才不能再向上申报");
+
+ // 标记为待向上申报
+ personnel.PendingUpgradeByUnitId = requestByUnitId;
+
+ await _context.SaveChangesAsync();
+
+ _logger.LogInformation("人员 {PersonnelId} 已由单位 {UnitId} 发起向上申报请求",
+ personnelId, requestByUnitId);
+
+ return personnel;
+ }
+
+ ///
+ /// 审批向上申报请求
+ ///
+ public async Task ApproveUpgradeAsync(int personnelId, int approvedByUnitId)
+ {
+ var personnel = await _context.Personnel
+ .Include(p => p.SubmittedByUnit)
+ .Include(p => p.ApprovedByUnit)
+ .Include(p => p.PendingUpgradeByUnit)
+ .FirstOrDefaultAsync(p => p.Id == personnelId);
+
+ if (personnel == null)
+ throw new ArgumentException("人员记录不存在");
+
+ if (!personnel.PendingUpgradeByUnitId.HasValue)
+ throw new ArgumentException("该人员没有待处理的向上申报请求");
+
+ var approvedByUnit = await _context.OrganizationalUnits.FindAsync(approvedByUnitId);
+ if (approvedByUnit == null)
+ throw new ArgumentException("审批单位不存在");
+
+ // 验证审批单位必须是申报单位的上级
+ var isParent = await _organizationService.IsParentUnitAsync(approvedByUnitId, personnel.PendingUpgradeByUnitId.Value);
+ if (!isParent)
+ throw new ArgumentException("审批单位必须是申报单位的上级");
+
+ var previousLevel = personnel.ApprovedLevel;
+
+ // 人才等级升级为申报单位的等级
+ var newLevel = (PersonnelLevel)(int)personnel.PendingUpgradeByUnit!.Level;
+
+ personnel.ApprovedLevel = newLevel;
+ personnel.ApprovedByUnitId = approvedByUnitId;
+ personnel.ApprovedAt = DateTime.UtcNow;
+ personnel.PendingUpgradeByUnitId = null; // 清除待申报标记
+
+ await _context.SaveChangesAsync();
+
+ // 记录审批历史
+ var userId = await GetUserIdByUnitAsync(approvedByUnitId);
+ await RecordApprovalHistoryAsync(personnelId, PersonnelApprovalAction.LevelUpgraded,
+ PersonnelStatus.Approved, PersonnelStatus.Approved, previousLevel, newLevel,
+ userId, approvedByUnitId, $"向上申报通过,等级从{GetLevelName(previousLevel)}升级为{GetLevelName(newLevel)}");
+
+ _logger.LogInformation("人员 {PersonnelId} 向上申报已被单位 {UnitId} 审批通过,等级升级为 {Level}",
+ personnelId, approvedByUnitId, newLevel);
+
+ return personnel;
+ }
}
diff --git a/src/MilitaryTrainingManagement/Services/Interfaces/IPersonnelService.cs b/src/MilitaryTrainingManagement/Services/Interfaces/IPersonnelService.cs
index 7a6e855..a21b71e 100644
--- a/src/MilitaryTrainingManagement/Services/Interfaces/IPersonnelService.cs
+++ b/src/MilitaryTrainingManagement/Services/Interfaces/IPersonnelService.cs
@@ -75,6 +75,16 @@ public interface IPersonnelService
/// 验证审批权限
///
Task CanApprovePersonnelAsync(int userId, int personnelId);
+
+ ///
+ /// 发起向上申报请求
+ ///
+ Task RequestUpgradeAsync(int personnelId, int requestByUnitId);
+
+ ///
+ /// 审批向上申报请求
+ ///
+ Task ApproveUpgradeAsync(int personnelId, int approvedByUnitId);
}
///
diff --git a/src/MilitaryTrainingManagement/wwwroot/uploads/documents/fe649db1-6110-4015-8acd-1c4ebf844ed0.jpg b/src/MilitaryTrainingManagement/wwwroot/uploads/documents/fe649db1-6110-4015-8acd-1c4ebf844ed0.jpg
new file mode 100644
index 0000000..f7a5b18
Binary files /dev/null and b/src/MilitaryTrainingManagement/wwwroot/uploads/documents/fe649db1-6110-4015-8acd-1c4ebf844ed0.jpg differ
diff --git a/src/MilitaryTrainingManagement/wwwroot/uploads/photos/af379bda-6c88-4d5e-96e1-5ae10c18be82.jpg b/src/MilitaryTrainingManagement/wwwroot/uploads/photos/af379bda-6c88-4d5e-96e1-5ae10c18be82.jpg
new file mode 100644
index 0000000..3802c60
Binary files /dev/null and b/src/MilitaryTrainingManagement/wwwroot/uploads/photos/af379bda-6c88-4d5e-96e1-5ae10c18be82.jpg differ
diff --git a/src/MilitaryTrainingManagement/wwwroot/uploads/photos/ba845008-3425-47d3-9536-262a38a5141c.jpg b/src/MilitaryTrainingManagement/wwwroot/uploads/photos/ba845008-3425-47d3-9536-262a38a5141c.jpg
new file mode 100644
index 0000000..3802c60
Binary files /dev/null and b/src/MilitaryTrainingManagement/wwwroot/uploads/photos/ba845008-3425-47d3-9536-262a38a5141c.jpg differ
diff --git a/src/MilitaryTrainingManagement/wwwroot/uploads/photos/e2a93ae7-5e95-4ac7-be94-595cb93582f9.jpg b/src/MilitaryTrainingManagement/wwwroot/uploads/photos/e2a93ae7-5e95-4ac7-be94-595cb93582f9.jpg
new file mode 100644
index 0000000..3802c60
Binary files /dev/null and b/src/MilitaryTrainingManagement/wwwroot/uploads/photos/e2a93ae7-5e95-4ac7-be94-595cb93582f9.jpg differ
diff --git a/src/frontend/src/api/personnel.ts b/src/frontend/src/api/personnel.ts
index b451364..c290713 100644
--- a/src/frontend/src/api/personnel.ts
+++ b/src/frontend/src/api/personnel.ts
@@ -55,5 +55,17 @@ export const personnelApi = {
async getPendingApprovals(): Promise {
const response = await apiClient.get('/personnel/pending')
return response.data
+ },
+
+ // 发起向上申报请求
+ async requestUpgrade(personnelId: number): Promise {
+ const response = await apiClient.post(`/personnel/${personnelId}/request-upgrade`)
+ return response.data
+ },
+
+ // 审批向上申报请求
+ async approveUpgrade(personnelId: number): Promise {
+ const response = await apiClient.post(`/personnel/${personnelId}/approve-upgrade`)
+ return response.data
}
}
diff --git a/src/frontend/src/layouts/MainLayout.vue b/src/frontend/src/layouts/MainLayout.vue
index f9f8fe8..1367444 100644
--- a/src/frontend/src/layouts/MainLayout.vue
+++ b/src/frontend/src/layouts/MainLayout.vue
@@ -31,22 +31,6 @@
创建配额
-
-
-
-
- 上报管理
-
- 上报列表
- 数据汇总
-
-
-
-
-
- 数据汇总
-
-
@@ -106,7 +90,6 @@ import {
HomeFilled,
OfficeBuilding,
Box,
- DataAnalysis,
User,
Checked,
Document,
diff --git a/src/frontend/src/types/index.ts b/src/frontend/src/types/index.ts
index 712f1b9..656acc2 100644
--- a/src/frontend/src/types/index.ts
+++ b/src/frontend/src/types/index.ts
@@ -177,6 +177,7 @@ export interface Personnel {
status: PersonnelStatus
submittedAt: string
approvedAt: string | null
+ pendingUpgradeByUnitId: number | null // 待向上申报的申报单位ID
}
export interface CreatePersonnelRequest {
diff --git a/src/frontend/src/views/allocations/AllocationReport.vue b/src/frontend/src/views/allocations/AllocationReport.vue
index 31f54ea..6d34819 100644
--- a/src/frontend/src/views/allocations/AllocationReport.vue
+++ b/src/frontend/src/views/allocations/AllocationReport.vue
@@ -75,7 +75,7 @@
label-width="120px"
@submit.prevent="handleSubmit"
>
-
+
(() => {
]
}
- // 连部需要选择上报目标
- if (isCompanyLevel.value) {
- baseRules.reportToLevel = [
- { required: true, message: '请选择上报目标', trigger: 'change' }
- ]
- }
+ // 连部需要选择上报目标(暂时注释)
+ // if (isCompanyLevel.value) {
+ // baseRules.reportToLevel = [
+ // { required: true, message: '请选择上报目标', trigger: 'change' }
+ // ]
+ // }
// 只有师团/团级才需要验证不超过剩余配额
if (!isBattalionOrBelow.value) {
@@ -342,10 +343,12 @@ async function handleSubmit() {
// 构建确认信息
let confirmMessage = ''
- if (isCompanyLevel.value) {
- const targetName = form.reportToLevel === 'Battalion' ? '营部' : '团部'
- confirmMessage = `本次消耗数量:${form.actualCompletion} ${allocation.value?.unit}\n上报目标:${targetName}\n\n确认提交吗?`
- } else if (isBattalionOrBelow.value) {
+ // 连部上报目标选择功能暂时注释
+ // if (isCompanyLevel.value) {
+ // const targetName = form.reportToLevel === 'Battalion' ? '营部' : '团部'
+ // confirmMessage = `本次消耗数量:${form.actualCompletion} ${allocation.value?.unit}\n上报目标:${targetName}\n\n确认提交吗?`
+ // } else
+ if (isBattalionOrBelow.value) {
confirmMessage = `本次消耗数量:${form.actualCompletion} ${allocation.value?.unit}\n\n确认提交吗?`
} else {
confirmMessage = `本次上报数量:${form.actualCompletion} ${allocation.value?.unit}\n上报后总数:${newTotal} ${allocation.value?.unit}\n\n确认提交吗?`
@@ -365,12 +368,12 @@ async function handleSubmit() {
if (!distribution.value) return
- // 构建备注信息(包含上报目标)
+ // 构建备注信息(上报目标功能暂时注释)
let remarks = form.remarks || ''
- if (isCompanyLevel.value && form.reportToLevel) {
- const targetName = form.reportToLevel === 'Battalion' ? '营部' : '团部'
- remarks = remarks ? `[上报到${targetName}] ${remarks}` : `[上报到${targetName}]`
- }
+ // if (isCompanyLevel.value && form.reportToLevel) {
+ // const targetName = form.reportToLevel === 'Battalion' ? '营部' : '团部'
+ // remarks = remarks ? `[上报到${targetName}] ${remarks}` : `[上报到${targetName}]`
+ // }
// 累加到已有数量
await allocationsApi.updateDistribution(distribution.value.id, {
diff --git a/src/frontend/src/views/personnel/PersonnelList.vue b/src/frontend/src/views/personnel/PersonnelList.vue
index 6fb87e8..432f1e7 100644
--- a/src/frontend/src/views/personnel/PersonnelList.vue
+++ b/src/frontend/src/views/personnel/PersonnelList.vue
@@ -63,9 +63,12 @@
-
+
-
+
+ 待上级审批
+
+
{{ getStatusName(row.status) }}
@@ -91,16 +94,21 @@
-
+
-
+
+
+
+
+
+
@@ -270,21 +278,45 @@ function handleEdit(person: Personnel) {
}
function canUpgrade(person: Personnel): boolean {
- // 检查当前用户单位层级是否高于人员已审批的等级
- if (!authStore.user || !person.approvedLevel) return false
- // 师级人才不能再向上申报
+ // 向上申报按钮显示条件:
+ // 1. 人才已审批
+ // 2. 不是师级人才(师级不能再向上)
+ // 3. 没有待处理的向上申报请求
+ // 4. 当前用户是审批单位(可以发起向上申报)
+ if (!authStore.user || !person.approvedLevel || !person.approvedByUnitId) return false
if (person.approvedLevel === PersonnelLevel.Division) return false
- // 用户单位层级必须高于人员当前等级(数值越小层级越高)
- const userLevel = authStore.user.organizationalLevel
- const personnelLevel = person.approvedLevel
- // Division=1, Regiment=2, Battalion=3, Company=4
- const levelOrder: Record = {
+ if (person.pendingUpgradeByUnitId) return false // 已有待处理的向上申报
+
+ // 当前用户单位是审批单位,可以发起向上申报
+ return person.approvedByUnitId === authStore.user.organizationalUnitId
+}
+
+// 判断是否可以审批向上申报请求
+function canApproveUpgrade(person: Personnel): boolean {
+ if (!authStore.user || !person.pendingUpgradeByUnitId) return false
+ // 用户单位层级必须高于申报单位层级
+ const userLevelNum = authStore.organizationalLevelNum
+ // 申报单位层级 = 人员等级 + 1(因为审批单位比人员等级高1级)
+ const personnelLevelNum = {
'Division': 1,
'Regiment': 2,
'Battalion': 3,
'Company': 4
- }
- return levelOrder[userLevel] < levelOrder[personnelLevel]
+ }[person.approvedLevel || 'Company'] || 4
+ const upgradeByUnitLevel = personnelLevelNum - 1 // 申报单位层级
+
+ return userLevelNum < upgradeByUnitLevel
+}
+
+// 判断是否可以审批该人员
+// 条件:1. 不是本单位提交的 2. 用户层级高于提交单位层级
+function canApprovePersonnel(person: Personnel): boolean {
+ if (!authStore.user) return false
+ // 本单位提交的人才不能自己审批
+ if (person.submittedByUnitId === authStore.user.organizationalUnitId) return false
+ // 用户层级必须高于提交单位层级(这里简化处理,假设能看到的数据都是下级提交的)
+ // 实际权限检查由后端完成
+ return true
}
function handleApprove(person: Personnel) {
@@ -294,11 +326,57 @@ function handleApprove(person: Personnel) {
showApprovalDialog.value = true
}
-function handleUpgrade(person: Personnel) {
- // 向上申报使用相同的审批流程
- selectedPerson.value = person
- approvalForm.comments = ''
- showApprovalDialog.value = true
+// 发起向上申报请求
+async function handleRequestUpgrade(person: Personnel) {
+ try {
+ const levelName = getLevelName(person.approvedLevel!)
+ await ElMessageBox.confirm(
+ `确定要将 "${person.name}"(${levelName})向上申报吗?\n申报后需要上级单位审批通过才能升级等级。`,
+ '确认向上申报',
+ {
+ type: 'warning',
+ confirmButtonText: '确认申报',
+ cancelButtonText: '取消'
+ }
+ )
+
+ await personnelApi.requestUpgrade(person.id)
+ ElMessage.success('向上申报请求已提交,等待上级审批')
+ await loadPersonnel()
+ } catch (error: any) {
+ if (error !== 'cancel') {
+ ElMessage.error(error.response?.data?.message || '向上申报失败')
+ }
+ }
+}
+
+// 审批向上申报请求
+async function handleApproveUpgrade(person: Personnel) {
+ try {
+ const currentLevel = getLevelName(person.approvedLevel!)
+ // 计算升级后的等级
+ const levelOrder = ['Company', 'Battalion', 'Regiment', 'Division']
+ const currentIndex = levelOrder.indexOf(person.approvedLevel || 'Company')
+ const newLevel = currentIndex < levelOrder.length - 1 ? getLevelName(levelOrder[currentIndex + 1] as PersonnelLevel) : currentLevel
+
+ await ElMessageBox.confirm(
+ `确定要批准 "${person.name}" 的向上申报请求吗?\n批准后,该人才将从${currentLevel}升级为${newLevel}。`,
+ '确认审批向上申报',
+ {
+ type: 'warning',
+ confirmButtonText: '批准',
+ cancelButtonText: '取消'
+ }
+ )
+
+ await personnelApi.approveUpgrade(person.id)
+ ElMessage.success('向上申报已批准,人才等级已升级')
+ await loadPersonnel()
+ } catch (error: any) {
+ if (error !== 'cancel') {
+ ElMessage.error(error.response?.data?.message || '审批失败')
+ }
+ }
}
async function submitApproval(approved: boolean) {