687 lines
23 KiB
Markdown
687 lines
23 KiB
Markdown
# 奖学金申请管理模块需求设计 v2.0
|
||
|
||
**版本**: v2.0
|
||
**更新时间**: 2025-01-01
|
||
**文档说明**: 基于班主任代学生申请模式的重新设计
|
||
|
||
---
|
||
|
||
## 📋 1. 需求概述
|
||
|
||
### 1.1 背景说明
|
||
|
||
基于实际业务需求调研,奖学金申请流程需要调整为:
|
||
- **班主任代申请模式**:不再是学生自主申请,而是由班主任从班级学生中选择推荐
|
||
- **材料上传管理**:班主任可以为每个推荐学生上传申请材料(非必填)
|
||
- **名额控制机制**:严格按照班级或学院分配的名额进行申请限制
|
||
- **时间窗口控制**:只能在批次开放的时间段内进行申请操作
|
||
|
||
### 1.2 核心变更点
|
||
|
||
| 变更点 | 原设计 | 新设计 |
|
||
|--------|--------|--------|
|
||
| **申请主体** | 学生自主申请 | 班主任代学生申请 |
|
||
| **申请方式** | 学生在线填写申请表 | 班主任从班级学生中选择 |
|
||
| **材料上传** | 学生自行上传 | 班主任统一管理上传 |
|
||
| **条件过滤** | 系统自动过滤 | 暂时不做申请条件过滤 |
|
||
| **名额控制** | 按院系统计控制 | 按班级→学院层级控制 |
|
||
|
||
---
|
||
|
||
## 👥 2. 角色权限设计
|
||
|
||
### 2.1 角色定义
|
||
|
||
| 角色 | 申请管理权限 | 主要操作 |
|
||
|------|-------------|----------|
|
||
| **班主任** | 本班级学生申请管理 | 选择学生、上传材料、提交申请 |
|
||
| **学院管理员** | 本学院申请审核管理 | 查看申请、审核、统计 |
|
||
| **学生处管理员** | 全校申请统计管理 | 全局统计、结果确认 |
|
||
| **学生** | 查看自己申请状态 | 查看申请进度、结果 |
|
||
|
||
### 2.2 权限矩阵
|
||
|
||
| 功能模块 | 班主任 | 学院管理员 | 学生处管理员 | 学生 |
|
||
|----------|--------|------------|-------------|------|
|
||
| 学生选择推荐 | ✏️ | 🔍 | 🔍 | ❌ |
|
||
| 材料上传管理 | ✏️ | 🔍 | 🔍 | ❌ |
|
||
| 申请提交 | ✏️ | ❌ | ❌ | ❌ |
|
||
| 申请审核 | 🔍 | ✏️ | ✏️ | ❌ |
|
||
| 申请状态查看 | ✅ | ✅ | ✅ | 🔍 |
|
||
| 统计报表 | 🔍 | ✏️ | ✅ | ❌ |
|
||
|
||
**图例**: ✅全部权限 ✏️编辑权限 🔍查看权限 ❌无权限
|
||
|
||
---
|
||
|
||
## 🔧 3. 功能模块设计
|
||
|
||
### 3.1 班主任申请管理
|
||
|
||
#### 3.1.1 学生选择功能
|
||
|
||
**功能描述**: 班主任从本班级学生中选择推荐申请奖学金的学生
|
||
|
||
**核心逻辑**:
|
||
```
|
||
1. 获取班级学生列表(显示基本信息:学号、姓名、专业)
|
||
2. 支持多选学生(暂不做申请条件自动过滤)
|
||
3. 实时显示已选择学生数量 vs 可申请名额
|
||
4. 名额控制:优先使用班级分配名额,无班级名额时使用学院名额
|
||
5. 提供学生基本信息预览(便于班主任选择判断)
|
||
```
|
||
|
||
**界面要求**:
|
||
- 学生列表表格:学号、姓名、专业、在校状态
|
||
- 批量选择操作:全选、反选、清空
|
||
- 名额提示:`已选择 X 人,可申请名额 Y 人`
|
||
- 学生详情弹窗:点击学生姓名显示详细信息
|
||
|
||
#### 3.1.2 材料上传管理
|
||
|
||
**功能描述**: 班主任为每个推荐学生上传申请材料
|
||
|
||
**核心逻辑**:
|
||
```
|
||
1. 已选择学生的材料管理列表
|
||
2. 支持每个学生上传多个材料文件
|
||
3. 材料分类管理:成绩单、获奖证书、其他证明
|
||
4. 文件格式限制:PDF、JPG、PNG,单文件不超过10MB
|
||
5. 材料状态标识:已上传、未上传(材料上传为非必填)
|
||
```
|
||
|
||
**界面要求**:
|
||
- 学生材料管理表格:学生信息、材料数量、上传状态、操作
|
||
- 材料上传弹窗:支持拖拽上传、批量上传
|
||
- 材料预览功能:支持在线预览已上传材料
|
||
- 进度提示:`X 人已上传材料,Y 人未上传`
|
||
|
||
#### 3.1.3 申请提交控制
|
||
|
||
**功能描述**: 班主任统一提交本班级所有推荐学生的申请
|
||
|
||
**核心逻辑**:
|
||
```
|
||
1. 时间窗口检查:必须在批次申请开放时间内
|
||
2. 名额数量检查:推荐学生数不能超过分配名额
|
||
3. 名额分配检查:班级有名额优先使用,无班级名额时使用学院名额
|
||
4. 批量生成申请记录:每个学生生成一条申请记录
|
||
5. 状态更新:申请提交后不能修改,除非撤回
|
||
```
|
||
|
||
**提交前验证**:
|
||
- ✅ 批次申请时间有效性
|
||
- ✅ 推荐学生数量 ≤ 可用名额
|
||
- ✅ 学生信息完整性
|
||
- ⚠️ 材料上传完整性(提示但不强制)
|
||
|
||
### 3.2 名额控制机制
|
||
|
||
#### 3.2.1 层级名额分配
|
||
|
||
```
|
||
全校总名额
|
||
├── 学院A名额
|
||
│ ├── 班级A1名额 (优先使用)
|
||
│ ├── 班级A2名额
|
||
│ └── 学院A机动名额 (班级无名额时使用)
|
||
└── 学院B名额
|
||
├── 班级B1名额
|
||
└── 学院B机动名额
|
||
```
|
||
|
||
#### 3.2.2 名额使用逻辑
|
||
|
||
**申请时名额检查顺序**:
|
||
1. **班级名额优先**: 如果班级有分配名额,优先使用班级名额
|
||
2. **学院名额兜底**: 如果班级无名额,使用学院级别名额
|
||
3. **名额不足提示**: 超过可用名额时给出明确提示
|
||
4. **实时名额更新**: 申请提交后立即更新已用名额
|
||
|
||
**名额计算公式**:
|
||
```sql
|
||
-- 班级可用名额计算
|
||
班级可用名额 = 班级总名额 - 班级已用名额 - 班级预留名额
|
||
|
||
-- 学院可用名额计算(当班级无名额时)
|
||
学院可用名额 = 学院总名额 - 学院已用名额 - 学院预留名额
|
||
```
|
||
|
||
### 3.3 时间窗口控制
|
||
|
||
#### 3.3.1 申请时间控制
|
||
|
||
```java
|
||
// 申请时间检查逻辑
|
||
public boolean checkApplicationTimeWindow(Long batchId) {
|
||
ScholarshipBatch batch = batchService.getById(batchId);
|
||
Date now = new Date();
|
||
|
||
// 检查批次状态
|
||
if (!"ACTIVE".equals(batch.getStatus())) {
|
||
return false;
|
||
}
|
||
|
||
// 检查申请时间窗口
|
||
return now.after(batch.getApplicationStartTime())
|
||
&& now.before(batch.getApplicationEndTime());
|
||
}
|
||
```
|
||
|
||
#### 3.3.2 操作权限控制
|
||
|
||
| 操作 | 申请开始前 | 申请期间 | 申请结束后 |
|
||
|------|------------|----------|------------|
|
||
| 选择学生 | ❌ | ✅ | ❌ |
|
||
| 上传材料 | ❌ | ✅ | 🔍(仅查看) |
|
||
| 提交申请 | ❌ | ✅ | ❌ |
|
||
| 撤回申请 | ❌ | ✅ | ❌ |
|
||
| 查看状态 | ✅ | ✅ | ✅ |
|
||
|
||
---
|
||
|
||
## 📊 4. 数据模型设计
|
||
|
||
### 4.1 申请记录表调整
|
||
|
||
基于新需求,需要调整现有的申请记录表结构:
|
||
|
||
```sql
|
||
-- 修改申请记录表
|
||
ALTER TABLE jcbt_scholarship_application
|
||
ADD COLUMN `applicant_type` VARCHAR(20) DEFAULT 'TEACHER' COMMENT '申请人类型:STUDENT-学生申请,TEACHER-教师代申请';
|
||
|
||
ALTER TABLE jcbt_scholarship_application
|
||
ADD COLUMN `applicant_id` BIGINT(20) DEFAULT NULL COMMENT '申请人ID(班主任ID)';
|
||
|
||
ALTER TABLE jcbt_scholarship_application
|
||
ADD COLUMN `applicant_name` VARCHAR(100) DEFAULT NULL COMMENT '申请人姓名(班主任姓名)';
|
||
|
||
-- 修改申请类型枚举值
|
||
ALTER TABLE jcbt_scholarship_application
|
||
MODIFY COLUMN `application_type` VARCHAR(20) NOT NULL
|
||
COMMENT '申请类型:TEACHER_RECOMMEND-教师推荐,AUTO-自动评定,DIRECT-直接指定';
|
||
|
||
-- 添加班级信息索引
|
||
CREATE INDEX idx_class_batch ON jcbt_scholarship_application(class_id, batch_id);
|
||
CREATE INDEX idx_applicant_batch ON jcbt_scholarship_application(applicant_id, batch_id);
|
||
```
|
||
|
||
### 4.2 班级名额分配表
|
||
|
||
新增班级级别的名额分配管理:
|
||
|
||
```sql
|
||
-- 班级名额分配表
|
||
CREATE TABLE jcbt_scholarship_class_quota (
|
||
id BIGINT(20) NOT NULL COMMENT '主键ID',
|
||
batch_id BIGINT(20) NOT NULL COMMENT '批次ID',
|
||
scholarship_type_id BIGINT(20) NOT NULL COMMENT '奖学金类型ID',
|
||
dept_id BIGINT(20) NOT NULL COMMENT '学院ID',
|
||
class_id BIGINT(20) NOT NULL COMMENT '班级ID',
|
||
class_name VARCHAR(100) NOT NULL COMMENT '班级名称',
|
||
total_quota INT DEFAULT 0 COMMENT '总名额',
|
||
used_quota INT DEFAULT 0 COMMENT '已用名额',
|
||
reserved_quota INT DEFAULT 0 COMMENT '预留名额',
|
||
available_quota INT DEFAULT 0 COMMENT '可用名额',
|
||
allocation_method VARCHAR(20) DEFAULT 'MANUAL' COMMENT '分配方式:MANUAL-手动分配,AUTO-自动分配',
|
||
is_locked TINYINT(1) DEFAULT 0 COMMENT '是否锁定:0-否,1-是',
|
||
status VARCHAR(20) DEFAULT 'ACTIVE' COMMENT '状态:ACTIVE-有效,INACTIVE-无效',
|
||
remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||
tenant_id BIGINT(20) NOT NULL COMMENT '租户ID',
|
||
create_by BIGINT(20) DEFAULT NULL COMMENT '创建者',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
update_by BIGINT(20) DEFAULT NULL COMMENT '更新者',
|
||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
deleted TINYINT(1) DEFAULT 0 COMMENT '删除标记:0-正常,1-删除',
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_batch_type_class (batch_id, scholarship_type_id, class_id, deleted),
|
||
INDEX idx_dept_class (dept_id, class_id),
|
||
INDEX idx_batch_dept (batch_id, dept_id),
|
||
INDEX idx_quota_status (total_quota, status),
|
||
INDEX idx_tenant (tenant_id, deleted)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='班级名额分配表';
|
||
```
|
||
|
||
### 4.3 申请材料表调整
|
||
|
||
调整材料表以支持班主任上传:
|
||
|
||
```sql
|
||
-- 添加上传者信息
|
||
ALTER TABLE jcbt_scholarship_attachment
|
||
ADD COLUMN `uploader_type` VARCHAR(20) DEFAULT 'TEACHER' COMMENT '上传者类型:STUDENT-学生,TEACHER-教师';
|
||
|
||
ALTER TABLE jcbt_scholarship_attachment
|
||
ADD COLUMN `uploader_id` BIGINT(20) DEFAULT NULL COMMENT '上传者ID';
|
||
|
||
ALTER TABLE jcbt_scholarship_attachment
|
||
ADD COLUMN `uploader_name` VARCHAR(100) DEFAULT NULL COMMENT '上传者姓名';
|
||
|
||
-- 修改必需字段逻辑
|
||
ALTER TABLE jcbt_scholarship_attachment
|
||
MODIFY COLUMN `is_required` TINYINT(1) DEFAULT 0 COMMENT '是否必需:0-否,1-是(新需求中材料非必填)';
|
||
```
|
||
|
||
### 4.4 名额使用记录表
|
||
|
||
新增名额使用记录表,用于追踪名额使用情况:
|
||
|
||
```sql
|
||
-- 名额使用记录表
|
||
CREATE TABLE jcbt_scholarship_quota_usage (
|
||
id BIGINT(20) NOT NULL COMMENT '主键ID',
|
||
batch_id BIGINT(20) NOT NULL COMMENT '批次ID',
|
||
scholarship_type_id BIGINT(20) NOT NULL COMMENT '奖学金类型ID',
|
||
quota_type VARCHAR(20) NOT NULL COMMENT '名额类型:CLASS-班级名额,DEPT-学院名额',
|
||
target_id BIGINT(20) NOT NULL COMMENT '目标ID(班级ID或学院ID)',
|
||
application_id BIGINT(20) NOT NULL COMMENT '申请ID',
|
||
student_id BIGINT(20) NOT NULL COMMENT '学生ID',
|
||
operation_type VARCHAR(20) NOT NULL COMMENT '操作类型:USE-使用,RELEASE-释放',
|
||
operation_time DATETIME NOT NULL COMMENT '操作时间',
|
||
operator_id BIGINT(20) NOT NULL COMMENT '操作人ID',
|
||
operator_name VARCHAR(100) NOT NULL COMMENT '操作人姓名',
|
||
remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||
tenant_id BIGINT(20) NOT NULL COMMENT '租户ID',
|
||
create_by BIGINT(20) DEFAULT NULL COMMENT '创建者',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
update_by BIGINT(20) DEFAULT NULL COMMENT '更新者',
|
||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
deleted TINYINT(1) DEFAULT 0 COMMENT '删除标记:0-正常,1-删除',
|
||
PRIMARY KEY (id),
|
||
INDEX idx_batch_type_target (batch_id, scholarship_type_id, target_id),
|
||
INDEX idx_application_student (application_id, student_id),
|
||
INDEX idx_operation_time (operation_type, operation_time),
|
||
INDEX idx_tenant (tenant_id, deleted)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='名额使用记录表';
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 5. 业务流程设计
|
||
|
||
### 5.1 申请提交流程
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[班主任登录] --> B[选择申请批次]
|
||
B --> C[检查申请时间窗口]
|
||
C --> D{时间窗口有效?}
|
||
D -->|否| E[提示申请时间未开放]
|
||
D -->|是| F[获取班级学生列表]
|
||
F --> G[选择推荐学生]
|
||
G --> H[检查名额限制]
|
||
H --> I{名额足够?}
|
||
I -->|否| J[提示名额不足]
|
||
I -->|是| K[上传学生材料]
|
||
K --> L[确认提交申请]
|
||
L --> M[生成申请记录]
|
||
M --> N[更新名额使用]
|
||
N --> O[发送提交通知]
|
||
```
|
||
|
||
### 5.2 名额检查流程
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[开始名额检查] --> B[获取班级分配名额]
|
||
B --> C{班级有分配名额?}
|
||
C -->|是| D[计算班级可用名额]
|
||
C -->|否| E[获取学院分配名额]
|
||
D --> F{班级名额足够?}
|
||
F -->|是| G[使用班级名额]
|
||
F -->|否| E
|
||
E --> H[计算学院可用名额]
|
||
H --> I{学院名额足够?}
|
||
I -->|是| J[使用学院名额]
|
||
I -->|否| K[提示名额不足]
|
||
G --> L[允许申请]
|
||
J --> L
|
||
K --> M[拒绝申请]
|
||
```
|
||
|
||
### 5.3 材料管理流程
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[进入材料管理] --> B[显示已选学生列表]
|
||
B --> C[选择学生上传材料]
|
||
C --> D[检查文件格式]
|
||
D --> E{格式有效?}
|
||
E -->|否| F[提示格式错误]
|
||
E -->|是| G[上传文件到服务器]
|
||
G --> H[保存材料记录]
|
||
H --> I[更新材料状态]
|
||
I --> J[显示上传成功]
|
||
J --> K{还有其他学生?}
|
||
K -->|是| C
|
||
K -->|否| L[完成材料上传]
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 6. 接口设计
|
||
|
||
### 6.1 学生选择接口
|
||
|
||
```java
|
||
/**
|
||
* 获取班级学生列表(供选择推荐)
|
||
*/
|
||
@GetMapping("/class-students")
|
||
public R<List<StudentSelectVo>> getClassStudents(
|
||
@RequestParam Long classId,
|
||
@RequestParam Long batchId,
|
||
@RequestParam Long scholarshipTypeId) {
|
||
// 返回班级学生列表,包含基本信息和是否已申请状态
|
||
}
|
||
|
||
/**
|
||
* 检查申请名额限制
|
||
*/
|
||
@PostMapping("/check-quota")
|
||
public R<QuotaCheckVo> checkQuota(
|
||
@RequestBody QuotaCheckBo quotaCheckBo) {
|
||
// 检查选择的学生数量是否超过可用名额
|
||
}
|
||
```
|
||
|
||
### 6.2 申请提交接口
|
||
|
||
```java
|
||
/**
|
||
* 批量提交学生申请
|
||
*/
|
||
@PostMapping("/batch-submit")
|
||
public R<BatchSubmitVo> batchSubmitApplications(
|
||
@RequestBody BatchApplicationBo batchApplicationBo) {
|
||
// 批量创建申请记录,更新名额使用情况
|
||
}
|
||
|
||
/**
|
||
* 撤回班级申请
|
||
*/
|
||
@PostMapping("/withdraw-batch")
|
||
public R<Void> withdrawBatchApplications(
|
||
@RequestParam Long classId,
|
||
@RequestParam Long batchId,
|
||
@RequestParam Long scholarshipTypeId) {
|
||
// 撤回班级所有申请,释放名额
|
||
}
|
||
```
|
||
|
||
### 6.3 材料管理接口
|
||
|
||
```java
|
||
/**
|
||
* 上传学生申请材料
|
||
*/
|
||
@PostMapping("/upload-material")
|
||
public R<MaterialUploadVo> uploadStudentMaterial(
|
||
@RequestParam Long applicationId,
|
||
@RequestParam MultipartFile file,
|
||
@RequestParam String materialType) {
|
||
// 上传单个学生的申请材料
|
||
}
|
||
|
||
/**
|
||
* 获取学生材料列表
|
||
*/
|
||
@GetMapping("/student-materials")
|
||
public R<List<MaterialVo>> getStudentMaterials(
|
||
@RequestParam Long applicationId) {
|
||
// 获取指定申请的所有材料
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 7. 前端页面设计
|
||
|
||
### 7.1 申请管理主页面
|
||
|
||
**页面结构**:
|
||
```
|
||
[批次选择] [奖学金类型选择]
|
||
==========================================
|
||
申请状态: [时间窗口状态] [名额统计]
|
||
==========================================
|
||
学生选择区域:
|
||
┌─────────────────────────────────────┐
|
||
│ [全选] [反选] [清空] 已选择X人/可申请Y人 │
|
||
├─────────────────────────────────────┤
|
||
│ ☐ 张三 (2021001) 计算机科学与技术 │
|
||
│ ☑ 李四 (2021002) 软件工程 │
|
||
│ ☐ 王五 (2021003) 信息安全 │
|
||
└─────────────────────────────────────┘
|
||
==========================================
|
||
[上传材料] [提交申请] [撤回申请]
|
||
```
|
||
|
||
### 7.2 材料管理页面
|
||
|
||
**页面结构**:
|
||
```
|
||
材料上传管理
|
||
==========================================
|
||
┌─学生─┬─材料数量─┬─上传状态─┬─操作─┐
|
||
│ 张三 │ 2 │ 已完成 │ 查看 │
|
||
│ 李四 │ 0 │ 未上传 │ 上传 │
|
||
│ 王五 │ 1 │ 部分 │ 管理 │
|
||
└─────┴────────┴────────┴──────┘
|
||
==========================================
|
||
进度: 2人已上传材料,1人未上传
|
||
```
|
||
|
||
### 7.3 申请状态查看页面
|
||
|
||
**页面结构**:
|
||
```
|
||
申请状态总览
|
||
==========================================
|
||
批次: 2024年春季学期 | 类型: 国家奖学金
|
||
申请时间: 2024-03-01 ~ 2024-03-31
|
||
名额情况: 班级名额 2/3,学院名额 15/20
|
||
==========================================
|
||
申请学生列表:
|
||
┌─学号───┬─姓名─┬─状态───┬─材料─┬─操作─┐
|
||
│2021001 │ 张三 │ 待审核 │ 2 │ 查看 │
|
||
│2021002 │ 李四 │ 已通过 │ 0 │ 查看 │
|
||
└────────┴─────┴────────┴──────┴──────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 8. 技术实现要点
|
||
|
||
### 8.1 名额控制实现
|
||
|
||
```java
|
||
@Service
|
||
public class QuotaControlService {
|
||
|
||
/**
|
||
* 检查并分配名额
|
||
*/
|
||
public QuotaAllocationResult allocateQuota(QuotaAllocationBo request) {
|
||
// 1. 检查班级名额
|
||
QuotaVo classQuota = getClassQuota(request.getClassId(),
|
||
request.getBatchId(), request.getScholarshipTypeId());
|
||
|
||
if (classQuota != null && classQuota.getAvailableQuota() >= request.getStudentCount()) {
|
||
// 使用班级名额
|
||
return allocateClassQuota(request, classQuota);
|
||
}
|
||
|
||
// 2. 检查学院名额
|
||
QuotaVo deptQuota = getDeptQuota(request.getDeptId(),
|
||
request.getBatchId(), request.getScholarshipTypeId());
|
||
|
||
if (deptQuota != null && deptQuota.getAvailableQuota() >= request.getStudentCount()) {
|
||
// 使用学院名额
|
||
return allocateDeptQuota(request, deptQuota);
|
||
}
|
||
|
||
// 3. 名额不足
|
||
throw new BusinessException("可用名额不足");
|
||
}
|
||
}
|
||
```
|
||
|
||
### 8.2 时间窗口控制
|
||
|
||
```java
|
||
@Component
|
||
public class ApplicationTimeValidator {
|
||
|
||
@Autowired
|
||
private ScholarshipBatchService batchService;
|
||
|
||
/**
|
||
* 验证申请时间窗口
|
||
*/
|
||
public void validateApplicationTime(Long batchId) {
|
||
ScholarshipBatch batch = batchService.getById(batchId);
|
||
Date now = new Date();
|
||
|
||
// 检查批次状态
|
||
if (!"ACTIVE".equals(batch.getStatus())) {
|
||
throw new BusinessException("当前批次未开放申请");
|
||
}
|
||
|
||
// 检查申请开始时间
|
||
if (now.before(batch.getApplicationStartTime())) {
|
||
throw new BusinessException("申请尚未开始,开始时间:" +
|
||
DateUtils.formatDate(batch.getApplicationStartTime()));
|
||
}
|
||
|
||
// 检查申请结束时间
|
||
if (now.after(batch.getApplicationEndTime())) {
|
||
throw new BusinessException("申请已结束,结束时间:" +
|
||
DateUtils.formatDate(batch.getApplicationEndTime()));
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 8.3 批量申请提交
|
||
|
||
```java
|
||
@Service
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public class BatchApplicationService {
|
||
|
||
/**
|
||
* 批量提交申请
|
||
*/
|
||
public BatchSubmitResult batchSubmitApplications(BatchApplicationBo request) {
|
||
// 1. 验证申请时间
|
||
applicationTimeValidator.validateApplicationTime(request.getBatchId());
|
||
|
||
// 2. 分配名额
|
||
QuotaAllocationResult quotaResult = quotaControlService.allocateQuota(request);
|
||
|
||
// 3. 批量创建申请记录
|
||
List<ScholarshipApplication> applications = request.getStudentIds().stream()
|
||
.map(studentId -> buildApplication(request, studentId, quotaResult))
|
||
.collect(Collectors.toList());
|
||
|
||
scholarshipApplicationService.saveBatch(applications);
|
||
|
||
// 4. 更新名额使用情况
|
||
updateQuotaUsage(quotaResult);
|
||
|
||
// 5. 记录操作日志
|
||
logBatchOperation(request, applications);
|
||
|
||
return BatchSubmitResult.success(applications.size());
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 9. 测试用例设计
|
||
|
||
### 9.1 功能测试用例
|
||
|
||
| 测试场景 | 测试步骤 | 预期结果 |
|
||
|----------|----------|----------|
|
||
| 正常申请流程 | 1.选择学生 2.上传材料 3.提交申请 | 申请成功,名额正确扣减 |
|
||
| 名额不足 | 选择学生数量超过可用名额 | 提示名额不足,禁止提交 |
|
||
| 时间窗口外申请 | 在申请时间外进行操作 | 提示时间窗口错误 |
|
||
| 材料上传 | 上传各种格式文件 | 正确文件上传成功,错误格式拒绝 |
|
||
| 申请撤回 | 提交后撤回申请 | 申请状态更新,名额释放 |
|
||
|
||
### 9.2 性能测试用例
|
||
|
||
| 测试场景 | 并发数 | 数据量 | 性能要求 |
|
||
|----------|--------|--------|----------|
|
||
| 批量申请提交 | 50 | 100人/班 | 响应时间<3秒 |
|
||
| 学生列表查询 | 100 | 10000学生 | 响应时间<1秒 |
|
||
| 材料上传 | 20 | 10MB文件 | 上传成功率>99% |
|
||
|
||
---
|
||
|
||
## 📚 10. 部署说明
|
||
|
||
### 10.1 数据库升级脚本
|
||
|
||
1. 执行申请表结构调整脚本
|
||
2. 创建班级名额分配表
|
||
3. 创建名额使用记录表
|
||
4. 更新相关索引
|
||
|
||
### 10.2 配置项调整
|
||
|
||
```yaml
|
||
# application.yml
|
||
scholarship:
|
||
application:
|
||
# 材料上传配置
|
||
material:
|
||
max-file-size: 10MB
|
||
allowed-types: pdf,jpg,jpeg,png
|
||
upload-path: /data/scholarship/materials/
|
||
|
||
# 名额控制配置
|
||
quota:
|
||
check-enabled: true
|
||
auto-allocation: true
|
||
|
||
# 时间窗口配置
|
||
time-window:
|
||
strict-check: true
|
||
buffer-minutes: 30
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 11. 总结
|
||
|
||
### 11.1 主要改进点
|
||
|
||
1. **申请模式优化**: 从学生自申请改为班主任代申请,提高管理效率
|
||
2. **名额控制增强**: 实现班级→学院两级名额管理,更精确的控制
|
||
3. **材料管理简化**: 班主任统一管理,降低学生操作复杂度
|
||
4. **时间窗口严格控制**: 确保申请在规定时间内进行
|
||
|
||
### 11.2 技术创新点
|
||
|
||
1. **层级名额算法**: 智能的班级→学院名额分配算法
|
||
2. **批量操作优化**: 高效的批量申请提交和撤回机制
|
||
3. **实时状态同步**: 名额使用情况实时更新
|
||
4. **操作日志完整**: 完整的操作追踪和审计功能
|
||
|
||
### 11.3 下一步计划
|
||
|
||
1. **Phase 1**: 完成核心申请管理功能开发
|
||
2. **Phase 2**: 增加申请条件自动过滤功能
|
||
3. **Phase 3**: 完善统计报表和数据导出
|
||
4. **Phase 4**: 优化用户体验和性能调优
|
||
|
||
---
|
||
|
||
**文档维护**: 本文档将随着需求变更和系统开发进展持续更新
|
||
**最后更新**: 2025-01-01
|
||
**文档版本**: v2.0 |