改名字

This commit is contained in:
18631081161 2026-01-22 20:36:51 +08:00
parent d64ce88ec8
commit 8f1840d823
30 changed files with 113 additions and 113 deletions

View File

@ -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)
{

View File

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

View File

@ -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,

View File

@ -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>

View File

@ -459,7 +459,7 @@ public class ReportingServiceTests
}
/// <summary>
/// 测试获取详细上报记录 - 包含物资信息
/// 测试获取详细上报记录 - 包含弹种信息
/// </summary>
[Fact]
public async Task GetDetailedReportsAsync_IncludesMaterialInfo()

View File

@ -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());

View File

@ -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",

View File

@ -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 = "删除成功" });

View File

@ -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)

View File

@ -97,7 +97,7 @@ public class StatsController : BaseApiController
}
/// <summary>
/// 获取各团物资配额统计(饼状图数据)
/// 获取各团弹种配额统计(饼状图数据)
/// </summary>
[HttpGet("regiment-allocations")]
public async Task<IActionResult> GetRegimentAllocationsStats()

View File

@ -220,7 +220,7 @@ public class AuditInterceptor : SaveChangesInterceptor
{
var entityDisplayName = entityType switch
{
"MaterialAllocation" => "物资配额",
"MaterialAllocation" => "弹种配额",
"AllocationDistribution" => "配额分配",
"Personnel" => "人员",
"OrganizationalUnit" => "组织单位",

View File

@ -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
{

View File

@ -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
{

View File

@ -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!;

View File

@ -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;

View File

@ -1,7 +1,7 @@
namespace MilitaryTrainingManagement.Models.Entities;
/// <summary>
/// 物资类别
/// 弹种类别
/// </summary>
public class MaterialCategory
{

View File

@ -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("默认弹种类别已创建!");
}
// 如果没有组织单位,创建种子数据

View File

@ -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)

View File

@ -388,7 +388,7 @@ public class AuditService : IAuditService
{
return entityType switch
{
"MaterialAllocation" => "物资配额",
"MaterialAllocation" => "弹种配额",
"AllocationDistribution" => "配额分配",
"Personnel" => "人员",
"OrganizationalUnit" => "组织单位",

View File

@ -36,7 +36,7 @@ public class ReportingService : IReportingService
/// <summary>
/// 获取单位的分配记录
/// 需求3.1:显示类别、物资名称、单位、配额、实际完成和完成率
/// 需求3.1:显示类别、弹种名称、单位、配额、实际完成和完成率
/// </summary>
public async Task<IEnumerable<AllocationDistribution>> GetDistributionsByUnitAsync(int unitId)
{

View File

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

View File

@ -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(() => {

View File

@ -33,7 +33,7 @@ const routes: RouteRecordRaw[] = [
path: 'allocations',
name: 'Allocations',
component: () => import('@/views/allocations/AllocationList.vue'),
meta: { title: '物资配额' }
meta: { title: '弹种配额' }
},
{
path: 'allocations/categories',

View File

@ -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': '消耗删改申请',

View File

@ -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>

View File

@ -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' }]
}

View File

@ -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',

View File

@ -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="物资类别">

View File

@ -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="原上报数量">

View File

@ -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="配额">