15 KiB
设计文档
概述
兵团训练物资管控系统是一个基于分层架构的Web管理平台,采用.NET 8后端、Vue3+ElementPlus前端和SQL Server数据库构建。系统实现了四级组织结构(师团→团→营→连),具备基于角色的访问控制、自动数据分发和审批工作流功能。
系统架构遵循自上而下分配和自下而上上报的模式,上级组织单位创建和分发资源配额,下级单位上报实际完成数据,数据通过组织层级向上流动。
架构设计
系统架构
graph TB
subgraph "前端层"
UI[Vue3 + ElementPlus 界面]
Auth[认证模块]
Router[Vue路由]
end
subgraph "后端层"
API[ASP.NET Core Web API]
Auth_BE[认证服务]
Alloc[配额分配服务]
Personnel[人员管理服务]
Approval[审批工作流服务]
end
subgraph "数据层"
DB[(SQL Server 数据库)]
Audit[审计日志表]
end
UI --> API
Auth --> Auth_BE
API --> DB
API --> Audit
组织层级模型
graph TD
Division[师团] --> Regiment1[团1]
Division --> Regiment2[团N]
Regiment1 --> Battalion1[营1]
Regiment1 --> Battalion2[营2]
Battalion1 --> Company1[连1]
Battalion1 --> Company2[连2]
数据流架构
sequenceDiagram
participant D as 师团
participant R as 团
participant B as 营
participant C as 连
Note over D,C: 配额分配 (自上而下)
D->>R: 创建并分发配额
R->>B: 转发配额
B->>C: 分发给连队
Note over D,C: 上报流程 (自下而上)
C->>B: 提交实际完成情况
B->>R: 汇总并上报
R->>D: 最终上报
组件和接口
核心组件
1. 认证与授权模块
- 目的: 管理用户认证和基于角色的访问控制
- 核心类:
AuthenticationService,AuthorizationHandler,OrganizationalRole - 职责:
- 用户登录/登出
- 基于角色的权限执行
- 组织层级验证
2. 组织管理模块
- 目的: 管理四级组织结构
- 核心类:
OrganizationService,OrganizationalUnit,HierarchyValidator - 职责:
- 组织单位创建和管理
- 层级关系维护
- 基于组织结构的账户生成
3. 物资配额模块
- 目的: 处理训练物资配额和分发
- 核心类:
AllocationService,MaterialAllocation,AllocationDistributor - 职责:
- 物资类别管理
- 配额创建和验证
- 自动分发给下级单位
4. 上报模块
- 目的: 管理实际完成情况上报和数据汇总
- 核心类:
ReportingService,CompletionReport,DataAggregator - 职责:
- 完成情况数据提交
- 自动完成率计算
- 跨组织层级数据汇总
5. 人员管理模块
- 目的: 处理人员信息和审批工作流
- 核心类:
PersonnelService,Personnel,ApprovalWorkflow - 职责:
- 人员数据提交和存储
- 照片和文档管理
- 基于审批层级的人员等级分配
6. 审批工作流模块
- 目的: 管理修改和人员的审批流程
- 核心类:
WorkflowService,ApprovalRequest,WorkflowState - 职责:
- 修改请求路由
- 审批/拒绝处理
- 审计跟踪维护
API接口设计
认证端点
POST /api/admin/auth/login
POST /api/admin/auth/logout
GET /api/admin/auth/profile
组织管理
GET /api/admin/organizations
POST /api/admin/organizations
GET /api/admin/organizations/{id}/subordinates
POST /api/admin/organizations/{id}/accounts
物资配额
GET /api/admin/allocations
POST /api/admin/allocations
PUT /api/admin/allocations/{id}
DELETE /api/admin/allocations/{id}
GET /api/admin/allocations/{id}/distribution
上报管理
GET /api/admin/reports
POST /api/admin/reports
PUT /api/admin/reports/{id}
GET /api/admin/reports/aggregated
人员管理
GET /api/admin/personnel
POST /api/admin/personnel
PUT /api/admin/personnel/{id}
POST /api/admin/personnel/{id}/approve
POST /api/admin/personnel/{id}/reject
数据模型
核心实体
组织单位 (OrganizationalUnit)
public class OrganizationalUnit
{
public int Id { get; set; }
public string Name { get; set; }
public OrganizationalLevel Level { get; set; }
public int? ParentId { get; set; }
public OrganizationalUnit Parent { get; set; }
public List<OrganizationalUnit> Children { get; set; }
public List<UserAccount> Accounts { get; set; }
public DateTime CreatedAt { get; set; }
}
public enum OrganizationalLevel
{
Division = 1, // 师团
Regiment = 2, // 团
Battalion = 3, // 营
Company = 4 // 连
}
物资配额 (MaterialAllocation)
public class MaterialAllocation
{
public int Id { get; set; }
public string Category { get; set; } // 类别
public string MaterialName { get; set; } // 弹药/器材名称
public string Unit { get; set; } // 计量单位
public decimal TotalQuota { get; set; } // 总训练指标
public int CreatedByUnitId { get; set; }
public OrganizationalUnit CreatedByUnit { get; set; }
public List<AllocationDistribution> Distributions { get; set; }
public DateTime CreatedAt { get; set; }
}
配额分配 (AllocationDistribution)
public class AllocationDistribution
{
public int Id { get; set; }
public int AllocationId { get; set; }
public MaterialAllocation Allocation { get; set; }
public int TargetUnitId { get; set; }
public OrganizationalUnit TargetUnit { get; set; }
public decimal UnitQuota { get; set; } // 单位指标
public decimal? ActualCompletion { get; set; } // 单位完成
public decimal CompletionRate => ActualCompletion.HasValue ? ActualCompletion.Value / UnitQuota : 0; // 完成率
public DateTime? ReportedAt { get; set; }
public int? ReportedByUserId { get; set; }
}
人员 (Personnel)
public class Personnel
{
public int Id { get; set; }
public string Name { get; set; } // 姓名
public string PhotoPath { get; set; } // 照片路径
public string Position { get; set; } // 职位
public string Rank { get; set; } // 军衔
public string Gender { get; set; } // 性别
public string IdNumber { get; set; } // 身份证号
public string ProfessionalTitle { get; set; } // 专业职位
public string EducationLevel { get; set; } // 文化程度
public int Age { get; set; } // 年龄
public decimal Height { get; set; } // 身高
public string ContactInfo { get; set; } // 联系方式
public string Hometown { get; set; } // 籍贯
public string TrainingParticipation { get; set; } // 参加培训情况
public string Achievements { get; set; } // 取得成绩
public string SupportingDocuments { get; set; } // 佐证材料
public int SubmittedByUnitId { get; set; }
public OrganizationalUnit SubmittedByUnit { get; set; }
public PersonnelLevel? ApprovedLevel { get; set; }
public int? ApprovedByUnitId { get; set; }
public OrganizationalUnit ApprovedByUnit { get; set; }
public PersonnelStatus Status { get; set; }
public DateTime SubmittedAt { get; set; }
public DateTime? ApprovedAt { get; set; }
}
public enum PersonnelLevel
{
Company = 4, // 连级人才
Battalion = 3, // 营级人才
Regiment = 2, // 团级人才
Division = 1 // 师级人才
}
public enum PersonnelStatus
{
Pending, // 待审批
Approved, // 已批准
Rejected // 已拒绝
}
审批请求 (ApprovalRequest)
public class ApprovalRequest
{
public int Id { get; set; }
public ApprovalRequestType Type { get; set; }
public int RequestedByUserId { get; set; }
public UserAccount RequestedByUser { get; set; }
public string Reason { get; set; } // 修改原因
public string OriginalData { get; set; } // 原始数据
public string RequestedChanges { get; set; } // 请求的更改
public ApprovalStatus Status { get; set; }
public int? ReviewedByUserId { get; set; }
public UserAccount ReviewedByUser { get; set; }
public string ReviewComments { get; set; } // 审批意见
public DateTime RequestedAt { get; set; }
public DateTime? ReviewedAt { get; set; }
}
public enum ApprovalRequestType
{
AllocationModification, // 配额修改
ReportModification, // 上报修改
PersonnelModification // 人员修改
}
public enum ApprovalStatus
{
Pending, // 待审批
Approved, // 已批准
Rejected // 已拒绝
}
数据库架构关系
erDiagram
OrganizationalUnit ||--o{ OrganizationalUnit : "上下级关系"
OrganizationalUnit ||--o{ UserAccount : "拥有账户"
OrganizationalUnit ||--o{ MaterialAllocation : "创建配额"
OrganizationalUnit ||--o{ Personnel : "提交人员"
MaterialAllocation ||--o{ AllocationDistribution : "分配给"
AllocationDistribution }o--|| OrganizationalUnit : "目标单位"
Personnel }o--|| OrganizationalUnit : "审批单位"
UserAccount ||--o{ ApprovalRequest : "发起请求"
UserAccount ||--o{ ApprovalRequest : "审批请求"
正确性属性
属性是系统所有有效执行中都应该保持为真的特征或行为——本质上是关于系统应该做什么的正式声明。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。
属性反思
在分析所有验收标准后,可以合并几个属性以消除冗余:
- 与组织层级访问控制相关的属性(1.3、4.4、8.1、8.2、8.4)可以合并为综合的基于层级的访问控制属性
- 关于审计跟踪维护的属性(1.4、5.4、6.4)可以合并为通用的审计日志属性
- 关于数据显示要求的属性(3.1、4.1、4.2、8.3)可以合并为综合的数据可见性属性
- 关于工作流路由的属性(5.2、6.3)可以合并为通用的工作流路由属性
核心属性
属性1:组织层级访问控制 对于任何用户和任何数据资源,只有当用户的组织层级等于或高于资源的组织层级时,才应授予访问权限 验证需求:需求1.3、4.4、8.1、8.2、8.4
属性2:配额总和验证 对于任何带有单位配额的物资配额,所有单位配额的总和不应超过总配额指标 验证需求:需求2.3
属性3:完成率计算一致性 对于任何具有实际完成和单位指标的配额分配,完成率应等于实际完成除以单位指标 验证需求:需求3.3
属性4:层级数据汇总 对于任何组织单位,显示的汇总数据应等于所有直接下级单位数据的总和 验证需求:需求3.4、4.1
属性5:工作流状态修改限制 对于任何已提交的报告或人员记录,一旦被上级组织层级批准,应阻止直接修改 验证需求:需求5.1、5.5
属性6:人员等级分配一致性 对于任何已批准的人员记录,分配的人员等级应与批准单位的组织层级完全对应 验证需求:需求7.2、7.3、7.5
属性7:必填字段验证 对于任何数据提交(配额、报告或人员),所有必填字段必须存在且有效,才能接受提交 验证需求:需求2.2、6.1
属性8:自动数据分发 对于任何创建的配额,应自动为所有指定的目标组织单位创建分配记录 验证需求:需求2.4
属性9:审计跟踪完整性 对于任何修改数据的系统操作,应创建相应的审计日志条目,包含完整的操作详情 验证需求:需求1.4、5.4、6.4
属性10:组织层级分类 对于任何组织单位,应被分类为四个有效层级中的一个:师团、团、营或连 验证需求:需求1.2
错误处理
输入验证错误
- 无效组织结构:当检测到组织层级违规时,返回结构化错误消息
- 配额验证失败:当单位配额超过总配额指标时,提供清晰的反馈
- 缺少必填字段:对不完整的提交返回字段特定的验证错误
- 无效文件格式:拒绝不符合2寸格式要求的照片上传,并提供描述性错误消息
授权错误
- 权限不足:当用户尝试未授权操作时,返回HTTP 403并说明具体权限要求
- 跨层级访问违规:阻止并记录尝试访问组织层级外数据的行为
- 工作流状态违规:阻止并报告尝试在没有适当工作流的情况下修改已批准记录的行为
业务逻辑错误
- 循环组织引用:检测并防止组织单位成为自己的上级或下级
- 重复人员记录:使用身份证号和其他唯一标识符验证现有人员
- 无效审批工作流:确保审批请求路由到适当的上级单位
系统错误
- 数据库连接失败:为数据库连接问题实施重试逻辑和优雅降级
- 文件上传失败:处理照片和支持文档的存储失败,并进行适当的回滚
- 审计日志失败:确保即使审计日志临时失败,系统操作也能继续,并具有恢复机制
测试策略
双重测试方法
系统将采用单元测试和基于属性的测试来确保全面覆盖:
- 单元测试验证特定示例、边界情况和错误条件
- 属性测试验证应在所有输入中保持的通用属性
- 两者结合提供全面覆盖:单元测试捕获具体错误,属性测试验证一般正确性
单元测试要求
单元测试将专注于:
- 演示每个组件正确行为的特定示例
- 组织层级和数据访问之间的集成点
- 具有已知输入和预期输出的错误处理场景
- 工作流状态转换和审批流程
基于属性的测试要求
测试框架:系统将使用**.NET的FsCheck**进行基于属性的测试,配置为每个属性测试运行最少100次迭代。
每个基于属性的测试将:
- 使用明确引用正确性属性的注释进行标记:
**功能:military-training-material-management,属性{编号}:{属性文本}** - 在域约束内生成随机但有效的测试数据
- 验证指定属性在所有生成的输入中都成立
- 专注于测试正确性属性部分中定义的通用属性
属性测试实现要求:
- 每个正确性属性必须由单个基于属性的测试实现
- 测试应生成现实的组织结构、配额和人员数据
- 智能生成器应将输入约束到有效的组织层级和业务规则
- 属性测试不应使用模拟,而应针对真实的业务逻辑实现进行测试
集成测试
集成测试将验证:
- 从配额创建到完成上报的端到端工作流
- 认证、授权和业务逻辑之间的跨模块交互
- 复杂操作中的数据库事务完整性
- 各种认证和授权场景下的API端点行为
性能测试
性能测试将验证:
- 大型组织结构中层级数据汇总的响应时间
- 复杂组织层级查询的数据库查询性能
- 人员照片和支持文档的文件上传性能
- 军事组织典型使用模式下的并发用户访问模式