改名字
This commit is contained in:
parent
d64ce88ec8
commit
8f1840d823
|
|
@ -13,7 +13,7 @@ public class AllocationQuotaPropertyTests
|
|||
{
|
||||
/// <summary>
|
||||
/// 属性2:配额总和验证
|
||||
/// *对于任何*带有单位配额的物资配额,所有单位配额的总和不应超过总配额指标
|
||||
/// *对于任何*带有单位配额的弹种配额,所有单位配额的总和不应超过总配额指标
|
||||
/// **验证需求:需求2.3**
|
||||
/// </summary>
|
||||
[Property(MaxTest = 100)]
|
||||
|
|
@ -167,7 +167,7 @@ public class AllocationQuotaPropertyTests
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建带有分配的物资配额
|
||||
/// 创建带有分配的弹种配额
|
||||
/// </summary>
|
||||
private static MaterialAllocation CreateAllocationWithDistributions(decimal totalQuota, decimal[] quotas)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ public class RequiredFieldValidationPropertyTests
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// 属性7扩展:物资配额必填字段验证
|
||||
/// *对于任何*物资配额创建,物资名称、单位和总配额必须存在且有效
|
||||
/// 属性7扩展:弹种配额必填字段验证
|
||||
/// *对于任何*弹种配额创建,弹种名称、单位和总配额必须存在且有效
|
||||
/// **验证需求:需求2.2**
|
||||
/// </summary>
|
||||
[Property(MaxTest = 100)]
|
||||
|
|
@ -163,7 +163,7 @@ public class RequiredFieldValidationPropertyTests
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 属性7扩展:缺少物资名称的配额应该无效
|
||||
/// 属性7扩展:缺少弹种名称的配额应该无效
|
||||
/// **验证需求:需求2.2**
|
||||
/// </summary>
|
||||
[Property(MaxTest = 100)]
|
||||
|
|
@ -175,14 +175,14 @@ public class RequiredFieldValidationPropertyTests
|
|||
var allocation = new MaterialAllocation
|
||||
{
|
||||
Category = TruncateString(category.Get, 100),
|
||||
MaterialName = "", // 缺少物资名称
|
||||
MaterialName = "", // 缺少弹种名称
|
||||
Unit = TruncateString(unit.Get, 50),
|
||||
TotalQuota = totalQuotaInt.Get,
|
||||
CreatedByUnitId = 1,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
// 缺少物资名称应该无效
|
||||
// 缺少弹种名称应该无效
|
||||
return string.IsNullOrWhiteSpace(allocation.MaterialName);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@ public class WorkflowStatePropertyTests
|
|||
var (hierarchy, users) = CreateHierarchyWithUsers(context);
|
||||
var workflowService = new WorkflowService(context);
|
||||
|
||||
// 创建物资配额
|
||||
// 创建弹种配额
|
||||
var allocation = new MaterialAllocation
|
||||
{
|
||||
Category = "弹药",
|
||||
MaterialName = "测试物资",
|
||||
MaterialName = "测试弹种",
|
||||
Unit = "发",
|
||||
TotalQuota = 1000,
|
||||
CreatedByUnitId = hierarchy[OrganizationalLevel.Division].Id,
|
||||
|
|
@ -170,11 +170,11 @@ public class WorkflowStatePropertyTests
|
|||
var (hierarchy, users) = CreateHierarchyWithUsers(context);
|
||||
var workflowService = new WorkflowService(context);
|
||||
|
||||
// 创建物资配额
|
||||
// 创建弹种配额
|
||||
var allocation = new MaterialAllocation
|
||||
{
|
||||
Category = "弹药",
|
||||
MaterialName = "测试物资",
|
||||
MaterialName = "测试弹种",
|
||||
Unit = "发",
|
||||
TotalQuota = 1000,
|
||||
CreatedByUnitId = hierarchy[OrganizationalLevel.Division].Id,
|
||||
|
|
@ -238,11 +238,11 @@ public class WorkflowStatePropertyTests
|
|||
var (hierarchy, users) = CreateHierarchyWithUsers(context);
|
||||
var workflowService = new WorkflowService(context);
|
||||
|
||||
// 创建物资配额
|
||||
// 创建弹种配额
|
||||
var allocation = new MaterialAllocation
|
||||
{
|
||||
Category = "弹药",
|
||||
MaterialName = "测试物资",
|
||||
MaterialName = "测试弹种",
|
||||
Unit = "发",
|
||||
TotalQuota = 1000,
|
||||
CreatedByUnitId = hierarchy[OrganizationalLevel.Division].Id,
|
||||
|
|
@ -314,11 +314,11 @@ public class WorkflowStatePropertyTests
|
|||
var (hierarchy, users) = CreateHierarchyWithUsers(context);
|
||||
var workflowService = new WorkflowService(context);
|
||||
|
||||
// 创建物资配额
|
||||
// 创建弹种配额
|
||||
var allocation = new MaterialAllocation
|
||||
{
|
||||
Category = "弹药",
|
||||
MaterialName = "测试物资",
|
||||
MaterialName = "测试弹种",
|
||||
Unit = "发",
|
||||
TotalQuota = 1000,
|
||||
CreatedByUnitId = hierarchy[OrganizationalLevel.Division].Id,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using MilitaryTrainingManagement.Services.Implementations;
|
|||
namespace MilitaryTrainingManagement.Tests.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 物资配额服务单元测试
|
||||
/// 弹种配额服务单元测试
|
||||
/// 测试配额创建、验证逻辑、分发算法和错误处理场景
|
||||
/// _需求:2.1, 2.2, 2.3, 2.4, 2.5_
|
||||
/// </summary>
|
||||
|
|
@ -136,7 +136,7 @@ public class AllocationServiceTests
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试创建配额时必填字段验证 - 空物资名称
|
||||
/// 测试创建配额时必填字段验证 - 空弹种名称
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAsync_WithEmptyMaterialName_ThrowsArgumentException()
|
||||
|
|
@ -154,7 +154,7 @@ public class AllocationServiceTests
|
|||
var exception = await Assert.ThrowsAsync<ArgumentException>(() =>
|
||||
service.CreateAsync("弹药", "", "件", 100m, division.Id, new Dictionary<int, decimal>()));
|
||||
|
||||
Assert.Equal("物资名称不能为空", exception.Message);
|
||||
Assert.Equal("弹种名称不能为空", exception.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ public class ReportingServiceTests
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取详细上报记录 - 包含物资信息
|
||||
/// 测试获取详细上报记录 - 包含弹种信息
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task GetDetailedReportsAsync_IncludesMaterialInfo()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using MilitaryTrainingManagement.Services.Interfaces;
|
|||
namespace MilitaryTrainingManagement.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 物资配额控制器
|
||||
/// 弹种配额控制器
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
public class AllocationsController : BaseApiController
|
||||
|
|
@ -33,7 +33,7 @@ public class AllocationsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前用户可见的所有物资配额
|
||||
/// 获取当前用户可见的所有弹种配额
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetAll(
|
||||
|
|
@ -94,7 +94,7 @@ public class AllocationsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前单位创建的物资配额
|
||||
/// 获取当前单位创建的弹种配额
|
||||
/// </summary>
|
||||
[HttpGet("my")]
|
||||
public async Task<IActionResult> GetMyAllocations()
|
||||
|
|
@ -124,7 +124,7 @@ public class AllocationsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID获取物资配额
|
||||
/// 根据ID获取弹种配额
|
||||
/// 需求1.1, 1.2, 1.3:营部及以下级别用户只能查看本单位及直接下级的配额
|
||||
/// </summary>
|
||||
[HttpGet("{id}")]
|
||||
|
|
@ -200,9 +200,9 @@ public class AllocationsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建物资配额
|
||||
/// 需求2.1:师团管理员可以创建物资类别
|
||||
/// 需求2.2:创建配额需要物资名称、单位、总配额和目标单位
|
||||
/// 创建弹种配额
|
||||
/// 需求2.1:师团管理员可以创建弹种类别
|
||||
/// 需求2.2:创建配额需要弹种名称、单位、总配额和目标单位
|
||||
/// 需求2.4:创建后自动分发给目标单位
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
|
|
@ -233,7 +233,7 @@ public class AllocationsController : BaseApiController
|
|||
"MaterialAllocation",
|
||||
allocation.Id,
|
||||
"Create",
|
||||
$"创建物资配额:{request.Category} - {request.MaterialName},总配额:{request.TotalQuota}{request.Unit}",
|
||||
$"创建弹种配额:{request.Category} - {request.MaterialName},总配额:{request.TotalQuota}{request.Unit}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
@ -247,7 +247,7 @@ public class AllocationsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新物资配额基本信息
|
||||
/// 更新弹种配额基本信息
|
||||
/// </summary>
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Policy = "DivisionLevel")]
|
||||
|
|
@ -285,7 +285,7 @@ public class AllocationsController : BaseApiController
|
|||
"MaterialAllocation",
|
||||
id,
|
||||
"Update",
|
||||
$"更新物资配额:{request.Category} - {request.MaterialName},总配额:{request.TotalQuota}{request.Unit}",
|
||||
$"更新弹种配额:{request.Category} - {request.MaterialName},总配额:{request.TotalQuota}{request.Unit}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
@ -387,7 +387,7 @@ public class AllocationsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除物资配额
|
||||
/// 删除弹种配额
|
||||
/// </summary>
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Policy = "DivisionLevel")]
|
||||
|
|
@ -419,7 +419,7 @@ public class AllocationsController : BaseApiController
|
|||
"MaterialAllocation",
|
||||
id,
|
||||
"Delete",
|
||||
$"删除物资配额:{category} - {materialName}",
|
||||
$"删除弹种配额:{category} - {materialName}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ public class ConsumptionChangeRequestsController : BaseApiController
|
|||
|
||||
// 记录审计日志
|
||||
var requestTypeName = request.RequestType == ChangeRequestType.Delete ? "删除" : "修改";
|
||||
var materialName = report.AllocationDistribution?.Allocation?.MaterialName ?? "未知物资";
|
||||
var materialName = report.AllocationDistribution?.Allocation?.MaterialName ?? "未知弹种";
|
||||
|
||||
await _auditService.LogApprovalAsync(
|
||||
"ConsumptionReportChangeRequest",
|
||||
changeRequest.Id,
|
||||
"Create",
|
||||
$"提交消耗记录{requestTypeName}申请,物资:{materialName},申请原因:{request.Reason}",
|
||||
$"提交消耗记录{requestTypeName}申请,弹种:{materialName},申请原因:{request.Reason}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
@ -289,14 +289,14 @@ public class ConsumptionChangeRequestsController : BaseApiController
|
|||
|
||||
// 记录审计日志
|
||||
var requestTypeName = changeRequest.RequestType == ChangeRequestType.Delete ? "删除" : "修改";
|
||||
var materialName = changeRequest.ConsumptionReport?.AllocationDistribution?.Allocation?.MaterialName ?? "未知物资";
|
||||
var materialName = changeRequest.ConsumptionReport?.AllocationDistribution?.Allocation?.MaterialName ?? "未知弹种";
|
||||
var reportedByUnitName = changeRequest.RequestedByUnit?.Name ?? "未知单位";
|
||||
|
||||
await _auditService.LogApprovalAsync(
|
||||
"ConsumptionReportChangeRequest",
|
||||
id,
|
||||
request.Approved ? "Approve" : "Reject",
|
||||
$"{action}「{reportedByUnitName}」的消耗记录{requestTypeName}申请,物资:{materialName},原因:{changeRequest.Reason},处理意见:{request.Comments ?? "无"}",
|
||||
$"{action}「{reportedByUnitName}」的消耗记录{requestTypeName}申请,弹种:{materialName},原因:{changeRequest.Reason},处理意见:{request.Comments ?? "无"}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
@ -351,7 +351,7 @@ public class ConsumptionChangeRequestsController : BaseApiController
|
|||
|
||||
// 记录审计日志
|
||||
var userId = GetCurrentUserId();
|
||||
var materialName = distribution.Allocation?.MaterialName ?? "未知物资";
|
||||
var materialName = distribution.Allocation?.MaterialName ?? "未知弹种";
|
||||
|
||||
await _auditService.LogApprovalAsync(
|
||||
"ConsumptionReport",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using MilitaryTrainingManagement.Services.Interfaces;
|
|||
namespace MilitaryTrainingManagement.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 物资类别管理控制器
|
||||
/// 弹种类别管理控制器
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
public class MaterialCategoriesController : BaseApiController
|
||||
|
|
@ -29,7 +29,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有物资类别
|
||||
/// 获取所有弹种类别
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetAll([FromQuery] bool? activeOnly = true)
|
||||
|
|
@ -50,7 +50,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID获取物资类别
|
||||
/// 根据ID获取弹种类别
|
||||
/// </summary>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
|
|
@ -58,13 +58,13 @@ public class MaterialCategoriesController : BaseApiController
|
|||
var category = await _context.MaterialCategories.FindAsync(id);
|
||||
if (category == null)
|
||||
{
|
||||
return NotFound(new { message = "物资类别不存在" });
|
||||
return NotFound(new { message = "弹种类别不存在" });
|
||||
}
|
||||
return Ok(category);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建物资类别
|
||||
/// 创建弹种类别
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create([FromBody] CreateMaterialCategoryRequest request)
|
||||
|
|
@ -77,7 +77,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
.AnyAsync(c => c.Name == request.Name);
|
||||
if (exists)
|
||||
{
|
||||
return BadRequest(new { message = "物资类别名称已存在" });
|
||||
return BadRequest(new { message = "弹种类别名称已存在" });
|
||||
}
|
||||
|
||||
var category = new MaterialCategory
|
||||
|
|
@ -97,7 +97,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
"MaterialCategory",
|
||||
category.Id,
|
||||
"Create",
|
||||
$"创建物资类别:{request.Name}",
|
||||
$"创建弹种类别:{request.Name}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
@ -106,7 +106,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新物资类别
|
||||
/// 更新弹种类别
|
||||
/// </summary>
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> Update(int id, [FromBody] UpdateMaterialCategoryRequest request)
|
||||
|
|
@ -117,7 +117,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
var category = await _context.MaterialCategories.FindAsync(id);
|
||||
if (category == null)
|
||||
{
|
||||
return NotFound(new { message = "物资类别不存在" });
|
||||
return NotFound(new { message = "弹种类别不存在" });
|
||||
}
|
||||
|
||||
// 检查名称是否与其他类别重复
|
||||
|
|
@ -125,7 +125,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
.AnyAsync(c => c.Name == request.Name && c.Id != id);
|
||||
if (exists)
|
||||
{
|
||||
return BadRequest(new { message = "物资类别名称已存在" });
|
||||
return BadRequest(new { message = "弹种类别名称已存在" });
|
||||
}
|
||||
|
||||
category.Name = request.Name;
|
||||
|
|
@ -140,7 +140,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
"MaterialCategory",
|
||||
id,
|
||||
"Update",
|
||||
$"更新物资类别:{request.Name}",
|
||||
$"更新弹种类别:{request.Name}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress());
|
||||
|
|
@ -149,7 +149,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除物资类别
|
||||
/// 删除弹种类别
|
||||
/// </summary>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
|
|
@ -160,7 +160,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
var category = await _context.MaterialCategories.FindAsync(id);
|
||||
if (category == null)
|
||||
{
|
||||
return NotFound(new { message = "物资类别不存在" });
|
||||
return NotFound(new { message = "弹种类别不存在" });
|
||||
}
|
||||
|
||||
// 检查是否有配额使用此类别
|
||||
|
|
@ -180,7 +180,7 @@ public class MaterialCategoriesController : BaseApiController
|
|||
"MaterialCategory",
|
||||
id,
|
||||
"Delete",
|
||||
$"删除物资类别:{categoryName}",
|
||||
$"删除弹种类别:{categoryName}",
|
||||
userId,
|
||||
unitId,
|
||||
GetClientIpAddress()); return Ok(new { message = "删除成功" });
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class ReportsController : BaseApiController
|
|||
|
||||
/// <summary>
|
||||
/// 获取当前单位的分配记录
|
||||
/// 需求3.1:显示类别、物资名称、单位、配额、实际完成和完成率
|
||||
/// 需求3.1:显示类别、弹种名称、单位、配额、实际完成和完成率
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetByUnit([FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 10)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public class StatsController : BaseApiController
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取各团物资配额统计(饼状图数据)
|
||||
/// 获取各团弹种配额统计(饼状图数据)
|
||||
/// </summary>
|
||||
[HttpGet("regiment-allocations")]
|
||||
public async Task<IActionResult> GetRegimentAllocationsStats()
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ public class AuditInterceptor : SaveChangesInterceptor
|
|||
{
|
||||
var entityDisplayName = entityType switch
|
||||
{
|
||||
"MaterialAllocation" => "物资配额",
|
||||
"MaterialAllocation" => "弹种配额",
|
||||
"AllocationDistribution" => "配额分配",
|
||||
"Personnel" => "人员",
|
||||
"OrganizationalUnit" => "组织单位",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class DistributionRequestItem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建物资配额请求
|
||||
/// 创建弹种配额请求
|
||||
/// </summary>
|
||||
public class CreateAllocationRequest
|
||||
{
|
||||
|
|
@ -24,10 +24,10 @@ public class CreateAllocationRequest
|
|||
public string Category { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 物资名称
|
||||
/// 弹种名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "物资名称为必填项")]
|
||||
[MaxLength(200, ErrorMessage = "物资名称长度不能超过200个字符")]
|
||||
[Required(ErrorMessage = "弹种名称为必填项")]
|
||||
[MaxLength(200, ErrorMessage = "弹种名称长度不能超过200个字符")]
|
||||
public string MaterialName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -60,7 +60,7 @@ public class CreateAllocationRequest
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新物资配额请求
|
||||
/// 更新弹种配额请求
|
||||
/// </summary>
|
||||
public class UpdateAllocationRequest
|
||||
{
|
||||
|
|
@ -72,10 +72,10 @@ public class UpdateAllocationRequest
|
|||
public string Category { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 物资名称
|
||||
/// 弹种名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "物资名称为必填项")]
|
||||
[MaxLength(200, ErrorMessage = "物资名称长度不能超过200个字符")]
|
||||
[Required(ErrorMessage = "弹种名称为必填项")]
|
||||
[MaxLength(200, ErrorMessage = "弹种名称长度不能超过200个字符")]
|
||||
public string MaterialName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -112,7 +112,7 @@ public class UpdateDistributionRequest
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 物资配额响应
|
||||
/// 弹种配额响应
|
||||
/// </summary>
|
||||
public class AllocationResponse
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations;
|
|||
namespace MilitaryTrainingManagement.Models.DTOs;
|
||||
|
||||
/// <summary>
|
||||
/// 创建物资类别请求
|
||||
/// 创建弹种类别请求
|
||||
/// </summary>
|
||||
public class CreateMaterialCategoryRequest
|
||||
{
|
||||
|
|
@ -18,7 +18,7 @@ public class CreateMaterialCategoryRequest
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新物资类别请求
|
||||
/// 更新弹种类别请求
|
||||
/// </summary>
|
||||
public class UpdateMaterialCategoryRequest
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ public class AllocationDistribution
|
|||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的物资配额ID
|
||||
/// 关联的弹种配额ID
|
||||
/// </summary>
|
||||
public int AllocationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的物资配额
|
||||
/// 关联的弹种配额
|
||||
/// </summary>
|
||||
public MaterialAllocation Allocation { get; set; } = null!;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations;
|
|||
namespace MilitaryTrainingManagement.Models.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 物资配额实体
|
||||
/// 弹种配额实体
|
||||
/// </summary>
|
||||
public class MaterialAllocation
|
||||
{
|
||||
|
|
@ -19,7 +19,7 @@ public class MaterialAllocation
|
|||
/// <summary>
|
||||
/// 弹药/器材名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "物资名称为必填项")]
|
||||
[Required(ErrorMessage = "弹种名称为必填项")]
|
||||
[MaxLength(200)]
|
||||
public string MaterialName { get; set; } = string.Empty;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
namespace MilitaryTrainingManagement.Models.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 物资类别
|
||||
/// 弹种类别
|
||||
/// </summary>
|
||||
public class MaterialCategory
|
||||
{
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ builder.Services.AddControllers()
|
|||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "兵团训练物资管控系统 API", Version = "v1" });
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "兵团训练弹药管控系统 API", Version = "v1" });
|
||||
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT Authorization header using the Bearer scheme",
|
||||
|
|
@ -349,7 +349,7 @@ using (var scope = app.Services.CreateScope())
|
|||
Console.WriteLine($"创建 ConsumptionReportChangeRequests 表时出错: {ex.Message}");
|
||||
}
|
||||
|
||||
// 如果没有物资类别,创建默认类别
|
||||
// 如果没有弹种类别,创建默认类别
|
||||
if (!context.MaterialCategories.Any())
|
||||
{
|
||||
var categories = new[]
|
||||
|
|
@ -372,8 +372,8 @@ using (var scope = app.Services.CreateScope())
|
|||
},
|
||||
new MilitaryTrainingManagement.Models.Entities.MaterialCategory
|
||||
{
|
||||
Name = "物资",
|
||||
Description = "训练保障物资",
|
||||
Name = "其他",
|
||||
Description = "其他训练弹种",
|
||||
IsActive = true,
|
||||
SortOrder = 3,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
|
|
@ -389,7 +389,7 @@ using (var scope = app.Services.CreateScope())
|
|||
};
|
||||
context.MaterialCategories.AddRange(categories);
|
||||
await context.SaveChangesAsync();
|
||||
Console.WriteLine("默认物资类别已创建!");
|
||||
Console.WriteLine("默认弹种类别已创建!");
|
||||
}
|
||||
|
||||
// 如果没有组织单位,创建种子数据
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using MilitaryTrainingManagement.Services.Interfaces;
|
|||
namespace MilitaryTrainingManagement.Services.Implementations;
|
||||
|
||||
/// <summary>
|
||||
/// 物资配额服务实现
|
||||
/// 弹种配额服务实现
|
||||
/// </summary>
|
||||
public class AllocationService : IAllocationService
|
||||
{
|
||||
|
|
@ -139,7 +139,7 @@ public class AllocationService : IAllocationService
|
|||
if (string.IsNullOrWhiteSpace(category))
|
||||
throw new ArgumentException("类别不能为空");
|
||||
if (string.IsNullOrWhiteSpace(materialName))
|
||||
throw new ArgumentException("物资名称不能为空");
|
||||
throw new ArgumentException("弹种名称不能为空");
|
||||
if (string.IsNullOrWhiteSpace(unit))
|
||||
throw new ArgumentException("计量单位不能为空");
|
||||
if (totalQuota <= 0)
|
||||
|
|
@ -156,7 +156,7 @@ public class AllocationService : IAllocationService
|
|||
if (!await ValidateTargetUnitsExistAsync(distributions.Keys))
|
||||
throw new ArgumentException("目标单位不存在");
|
||||
|
||||
// 创建物资配额
|
||||
// 创建弹种配额
|
||||
var allocation = new MaterialAllocation
|
||||
{
|
||||
Category = category,
|
||||
|
|
@ -205,7 +205,7 @@ public class AllocationService : IAllocationService
|
|||
if (string.IsNullOrWhiteSpace(category))
|
||||
throw new ArgumentException("类别不能为空");
|
||||
if (string.IsNullOrWhiteSpace(materialName))
|
||||
throw new ArgumentException("物资名称不能为空");
|
||||
throw new ArgumentException("弹种名称不能为空");
|
||||
if (string.IsNullOrWhiteSpace(unit))
|
||||
throw new ArgumentException("计量单位不能为空");
|
||||
if (totalQuota <= 0)
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ public class AuditService : IAuditService
|
|||
{
|
||||
return entityType switch
|
||||
{
|
||||
"MaterialAllocation" => "物资配额",
|
||||
"MaterialAllocation" => "弹种配额",
|
||||
"AllocationDistribution" => "配额分配",
|
||||
"Personnel" => "人员",
|
||||
"OrganizationalUnit" => "组织单位",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class ReportingService : IReportingService
|
|||
|
||||
/// <summary>
|
||||
/// 获取单位的分配记录
|
||||
/// 需求3.1:显示类别、物资名称、单位、配额、实际完成和完成率
|
||||
/// 需求3.1:显示类别、弹种名称、单位、配额、实际完成和完成率
|
||||
/// </summary>
|
||||
public async Task<IEnumerable<AllocationDistribution>> GetDistributionsByUnitAsync(int unitId)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,27 +4,27 @@ using MilitaryTrainingManagement.Models.Enums;
|
|||
namespace MilitaryTrainingManagement.Services.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// 物资配额服务接口
|
||||
/// 弹种配额服务接口
|
||||
/// </summary>
|
||||
public interface IAllocationService
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据ID获取物资配额
|
||||
/// 根据ID获取弹种配额
|
||||
/// </summary>
|
||||
Task<MaterialAllocation?> GetByIdAsync(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有物资配额
|
||||
/// 获取所有弹种配额
|
||||
/// </summary>
|
||||
Task<IEnumerable<MaterialAllocation>> GetAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定单位创建的物资配额
|
||||
/// 获取指定单位创建的弹种配额
|
||||
/// </summary>
|
||||
Task<IEnumerable<MaterialAllocation>> GetByUnitAsync(int unitId);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定单位可见的物资配额(包括分配给该单位及其下级单位的配额)
|
||||
/// 获取指定单位可见的弹种配额(包括分配给该单位及其下级单位的配额)
|
||||
/// </summary>
|
||||
Task<IEnumerable<MaterialAllocation>> GetVisibleToUnitAsync(int unitId);
|
||||
|
||||
|
|
@ -39,12 +39,12 @@ public interface IAllocationService
|
|||
Task<AllocationDistribution?> GetDistributionByIdAsync(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 创建物资配额并自动分发给目标单位
|
||||
/// 创建弹种配额并自动分发给目标单位
|
||||
/// </summary>
|
||||
Task<MaterialAllocation> CreateAsync(string category, string materialName, string unit, decimal totalQuota, int createdByUnitId, Dictionary<int, decimal> distributions);
|
||||
|
||||
/// <summary>
|
||||
/// 更新物资配额基本信息
|
||||
/// 更新弹种配额基本信息
|
||||
/// </summary>
|
||||
Task<MaterialAllocation> UpdateAsync(int id, string category, string materialName, string unit, decimal totalQuota);
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ public interface IAllocationService
|
|||
Task<AllocationDistribution> UpdateDistributionCompletionAsync(int distributionId, int unitId, int userId, decimal actualCompletion, string? remarks = null);
|
||||
|
||||
/// <summary>
|
||||
/// 删除物资配额
|
||||
/// 删除弹种配额
|
||||
/// </summary>
|
||||
Task DeleteAsync(int id);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
<el-sub-menu v-if="canViewAllocations" index="allocations">
|
||||
<template #title>
|
||||
<el-icon><Box /></el-icon>
|
||||
<span>物资配额</span>
|
||||
<span>弹种配额</span>
|
||||
</template>
|
||||
<el-menu-item index="/allocations">配额列表</el-menu-item>
|
||||
<el-menu-item v-if="authStore.canCreateAllocations" index="/allocations/create">创建配额</el-menu-item>
|
||||
|
|
@ -104,7 +104,7 @@ const authStore = useAuthStore()
|
|||
const activeMenu = computed(() => route.path)
|
||||
const currentRoute = computed(() => route)
|
||||
|
||||
// 只有师本部和团本部可以查看物资配额(营、连级隐藏)
|
||||
// 只有师本部和团本部可以查看弹种配额(营、连级隐藏)
|
||||
const canViewAllocations = computed(() => authStore.organizationalLevelNum <= 2)
|
||||
|
||||
const levelName = computed(() => {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const routes: RouteRecordRaw[] = [
|
|||
path: 'allocations',
|
||||
name: 'Allocations',
|
||||
component: () => import('@/views/allocations/AllocationList.vue'),
|
||||
meta: { title: '物资配额' }
|
||||
meta: { title: '弹种配额' }
|
||||
},
|
||||
{
|
||||
path: 'allocations/categories',
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="数据类型">
|
||||
<el-select v-model="filters.entityType" placeholder="全部" clearable style="width: 180px">
|
||||
<el-option label="物资配额" value="MaterialAllocation" />
|
||||
<el-option label="弹种配额" value="MaterialAllocation" />
|
||||
<el-option label="配额分配" value="AllocationDistribution" />
|
||||
<el-option label="消耗记录" value="ConsumptionReport" />
|
||||
<el-option label="消耗删改申请" value="ConsumptionReportChangeRequest" />
|
||||
|
|
@ -228,7 +228,7 @@ function getActionTagType(action: string): string {
|
|||
|
||||
function getEntityTypeName(entityType: string): string {
|
||||
const nameMap: Record<string, string> = {
|
||||
'MaterialAllocation': '物资配额',
|
||||
'MaterialAllocation': '弹种配额',
|
||||
'AllocationDistribution': '配额分配',
|
||||
'ConsumptionReport': '消耗记录',
|
||||
'ConsumptionReportChangeRequest': '消耗删改申请',
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<div class="dashboard">
|
||||
<el-row :gutter="20">
|
||||
<!-- 师团级和团级显示物资配额 -->
|
||||
<!-- 师本部和团本部显示弹种配额 -->
|
||||
<el-col v-if="authStore.organizationalLevelNum <= 2" :span="6">
|
||||
<el-card class="stat-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon :size="24" color="#409EFF"><Box /></el-icon>
|
||||
<span>物资配额</span>
|
||||
<span>弹种配额</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="stat-value">{{ stats.allocations }}</div>
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="暂无团级物资配额数据" />
|
||||
<el-empty v-else description="暂无团级弹种配额数据" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="物资名称" prop="materialName">
|
||||
<el-input v-model="form.materialName" placeholder="请输入物资名称" />
|
||||
<el-form-item label="弹种名称" prop="materialName">
|
||||
<el-input v-model="form.materialName" placeholder="请输入弹种名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="计量单位" prop="unit">
|
||||
<el-input v-model="form.unit" placeholder="请输入计量单位" />
|
||||
|
|
@ -97,7 +97,7 @@ const form = reactive({
|
|||
|
||||
const rules: FormRules = {
|
||||
category: [{ required: true, message: '请输入物资类别', trigger: 'blur' }],
|
||||
materialName: [{ required: true, message: '请输入物资名称', trigger: 'blur' }],
|
||||
materialName: [{ required: true, message: '请输入弹种名称', trigger: 'blur' }],
|
||||
unit: [{ required: true, message: '请输入计量单位', trigger: 'blur' }],
|
||||
totalQuota: [{ required: true, message: '请输入总配额', trigger: 'blur' }]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
<div class="card-header">
|
||||
<div class="header-title">
|
||||
<el-icon class="title-icon" :size="22"><Box /></el-icon>
|
||||
<span>物资配额管理</span>
|
||||
<span>弹种配额管理</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="搜索物资名称"
|
||||
placeholder="搜索弹种名称"
|
||||
clearable
|
||||
style="width: 180px; margin-right: 12px"
|
||||
@clear="handleSearch"
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
<el-select v-model="categoryFilter" placeholder="类别筛选" clearable style="width: 120px; margin-right: 12px">
|
||||
<el-option label="弹药" value="弹药" />
|
||||
<el-option label="装备" value="装备" />
|
||||
<el-option label="物资" value="物资" />
|
||||
<el-option label="其他" value="其他" />
|
||||
<el-option label="器材" value="器材" />
|
||||
</el-select>
|
||||
<el-button v-if="authStore.canCreateAllocations" @click="$router.push('/allocations/categories')">
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="materialName" label="物资名称" min-width="150">
|
||||
<el-table-column prop="materialName" label="弹种名称" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<span class="material-name">{{ row.materialName }}</span>
|
||||
</template>
|
||||
|
|
@ -164,7 +164,7 @@
|
|||
<el-row :gutter="24">
|
||||
<el-col :span="6">
|
||||
<div class="summary-item">
|
||||
<div class="summary-label">物资类别</div>
|
||||
<div class="summary-label">弹种类别</div>
|
||||
<div class="summary-value">
|
||||
<el-tag :type="getCategoryTagType(selectedAllocation?.category || '')" size="large" effect="plain">
|
||||
{{ selectedAllocation?.category }}
|
||||
|
|
@ -230,7 +230,7 @@
|
|||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
<!-- 营部及以下只显示物资类别和总消耗,并增加上报消耗按钮 -->
|
||||
<!-- 营部及以下只显示弹种类别和总消耗,并增加上报消耗按钮 -->
|
||||
<template v-else>
|
||||
<el-col :span="8">
|
||||
<div class="summary-item">
|
||||
|
|
@ -645,7 +645,7 @@ function getCategoryTagType(category: string): string {
|
|||
switch (category) {
|
||||
case '弹药': return 'danger'
|
||||
case '装备': return 'warning'
|
||||
case '物资': return 'success'
|
||||
case '其他': return 'success'
|
||||
case '器材': return 'info'
|
||||
default: return 'info'
|
||||
}
|
||||
|
|
@ -1091,7 +1091,7 @@ function handleEdit(allocation: MaterialAllocation) {
|
|||
async function handleDelete(allocation: MaterialAllocation) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除物资配额 "${allocation.materialName}" 吗?此操作不可恢复。`,
|
||||
`确定要删除弹种配额 "${allocation.materialName}" 吗?此操作不可恢复。`,
|
||||
'确认删除',
|
||||
{
|
||||
type: 'warning',
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
<div class="info-section">
|
||||
<h3 class="section-title">配额信息</h3>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="物资名称">
|
||||
<el-descriptions-item label="弹种名称">
|
||||
<span class="material-name">{{ allocation?.materialName }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="物资类别">
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物资名称" width="120">
|
||||
<el-table-column label="弹种名称" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.consumptionReport?.materialName || '-' }}
|
||||
</template>
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物资名称" width="120">
|
||||
<el-table-column label="弹种名称" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.consumptionReport?.materialName || '-' }}
|
||||
</template>
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
<el-dialog v-model="modifyDialogVisible" title="修改消耗记录" width="500px">
|
||||
<div v-if="selectedRequest?.consumptionReport" class="modify-info">
|
||||
<el-descriptions :column="1" border size="small">
|
||||
<el-descriptions-item label="物资名称">
|
||||
<el-descriptions-item label="弹种名称">
|
||||
{{ selectedRequest.consumptionReport.materialName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="原上报数量">
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="materialName" label="物资名称" min-width="150">
|
||||
<el-table-column prop="materialName" label="弹种名称" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<span class="material-name">{{ row.materialName }}</span>
|
||||
</template>
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
{{ selectedReport?.category }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="物资名称">
|
||||
<el-form-item label="弹种名称">
|
||||
<span class="dialog-value">{{ selectedReport?.materialName }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="配额">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user