提交
This commit is contained in:
1 parent
fb6d0aa63c
commit
ff1228873c
37 files changed
+11861
-1823
No files matched your search
+69
-48
@@ -2,7 +2,7 @@
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本分文档详细说明学生退学、休学、毕业处理中的核心状态修改内容,包括学生学籍状态和用户登录状态的变更逻辑。
|
||||
本分文档详细说明学生退学、休学、毕业、复学处理中的核心状态修改内容,包括学生学籍状态和用户登录状态的变更逻辑。
|
||||
|
||||
## 🎯 核心状态修改
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
| `3` | 复学 | 从休学状态恢复 | info |
|
||||
| `4` | 退学 | 终止学籍 | danger |
|
||||
| `5` | 毕业 | 正常毕业 | success |
|
||||
|
||||
**重要说明**:
|
||||
- 数据库字段 `student_status` 为 char(1) 类型
|
||||
- 字典类型为 `xg_student_status`
|
||||
- 状态值与数据库字段值直接对应,无需转换
|
||||
| `6` | 不在籍 | - | - |
|
||||
| `7` | 结业 | - | - |
|
||||
| `8` | 停学 | - | - |
|
||||
| `9` | 分流 | - | - |
|
||||
|
||||
#### 🔄 处理逻辑
|
||||
- **休学**: `student_status = '2'`(休学)
|
||||
- **退学**: `student_status = '4'`(退学)
|
||||
- **毕业**: `student_status = '5'`(毕业)
|
||||
- **复学**: `student_status = '3'`(复学)
|
||||
|
||||
#### 📝 前端界面实现
|
||||
**文件位置**: `web/src/views/xg/xsjcxx/stuPersonalMsg/index.vue`
|
||||
@@ -53,7 +53,7 @@
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID (主键)
|
||||
-- @student_no: 学生学号
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, FU_XUE-复学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 休学处理
|
||||
@@ -66,7 +66,7 @@ WHERE id = @student_id
|
||||
|
||||
-- 退学处理
|
||||
UPDATE xg_student_msg
|
||||
SET student_status = '3',
|
||||
SET student_status = '4',
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = @student_id
|
||||
@@ -74,7 +74,15 @@ WHERE id = @student_id
|
||||
|
||||
-- 毕业处理
|
||||
UPDATE xg_student_msg
|
||||
SET student_status = '4',
|
||||
SET student_status = '5',
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = @student_id
|
||||
AND deleted = 0;
|
||||
|
||||
-- 复学处理
|
||||
UPDATE xg_student_msg
|
||||
SET student_status = '3',
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = @student_id
|
||||
@@ -96,9 +104,10 @@ WHERE id = @student_id
|
||||
| `1` | 停用 | 账号已被禁用 |
|
||||
|
||||
#### 🔄 处理逻辑
|
||||
- **休学**: 可选择保留账号(`status` 保持 `0`)或禁用账号(`status = '1'`)
|
||||
- **退学**: 必须禁用账号(`status = '1'`)
|
||||
- **毕业**: 必须禁用账号(`status = '1'`)
|
||||
- **休学**: 禁用账号(`status = '1'`)
|
||||
- **退学**: 禁用账号(`status = '1'`)
|
||||
- **毕业**: 禁用账号(`status = '1'`)
|
||||
- **复学**: 启用账号(`status = '0'`)
|
||||
|
||||
#### 📝 后端实体类
|
||||
**文件位置**: `backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java`
|
||||
@@ -113,29 +122,34 @@ WHERE id = @student_id
|
||||
#### 💾 SQL处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID (对应sys_user.user_id)
|
||||
-- @student_no: 学生学号 (对应sys_user.user_name)
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, FU_XUE-复学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 退学/毕业:禁用用户账号
|
||||
-- 1. 备份原始数据到his表
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = @student_id;
|
||||
|
||||
-- 2. 处理用户账号状态
|
||||
-- 退学/休学/毕业:禁用用户账号
|
||||
UPDATE sys_user
|
||||
SET status = '1',
|
||||
update_by = @operator_id,
|
||||
update_time = NOW(),
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 学生状态变更-', @change_type, '-', NOW())
|
||||
WHERE user_name = @student_no
|
||||
update_time = NOW()
|
||||
WHERE user_id = @student_id
|
||||
AND account_type = '2' -- 学生账户类型
|
||||
AND del_flag = '0';
|
||||
AND del_flag = '0'
|
||||
AND @change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE');
|
||||
|
||||
-- 休学:可选保留账号(根据业务需求决定是否执行)
|
||||
-- UPDATE sys_user
|
||||
-- SET status = '1', -- 如需禁用则取消注释
|
||||
-- update_by = @operator_id,
|
||||
-- update_time = NOW(),
|
||||
-- remark = CONCAT(COALESCE(remark, ''), ' | 学生休学-', NOW())
|
||||
-- WHERE user_name = @student_no
|
||||
-- AND account_type = '2'
|
||||
-- AND del_flag = '0';
|
||||
-- 复学:启用用户账号
|
||||
UPDATE sys_user
|
||||
SET status = '0',
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE user_id = @student_id
|
||||
AND account_type = '2' -- 学生账户类型
|
||||
AND del_flag = '0'
|
||||
AND @change_type = 'FU_XUE';
|
||||
```
|
||||
|
||||
### 3. 学生状态变更记录
|
||||
@@ -168,8 +182,8 @@ WHERE user_name = @student_no
|
||||
```java
|
||||
// 变更类型枚举
|
||||
public enum ChangeType {
|
||||
TUI_XUE("退学"),
|
||||
XIU_XUE("休学"),
|
||||
TUI_XUE("退学"),
|
||||
FU_XUE("复学"),
|
||||
BI_YE("毕业");
|
||||
}
|
||||
@@ -183,10 +197,11 @@ public enum ChangeType {
|
||||
```
|
||||
1. 创建状态变更记录 (xg_student_status_change)
|
||||
2. 验证学生当前状态和业务规则
|
||||
3. 更新学生学籍状态 (xg_student_msg.student_status)
|
||||
4. 根据变更类型处理用户登录状态 (sys_user.status)
|
||||
5. 记录操作日志和审计信息
|
||||
6. 触发后续业务处理 (组织关系、经济资助等)
|
||||
3. 备份原始数据到his表
|
||||
4. 更新学生学籍状态 (xg_student_msg.student_status)
|
||||
5. 根据变更类型处理用户登录状态 (sys_user.status)
|
||||
6. 记录操作日志和审计信息
|
||||
7. 触发后续业务处理 (组织关系、退宿处理等)
|
||||
```
|
||||
|
||||
#### ⚡ 事务处理要求
|
||||
@@ -197,11 +212,15 @@ START TRANSACTION;
|
||||
-- 步骤1: 创建变更记录
|
||||
INSERT INTO xg_student_status_change (...) VALUES (...);
|
||||
|
||||
-- 步骤2: 更新学生状态
|
||||
-- 步骤2: 备份原始数据到his表
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = ?;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = ?;
|
||||
|
||||
-- 步骤3: 更新学生状态
|
||||
UPDATE xg_student_msg SET student_status = ?, update_time = NOW() WHERE id = ?;
|
||||
|
||||
-- 步骤3: 更新用户状态 (如需要)
|
||||
UPDATE sys_user SET status = ?, update_time = NOW() WHERE user_name = ?;
|
||||
-- 步骤4: 更新用户状态
|
||||
UPDATE sys_user SET status = ?, update_time = NOW() WHERE user_id = ?;
|
||||
|
||||
-- 提交事务
|
||||
COMMIT;
|
||||
@@ -230,17 +249,18 @@ WHERE user_name = @student_no AND del_flag = '0';
|
||||
|
||||
#### 📊 状态变更矩阵
|
||||
|
||||
| 当前状态 | 可变更状态 | 说明 |
|
||||
|----------|------------|------|
|
||||
| 在读(1) | 休学(2)、退学(4)、毕业(5) | 正常学籍状态下的变更 |
|
||||
| 休学(2) | 复学(3)、退学(4)、毕业(5) | 休学状态下的恢复或终止 |
|
||||
| 复学(3) | 休学(2)、退学(4)、毕业(5) | 复学后的再次变更 |
|
||||
| 其他状态 | 需特殊审批 | 异常状态需要额外处理 |
|
||||
| 当前状态 | 可变更状态 | 账号处理 | 说明 |
|
||||
|----------|------------|----------|------|
|
||||
| 在读(1) | 休学(2)、退学(4)、毕业(5) | 禁用账号 | 正常学籍状态下的变更 |
|
||||
| 休学(2) | 复学(3)、退学(4)、毕业(5) | 禁用账号 | 休学状态下的恢复或终止 |
|
||||
| 复学(3) | 休学(2)、退学(4)、毕业(5) | 禁用账号 | 复学后的再次变更 |
|
||||
| 其他状态 | 需特殊审批 | 根据情况 | 异常状态需要额外处理 |
|
||||
|
||||
#### ⚠️ 业务约束
|
||||
- **休学限制**: 同一学年内休学不能超过规定次数
|
||||
- **退学限制**: 退学后不能恢复为正常学籍
|
||||
- **毕业限制**: 毕业状态为最终状态,不允许变更
|
||||
- **复学限制**: 只有休学状态才能复学
|
||||
- **时间约束**: 状态变更需要满足学年学期要求
|
||||
|
||||
### 4. 异常处理机制
|
||||
@@ -315,13 +335,14 @@ public class XgStudentStatusChangeServiceImpl implements IXgStudentStatusChangeS
|
||||
```vue
|
||||
<template>
|
||||
<el-form :model="form" :rules="rules" ref="statusChangeForm">
|
||||
<el-form-item label="变更类型" prop="changeType">
|
||||
<el-select v-model="form.changeType" placeholder="请选择变更类型">
|
||||
<el-option label="休学" value="XIU_XUE" />
|
||||
<el-option label="退学" value="TUI_XUE" />
|
||||
<el-option label="毕业" value="BI_YE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="变更类型" prop="changeType">
|
||||
<el-select v-model="form.changeType" placeholder="请选择变更类型">
|
||||
<el-option label="休学" value="XIU_XUE" />
|
||||
<el-option label="退学" value="TUI_XUE" />
|
||||
<el-option label="复学" value="FU_XUE" />
|
||||
<el-option label="毕业" value="BI_YE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="生效日期" prop="effectiveDate">
|
||||
<el-date-picker
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本分文档详细说明学生退学、休学、毕业处理中的组织关系处理内容,包括班级干部信息和社团成员关系的变更逻辑。
|
||||
本分文档详细说明学生退学、休学、毕业、复学处理中的组织关系处理内容,包括班级干部信息和社团成员关系的变更逻辑。
|
||||
|
||||
## 👥 组织关系处理
|
||||
|
||||
@@ -336,13 +336,14 @@ int deleteCount = sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
|
||||
-- 建议在学生状态变更的大事务中包含组织关系处理
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. 更新学生学籍状态
|
||||
UPDATE xg_student_msg SET student_status = ? WHERE id = ?;
|
||||
-- 1. 备份原始数据到his表
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = ?;
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = ?;
|
||||
|
||||
-- 2. 处理班级干部关系
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = ? WHERE student_id = ?;
|
||||
-- 2. 处理班级干部关系(仅退学、休学、毕业时)
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = ?, term_end_date = NOW(), dismissal_date = NOW(), dismissal_reason = ? WHERE student_id = ?;
|
||||
|
||||
-- 3. 处理社团成员关系
|
||||
-- 3. 处理社团成员关系(仅退学、休学、毕业时)
|
||||
UPDATE stgl_member SET status = 4 WHERE user_id = ?;
|
||||
|
||||
-- 4. 清理用户角色(如果需要)
|
||||
|
||||
+3
-765
@@ -2,773 +2,11 @@
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本分文档详细说明学生退学、休学、毕业处理中的经济资助业务处理内容,包括奖学金申请、获奖记录、勤工俭学和贫困生认定的变更逻辑。
|
||||
|
||||
## 💰 经济资助处理
|
||||
|
||||
### 1. 奖学金申请处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
**表名**: `jcbt_scholarship_application`
|
||||
**主键**: `id` (bigint(20))
|
||||
**核心关联字段**:
|
||||
- `batch_id`: 批次ID
|
||||
- `scholarship_type_id`: 奖学金类型ID
|
||||
- `student_id`: 学生ID
|
||||
- `student_no`: 学号
|
||||
- `student_name`: 学生姓名
|
||||
|
||||
#### 🎯 核心业务字段
|
||||
基于数据库表 `jcbt_scholarship_application` 的实际结构:
|
||||
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `current_status` | varchar(20) | 当前状态 | PENDING |
|
||||
| `application_type` | varchar(20) | 申请类型(TEACHER_RECOMMEND/AUTO/DIRECT) | - |
|
||||
| `calculated_score` | decimal(8,2) | 系统计算分数 | NULL |
|
||||
| `final_score` | decimal(8,2) | 最终评定分数 | NULL |
|
||||
| `ranking_in_dept` | int(11) | 院系排名 | NULL |
|
||||
| `ranking_in_major` | int(11) | 专业排名 | NULL |
|
||||
| `submit_time` | datetime | 提交时间 | NULL |
|
||||
| `applicant_type` | varchar(20) | 申请人类型(STUDENT/TEACHER) | TEACHER |
|
||||
|
||||
#### 🎯 申请状态字典
|
||||
系统使用 `jcbt_status` 字典类型(奖学金申请状态),具体定义如下:
|
||||
|
||||
| 状态值 | 状态名称 | 说明 | 样式类 |
|
||||
|--------|----------|------|--------|
|
||||
| `PENDING` | 待审核 | 申请已提交,等待审核 | warning |
|
||||
| `APPROVED` | 已通过 | 审核通过,获得奖学金资格 | success |
|
||||
| `REJECTED` | 已拒绝 | 审核未通过 | danger |
|
||||
| `WITHDRAWN` | 已撤回 | 申请人主动撤回或系统自动撤回 | info |
|
||||
|
||||
**关键字段说明** (基于实体类代码分析):
|
||||
- `currentStatus`: 当前状态 (PENDING/APPROVED/REJECTED/WITHDRAWN)
|
||||
- `applicationType`: 申请类型 (RECOMMEND-教师推荐,AUTO-自动评定,DIRECT-直接指定)
|
||||
- `calculatedScore`: 系统计算分数
|
||||
- `finalScore`: 最终评定分数
|
||||
- `rankingInDept`: 院系排名
|
||||
- `rankingInMajor`: 专业排名
|
||||
- `submitTime`: 提交时间
|
||||
|
||||
#### 🔄 奖学金评选流程
|
||||
|
||||
##### 📋 完整评选流程
|
||||
```
|
||||
1. 奖学金批次发布 → 学生申请提交
|
||||
2. 学院初审 → 系统评分计算
|
||||
3. 学生处终审 → 排名确定
|
||||
4. 获奖公示 → 证书生成
|
||||
5. 资金发放 → 档案归档
|
||||
6. 学生状态变更 → 相应流程调整
|
||||
```
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `JcbtScholarshipApplication.java`
|
||||
**控制器**: `JcbtScholarshipApplicationController.java`
|
||||
**服务类**: `JcbtScholarshipApplicationServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 奖学金申请实体类关键字段
|
||||
@Data
|
||||
@TableName("jcbt_scholarship_application")
|
||||
public class JcbtScholarshipApplication extends BaseEntity {
|
||||
private Long batchId; // 批次ID
|
||||
private Long scholarshipTypeId; // 奖学金类型ID
|
||||
private Long studentId; // 学生ID
|
||||
private String studentNo; // 学号
|
||||
private String studentName; // 学生姓名
|
||||
private String currentStatus; // 当前状态
|
||||
private String applicationType; // 申请类型
|
||||
private Double calculatedScore; // 系统计算分数
|
||||
private Double finalScore; // 最终评定分数
|
||||
private Integer rankingInDept; // 院系排名
|
||||
private Integer rankingInMajor; // 专业排名
|
||||
private Date submitTime; // 提交时间
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `jcbt/scholarship/application/index.vue`
|
||||
**状态显示**: 使用字典标签显示申请状态
|
||||
|
||||
```vue
|
||||
<!-- 申请状态列 -->
|
||||
<el-table-column label="申请状态" align="center" prop="currentStatus" width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="jcbt_application_status" :value="scope.row.currentStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 评分页数列 -->
|
||||
<el-table-column label="最终得分" align="center" prop="finalScore" width="100">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.finalScore">{{ scope.row.finalScore }}</span>
|
||||
<span v-else class="text-muted">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 排名列 -->
|
||||
<el-table-column label="院系排名" align="center" prop="rankingInDept" width="100">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.rankingInDept">第{{ scope.row.rankingInDept }}名</span>
|
||||
<span v-else class="text-muted">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的奖学金申请处理逻辑
|
||||
- **休学**: `current_status = 'WITHDRAWN'`(撤回),保留重新申请可能
|
||||
- **退学**: `current_status = 'REJECTED'`(拒绝),终止评选资格
|
||||
- **毕业**: 保持 `APPROVED` 状态,保留获奖资格;其他状态设为 `WITHDRAWN`
|
||||
|
||||
#### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 更新奖学金申请状态
|
||||
UPDATE jcbt_scholarship_application
|
||||
SET current_status = CASE
|
||||
WHEN @change_type = 'XIU_XUE' THEN 'WITHDRAWN' -- 休学:撤回,可重新申请
|
||||
WHEN @change_type = 'TUI_XUE' THEN 'REJECTED' -- 退学:拒绝,终止评选资格
|
||||
WHEN @change_type = 'BI_YE' THEN
|
||||
CASE WHEN current_status = 'APPROVED' THEN 'APPROVED' -- 毕业:保持已通过状态
|
||||
ELSE 'WITHDRAWN' -- 其他状态设为撤回
|
||||
END
|
||||
ELSE current_status
|
||||
END,
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND current_status NOT IN ('REJECTED') -- 已拒绝的不重复处理
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
### 2. 奖学金获奖记录处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
**表名**: `jcbt_scholarship_award`
|
||||
**主键**: `id` (bigint(20))
|
||||
**核心关联字段**:
|
||||
- `application_id`: 申请ID
|
||||
- `batch_id`: 批次ID
|
||||
- `scholarship_type_id`: 奖学金类型ID
|
||||
- `student_id`: 学生ID
|
||||
- `student_no`: 学号
|
||||
- `student_name`: 学生姓名
|
||||
|
||||
#### 🎯 核心业务字段
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `award_no` | varchar(50) | 获奖编号 | - |
|
||||
| `award_amount` | decimal(10,2) | 奖励金额 | - |
|
||||
| `award_level` | varchar(20) | 获奖等级 | NULL |
|
||||
| `final_score` | decimal(8,2) | 最终得分 | NULL |
|
||||
| `ranking_in_dept` | int(11) | 院系排名 | NULL |
|
||||
| `award_date` | date | 获奖日期 | - |
|
||||
| `certificate_no` | varchar(100) | 证书编号 | NULL |
|
||||
| `is_published` | tinyint(1) | 是否公示 | 0 |
|
||||
| `publish_date` | date | 公示日期 | NULL |
|
||||
| `is_paid` | tinyint(1) | 是否已发放 | 0 |
|
||||
| `pay_date` | date | 发放日期 | NULL |
|
||||
|
||||
#### 🔄 奖学金发放流程
|
||||
|
||||
##### 📋 完整发放流程
|
||||
```
|
||||
1. 申请审核通过 → 生成获奖记录 (jcbt_scholarship_award)
|
||||
2. 获奖信息确认 → 分配获奖编号和证书编号
|
||||
3. 公示期开始 → 更新公示状态 (is_published = 1)
|
||||
4. 公示期结束 → 如无异议,准备发放
|
||||
5. 资金拨付 → 更新发放状态 (is_paid = 1)
|
||||
6. 学生状态变更 → 根据情况调整发放流程
|
||||
```
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
虽然没有找到对应的实体类,但从数据库表结构可以推断业务逻辑:
|
||||
|
||||
```java
|
||||
// 奖学金获奖记录关键业务逻辑(推断)
|
||||
public class ScholarshipAwardService {
|
||||
// 证书生成
|
||||
public void generateCertificate(Long awardId) {
|
||||
// 生成证书编号
|
||||
// 更新 certificate_no 字段
|
||||
}
|
||||
|
||||
// 公示处理
|
||||
public void publishAward(Long awardId, Date publishDate) {
|
||||
// 更新 is_published = 1
|
||||
// 设置 publish_date
|
||||
}
|
||||
|
||||
// 资金发放
|
||||
public void payAward(Long awardId, Date payDate) {
|
||||
// 更新 is_paid = 1
|
||||
// 设置 pay_date
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `jcbt/scholarship/award/index.vue`
|
||||
**状态显示**: 公示和发放状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 公示状态列 -->
|
||||
<el-table-column label="公示状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.isPublished" type="success">已公示</el-tag>
|
||||
<el-tag v-else type="warning">未公示</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 发放状态列 -->
|
||||
<el-table-column label="发放状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.isPaid" type="success">已发放</el-tag>
|
||||
<el-tag v-else type="info">未发放</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 证书编号列 -->
|
||||
<el-table-column label="证书编号" align="center" prop="certificateNo" width="150">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.certificateNo">{{ scope.row.certificateNo }}</span>
|
||||
<span v-else class="text-muted">待生成</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的获奖记录处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **休学**: 获奖记录保留,暂停发放流程,保留恢复发放的可能
|
||||
- **退学**: 获奖记录保留作为档案,但取消发放资格,记录撤销原因
|
||||
- **毕业**: 确保完成发放流程,确保证书和资金发放完整
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @student_no: 学生学号
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
-- @change_date: 状态变更日期 (默认为当前日期)
|
||||
|
||||
SET @change_date = COALESCE(@change_date, CURDATE());
|
||||
|
||||
-- 1. 休学处理:暂停发放流程,保留获奖记录
|
||||
UPDATE jcbt_scholarship_award
|
||||
SET remark = CONCAT(COALESCE(remark, ''), ' | 学生休学(', @change_date, '),获奖记录保留,发放流程暂停'),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND deleted = 0
|
||||
AND @change_type = 'XIU_XUE';
|
||||
|
||||
-- 2. 退学处理:取消发放资格,保留获奖记录作为档案
|
||||
UPDATE jcbt_scholarship_award
|
||||
SET is_paid = CASE
|
||||
WHEN is_paid = 0 THEN 0 -- 标记为不发放,保留记录作为档案
|
||||
ELSE is_paid -- 已发放的不变
|
||||
END,
|
||||
pay_date = CASE
|
||||
WHEN is_paid = 0 AND certificate_no IS NOT NULL THEN NULL -- 取消发放
|
||||
ELSE pay_date
|
||||
END,
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 学生退学(', @change_date, '),取消发放资格,获奖记录作为档案保留'),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND deleted = 0
|
||||
AND @change_type = 'TUI_XUE';
|
||||
|
||||
-- 3. 毕业处理:确保完成发放流程,归档获奖记录
|
||||
UPDATE jcbt_scholarship_award
|
||||
SET is_paid = CASE
|
||||
WHEN is_paid = 0 AND certificate_no IS NOT NULL THEN 1 -- 确保证书发放
|
||||
ELSE is_paid
|
||||
END,
|
||||
pay_date = CASE
|
||||
WHEN is_paid = 0 AND certificate_no IS NOT NULL THEN @change_date -- 确保证书发放
|
||||
ELSE pay_date
|
||||
END,
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 学生毕业(', @change_date, '),获奖记录正式归档'),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND deleted = 0
|
||||
AND @change_type = 'BI_YE';
|
||||
|
||||
-- 统计处理结果
|
||||
SELECT
|
||||
@change_type as change_type,
|
||||
COUNT(CASE WHEN @change_type = 'XIU_XUE' THEN 1 END) as leave_records,
|
||||
COUNT(CASE WHEN @change_type = 'TUI_XUE' THEN 1 END) as drop_records,
|
||||
COUNT(CASE WHEN @change_type = 'BI_YE' THEN 1 END) as graduate_records,
|
||||
COUNT(*) as total_processed,
|
||||
CONCAT('学生', @student_no, '状态变更,奖学金获奖记录处理完成') as operation_note
|
||||
FROM jcbt_scholarship_award
|
||||
WHERE student_id = @student_id
|
||||
AND deleted = 0
|
||||
AND (
|
||||
(@change_type = 'XIU_XUE' AND remark LIKE CONCAT('%学生休学(', @change_date, ')%'))
|
||||
OR (@change_type = 'TUI_XUE' AND remark LIKE CONCAT('%学生退学(', @change_date, ')%'))
|
||||
OR (@change_type = 'BI_YE' AND remark LIKE CONCAT('%学生毕业(', @change_date, ')%'))
|
||||
);
|
||||
```
|
||||
|
||||
### 3. 勤工俭学申请处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
**表名**: `jcbt_work_study_application`
|
||||
**主键**: `id` (bigint(20), 雪花ID)
|
||||
**核心关联字段**:
|
||||
- `position_id`: 岗位ID
|
||||
- `student_id`: 学生ID
|
||||
- `student_number`: 学号
|
||||
- `college_id`: 学院ID
|
||||
|
||||
#### 🎯 核心业务字段
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `status` | varchar(20) | 申请状态 | DRAFT |
|
||||
| `application_date` | datetime | 申请提交时间 | - |
|
||||
| `college_review_status` | varchar(20) | 学院审核状态 | NULL |
|
||||
| `college_review_time` | datetime | 学院审核时间 | NULL |
|
||||
| `final_review_status` | varchar(20) | 学生处审核状态 | NULL |
|
||||
| `final_review_time` | datetime | 学生处审核时间 | NULL |
|
||||
| `work_start_date` | date | 工作开始时间 | NULL |
|
||||
| `work_end_date` | date | 工作结束时间 | NULL |
|
||||
| `planned_work_hours` | int(11) | 计划工作时长 | NULL |
|
||||
|
||||
#### 🎯 申请状态字典
|
||||
勤工俭学申请状态基于数据库字段定义,包含两级审核状态:
|
||||
|
||||
| 状态值 | 状态名称 | 说明 | 样式类 |
|
||||
|--------|----------|------|--------|
|
||||
| `DRAFT` | 草稿 | 申请草稿,尚未提交 | info |
|
||||
| `SUBMITTED` | 已提交 | 已提交,等待审核 | warning |
|
||||
| `COLLEGE_REVIEWING` | 学院审核中 | 学院正在审核 | primary |
|
||||
| `COLLEGE_PASSED` | 学院审核通过 | 学院审核通过 | success |
|
||||
| `COLLEGE_REJECTED` | 学院审核拒绝 | 学院审核拒绝 | danger |
|
||||
| `FINAL_REVIEWING` | 学生处审核中 | 学生处正在审核 | primary |
|
||||
| `APPROVED` | 审核通过 | 最终审核通过 | success |
|
||||
| `REJECTED` | 审核拒绝 | 最终审核拒绝 | danger |
|
||||
| `WITHDRAWN` | 已撤回 | 申请人撤回 | info |
|
||||
|
||||
**审核状态字段说明**:
|
||||
- `college_review_status`: 学院审核状态(APPROVED/REJECTED)
|
||||
- `final_review_status`: 学生处审核状态(APPROVED/REJECTED)
|
||||
|
||||
#### 🔄 勤工俭学审核流程
|
||||
|
||||
##### 📋 完整审核流程
|
||||
```
|
||||
1. 学生申请提交 → 状态: SUBMITTED
|
||||
2. 学院审核 → 状态: COLLEGE_REVIEWING → COLLEGE_PASSED/COLLEGE_REJECTED
|
||||
3. 学生处终审 → 状态: FINAL_REVIEWING → APPROVED/REJECTED
|
||||
4. 工作安排 → 设置工作时间 (work_start_date, work_end_date)
|
||||
5. 学生状态变更 → 相应流程调整
|
||||
```
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `JcbtWorkStudyApplication.java`
|
||||
**控制器**: `JcbtWorkStudyApplicationController.java`
|
||||
**服务类**: `JcbtWorkStudyApplicationServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 勤工俭学申请实体类关键字段
|
||||
@Data
|
||||
@TableName("jcbt_work_study_application")
|
||||
public class JcbtWorkStudyApplication extends BaseEntity {
|
||||
private Long positionId; // 岗位ID
|
||||
private String positionName; // 岗位名称
|
||||
private Long studentId; // 学生ID
|
||||
private String studentName; // 学生姓名
|
||||
private String studentNumber; // 学号
|
||||
private String status; // 申请状态
|
||||
private String collegeReviewStatus; // 学院审核状态
|
||||
private String finalReviewStatus; // 学生处审核状态
|
||||
private Date workStartDate; // 工作开始时间
|
||||
private Date workEndDate; // 工作结束时间
|
||||
private Integer plannedWorkHours; // 计划工作时长
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `jcbt/workStudy/application/index.vue`
|
||||
**状态显示**: 两级审核状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 申请状态列 -->
|
||||
<el-table-column label="申请状态" align="center" prop="status" width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="work_study_application_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 学院审核状态列 -->
|
||||
<el-table-column label="学院审核" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.collegeReviewStatus === 'APPROVED'" type="success">通过</el-tag>
|
||||
<el-tag v-else-if="scope.row.collegeReviewStatus === 'REJECTED'" type="danger">拒绝</el-tag>
|
||||
<el-tag v-else type="warning">审核中</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 学生处审核状态列 -->
|
||||
<el-table-column label="学生处审核" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.finalReviewStatus === 'APPROVED'" type="success">通过</el-tag>
|
||||
<el-tag v-else-if="scope.row.finalReviewStatus === 'REJECTED'" type="danger">拒绝</el-tag>
|
||||
<el-tag v-else type="warning">审核中</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 工作时间列 -->
|
||||
<el-table-column label="工作时间" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.workStartDate && scope.row.workEndDate">
|
||||
{{ parseTime(scope.row.workStartDate, '{y}-{m}-{d}') }} 至
|
||||
{{ parseTime(scope.row.workEndDate, '{y}-{m}-{d}') }}
|
||||
</span>
|
||||
<span v-else class="text-muted">未安排</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的勤工俭学申请处理逻辑
|
||||
- **休学**: `status = 'WITHDRAWN'`(撤回),终止当前工作,保留重新申请可能
|
||||
- **退学**: `status = 'REJECTED'`(拒绝),终止所有相关安排
|
||||
- **毕业**: 保持 `APPROVED` 状态,其他状态设为 `WITHDRAWN`
|
||||
|
||||
#### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 更新勤工俭学申请状态
|
||||
UPDATE jcbt_work_study_application
|
||||
SET status = CASE
|
||||
WHEN @change_type = 'XIU_XUE' THEN 'WITHDRAWN' -- 休学:撤回,可重新申请
|
||||
WHEN @change_type = 'TUI_XUE' THEN 'REJECTED' -- 退学:拒绝,终止资格
|
||||
WHEN @change_type = 'BI_YE' THEN
|
||||
CASE WHEN status = 'APPROVED' THEN 'APPROVED' -- 毕业:保持已通过状态
|
||||
ELSE 'WITHDRAWN' -- 其他状态设为撤回
|
||||
END
|
||||
ELSE status
|
||||
END,
|
||||
-- 更新审核状态
|
||||
college_review_status = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') AND college_review_status IS NOT NULL THEN 'REJECTED'
|
||||
ELSE college_review_status
|
||||
END,
|
||||
final_review_status = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') AND final_review_status IS NOT NULL THEN 'REJECTED'
|
||||
ELSE final_review_status
|
||||
END,
|
||||
final_review_time = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') THEN NOW()
|
||||
ELSE final_review_time
|
||||
END,
|
||||
final_reviewer_id = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') THEN @operator_id
|
||||
ELSE final_reviewer_id
|
||||
END,
|
||||
final_reviewer_name = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') THEN '系统'
|
||||
ELSE final_reviewer_name
|
||||
END,
|
||||
final_review_comment = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') THEN CONCAT('学生', @change_type, ',岗位申请自动终止')
|
||||
ELSE final_review_comment
|
||||
END,
|
||||
-- 如果是进行中的工作,设置结束时间
|
||||
work_end_date = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') AND status = 'APPROVED' THEN CURDATE()
|
||||
ELSE work_end_date
|
||||
END,
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND status NOT IN ('REJECTED', 'COLLEGE_REJECTED') -- 已拒绝的不重复处理
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
### 4. 贫困生认定申请处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
**表名**: `jcbt_poverty_application`
|
||||
**主键**: `id` (bigint(20))
|
||||
**核心关联字段**:
|
||||
- `student_id`: 学生ID
|
||||
- `student_no`: 学号
|
||||
- `college_id`: 学院ID
|
||||
- `major_id`: 专业ID
|
||||
- `class_id`: 班级ID
|
||||
|
||||
#### 🎯 核心业务字段
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `application_no` | varchar(32) | 申请编号 | - |
|
||||
| `academic_year` | varchar(20) | 学年 | - |
|
||||
| `term` | tinyint(1) | 学期 | - |
|
||||
| `status` | varchar(20) | 申请状态 | DRAFT |
|
||||
| `recognition_group` | varchar(20) | 认定群体 | - |
|
||||
| `recognition_type_id` | bigint(20) | 认定类型ID | - |
|
||||
| `submit_time` | datetime | 提交时间 | NULL |
|
||||
| `audit_time` | datetime | 审核时间 | NULL |
|
||||
|
||||
#### 🎯 申请状态字典
|
||||
贫困生认定申请状态基于数据库表定义:
|
||||
|
||||
| 状态值 | 状态名称 | 说明 | 样式类 |
|
||||
|--------|----------|------|--------|
|
||||
| `DRAFT` | 草稿 | 申请草稿,尚未提交 | info |
|
||||
| `SUBMITTED` | 已提交 | 已提交,等待审核 | warning |
|
||||
| `REVIEWING` | 审核中 | 正在审核中 | primary |
|
||||
| `APPROVED` | 已通过 | 审核通过,获得贫困生资格 | success |
|
||||
| `REJECTED` | 已拒绝 | 审核未通过 | danger |
|
||||
| `WITHDRAWN` | 已撤回 | 申请人主动撤回 | info |
|
||||
| `REVOKED` | 已撤销 | 资格被撤销 | danger |
|
||||
|
||||
**特殊状态说明**:
|
||||
- `SUSPENDED`: 暂停状态(文档中提到但数据库中未定义,可能需要扩展)
|
||||
- `COMPLETED`: 完成状态(毕业时的最终状态)
|
||||
|
||||
#### 🔄 贫困生认定流程
|
||||
|
||||
##### 📋 完整认定流程
|
||||
```
|
||||
1. 学生申请提交 → 状态: SUBMITTED
|
||||
2. 班主任审核 → 学院评审小组审核
|
||||
3. 学校认定委员会终审 → 状态: APPROVED/REJECTED
|
||||
4. 资格确认 → 发放相关资助
|
||||
5. 学生状态变更 → 根据情况调整认定资格
|
||||
```
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `JcbtPovertyApplication.java`
|
||||
**控制器**: `JcbtPovertyApplicationController.java`
|
||||
**服务类**: `JcbtPovertyApplicationServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 贫困生认定申请实体类关键字段
|
||||
@Data
|
||||
@TableName("jcbt_poverty_application")
|
||||
public class JcbtPovertyApplication extends BaseEntity {
|
||||
private String applicationNo; // 申请编号
|
||||
private String academicYear; // 学年
|
||||
private Integer term; // 学期
|
||||
private Long studentId; // 学生ID
|
||||
private String studentNo; // 学号
|
||||
private String studentName; // 学生姓名
|
||||
private String status; // 申请状态
|
||||
private String recognitionGroup; // 认定群体
|
||||
private Long recognitionTypeId; // 认定类型ID
|
||||
private Date submitTime; // 提交时间
|
||||
private Date auditTime; // 审核时间
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `jcbt/poverty/application/index.vue`
|
||||
**状态显示**: 认定状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 申请状态列 -->
|
||||
<el-table-column label="申请状态" align="center" prop="status" width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="poverty_application_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 认定群体列 -->
|
||||
<el-table-column label="认定群体" align="center" prop="recognitionGroup" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.recognitionGroup }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 认定类型列 -->
|
||||
<el-table-column label="认定类型" align="center" prop="recognitionTypeName" width="150">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.recognitionTypeName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的贫困生认定处理逻辑
|
||||
- **休学**: 认定记录保留,资格暂时维持(可根据业务需求调整为WITHDRAWN)
|
||||
- **退学**: 认定资格撤销(REVOKED),终止贫困生资格
|
||||
- **毕业**: 认定流程完成,记录保持APPROVED状态
|
||||
|
||||
#### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 更新贫困生认定状态
|
||||
UPDATE jcbt_poverty_application
|
||||
SET status = CASE
|
||||
WHEN @change_type = 'XIU_XUE' THEN
|
||||
CASE WHEN status = 'APPROVED' THEN 'APPROVED' -- 休学:保持认定资格
|
||||
ELSE status
|
||||
END
|
||||
WHEN @change_type = 'TUI_XUE' THEN 'REVOKED' -- 退学:撤销认定
|
||||
WHEN @change_type = 'BI_YE' THEN status -- 毕业:保持现有状态
|
||||
ELSE status
|
||||
END,
|
||||
-- 更新审核信息(仅退学时更新)
|
||||
audit_time = CASE
|
||||
WHEN @change_type = 'TUI_XUE' THEN NOW()
|
||||
ELSE audit_time
|
||||
END,
|
||||
auditor_id = CASE
|
||||
WHEN @change_type = 'TUI_XUE' THEN @operator_id
|
||||
ELSE auditor_id
|
||||
END,
|
||||
auditor_name = CASE
|
||||
WHEN @change_type = 'TUI_XUE' THEN '系统'
|
||||
ELSE auditor_name
|
||||
END,
|
||||
audit_opinion = CASE
|
||||
WHEN @change_type = 'TUI_XUE' THEN '学生退学,贫困生认定撤销'
|
||||
ELSE audit_opinion
|
||||
END,
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND status NOT IN ('REVOKED') -- 已撤销的不重复处理
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
## 🔗 经济资助业务关联处理
|
||||
|
||||
### 1. 业务数据一致性保证
|
||||
|
||||
#### 🛡️ 事务处理要求
|
||||
```sql
|
||||
-- 建议在学生状态变更的大事务中包含所有经济资助处理
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. 更新学生学籍状态
|
||||
UPDATE xg_student_msg SET student_status = ? WHERE id = ?;
|
||||
|
||||
-- 2. 处理奖学金申请
|
||||
UPDATE jcbt_scholarship_application SET current_status = ? WHERE student_id = ?;
|
||||
|
||||
-- 3. 处理奖学金获奖记录
|
||||
UPDATE jcbt_scholarship_award SET remark = CONCAT(remark, ?) WHERE student_id = ?;
|
||||
|
||||
-- 4. 处理勤工俭学申请
|
||||
UPDATE jcbt_work_study_application SET status = ? WHERE student_id = ?;
|
||||
|
||||
-- 5. 处理贫困生认定
|
||||
UPDATE jcbt_poverty_application SET status = ? WHERE student_id = ?;
|
||||
|
||||
COMMIT;
|
||||
```
|
||||
|
||||
#### 📊 处理统计表
|
||||
|
||||
| 业务模块 | 涉及表数量 | 处理类型 | 重要程度 |
|
||||
|----------|------------|----------|----------|
|
||||
| 奖学金申请 | 1 (jcbt_scholarship_application) | 状态更新 | ⭐⭐⭐⭐ |
|
||||
| 奖学金获奖 | 1 (jcbt_scholarship_award) | 发放调整 | ⭐⭐⭐⭐⭐ |
|
||||
| 勤工俭学 | 1 (jcbt_work_study_application) | 审核终止 | ⭐⭐⭐⭐ |
|
||||
| 贫困生认定 | 1 (jcbt_poverty_application) | 资格调整 | ⭐⭐⭐⭐ |
|
||||
| **总计** | **4个表** | **状态更新+流程调整** | **⭐⭐⭐⭐⭐** |
|
||||
|
||||
### 2. 业务规则和约束
|
||||
|
||||
#### 📋 状态变更矩阵
|
||||
|
||||
| 当前状态 | 休学处理 | 退学处理 | 毕业处理 |
|
||||
|----------|----------|----------|----------|
|
||||
| 奖学金申请中 | 撤回(WITHDRAWN) | 拒绝(REJECTED) | 保持通过/撤回 |
|
||||
| 奖学金已通过 | 记录保留 | 取消发放 | 确保证书发放 |
|
||||
| 勤工俭学进行中 | 撤回(WITHDRAWN) | 拒绝(REJECTED) | 保持通过/撤回 |
|
||||
| 贫困生已认定 | 保持认定资格 | 撤销(REVOKED) | 保持认定状态 |
|
||||
|
||||
#### ⚠️ 重要业务约束
|
||||
- **资金安全**: 奖学金获奖记录涉及实际资金,不得随意删除
|
||||
- **证书管理**: 已发放证书的记录必须保留发放状态
|
||||
- **公示流程**: 已公示的奖学金变更可能需要重新公示
|
||||
- **档案完整性**: 所有经济资助记录作为学生档案的重要组成部分
|
||||
|
||||
### 3. 监控和审计要求
|
||||
|
||||
#### 📊 数据完整性检查
|
||||
```sql
|
||||
-- 检查处理结果的完整性
|
||||
SELECT
|
||||
'奖学金申请' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN current_status IN ('WITHDRAWN', 'REJECTED', 'APPROVED') THEN 1 END) as processed_count
|
||||
FROM jcbt_scholarship_application
|
||||
WHERE student_id = @student_id AND deleted = 0
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'奖学金获奖' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN remark LIKE '%学生%' THEN 1 END) as processed_count
|
||||
FROM jcbt_scholarship_award
|
||||
WHERE student_id = @student_id AND deleted = 0
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'勤工俭学' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN status IN ('WITHDRAWN', 'REJECTED', 'APPROVED') THEN 1 END) as processed_count
|
||||
FROM jcbt_work_study_application
|
||||
WHERE student_id = @student_id AND deleted = 0
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'贫困生认定' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN status IN ('SUSPENDED', 'REVOKED', 'COMPLETED') THEN 1 END) as processed_count
|
||||
FROM jcbt_poverty_application
|
||||
WHERE student_id = @student_id AND deleted = 0;
|
||||
```
|
||||
|
||||
#### 📝 审计日志记录
|
||||
```sql
|
||||
-- 记录经济资助处理的审计日志
|
||||
INSERT INTO sys_oper_log (
|
||||
title, business_type, method, request_method, operator_type,
|
||||
oper_name, dept_name, oper_url, oper_ip, oper_location,
|
||||
oper_param, json_result, status, error_msg, oper_time
|
||||
) VALUES (
|
||||
'经济资助业务处理', 'UPDATE', 'processEconomicSupport', 'PROCEDURE', 'MANAGE',
|
||||
@operator_name, @dept_name, '/economic/support/process', @client_ip, @location,
|
||||
CONCAT('学生ID:', @student_id, ',学号:', @student_no, ',变更类型:', @change_type),
|
||||
@process_result_json, 0, NULL, NOW()
|
||||
);
|
||||
```
|
||||
**注意**: 根据用户需求,经济资助处理不是学生退学、休学、毕业的核心业务逻辑,已删除相关处理内容。如有需要,可根据实际业务需求另行处理。
|
||||
|
||||
---
|
||||
|
||||
## 📅 更新记录
|
||||
|
||||
- **2025-12-XX**: 分文档创建,包含经济资助处理逻辑
|
||||
- **2025-12-XX**: 基于代码分析完善技术实现细节和业务逻辑
|
||||
- **后续更新**: 根据实际业务需求持续完善
|
||||
|
||||
---
|
||||
|
||||
*本分文档详细说明学生状态变更时的经济资助业务处理逻辑和技术实现,包括奖学金、勤工俭学和贫困生认定的完整处理方案。*
|
||||
- **2025-12-XX**: 根据用户需求删除经济资助处理逻辑,保留为非核心业务
|
||||
- **后续更新**: 如需要经济资助处理,可根据实际业务需求重新添加
|
||||
+25
-816
@@ -2,7 +2,7 @@
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本分文档详细说明学生退学、休学、毕业处理中的其他业务模块处理内容,包括住宿管理、心理健康、实践活动和其他关联信息的变更逻辑。
|
||||
本分文档详细说明学生退学、休学、毕业、复学处理中的其他业务模块处理内容,包括住宿管理和其他关联信息的变更逻辑。
|
||||
|
||||
## 🏠 住宿管理
|
||||
|
||||
@@ -16,843 +16,52 @@
|
||||
| `id` | bigint(20) | 主键ID | - |
|
||||
| `student_id` | bigint(20) | 学生ID | - |
|
||||
| `bed_id` | bigint(20) | 床位ID | - |
|
||||
| `room_id` | bigint(20) | 房间ID | - |
|
||||
| `building_id` | bigint(20) | 宿舍楼ID | - |
|
||||
| `campus_id` | bigint(20) | 校区ID | - |
|
||||
| `status` | varchar(10) | 状态(0正常 1已退宿) | - |
|
||||
| `assign_time` | datetime | 分配时间 | - |
|
||||
| `checkout_time` | datetime | 退宿时间 | NULL |
|
||||
| `remark` | varchar(100) | 备注 | NULL |
|
||||
| `deleted` | varchar(1) | 删除标志 | 0 |
|
||||
|
||||
**关键字段说明** (基于实体类代码分析):
|
||||
- `studentId`: 学生ID
|
||||
- `bedId`: 床位ID
|
||||
- `roomId`: 房间ID
|
||||
- `buildingId`: 宿舍楼ID
|
||||
- `campusId`: 校区ID
|
||||
- `status`: 状态(0正常 1已退宿)
|
||||
- `assignTime`: 分配时间
|
||||
- `checkoutTime`: 退宿时间
|
||||
|
||||
##### 宿舍申请表 (xg_dorm_application)
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| `application_type` | char(1) | 申请类型(1调宿 2退宿) |
|
||||
| `application_status` | varchar(20) | 审批状态 |
|
||||
|
||||
#### 🔄 宿舍退宿业务流程
|
||||
|
||||
##### 📋 完整退宿流程
|
||||
```
|
||||
1. 接收退宿申请或状态变更触发
|
||||
2. 验证学生当前住宿状态
|
||||
3. 检查是否有未完成的宿舍申请
|
||||
4. 更新床位分配状态为已退宿
|
||||
5. 处理相关的宿舍申请状态
|
||||
6. 记录退宿操作日志
|
||||
7. 释放床位资源供其他学生使用
|
||||
```
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `XgDormBedStudent.java`
|
||||
**服务类**: `XgDormBedStudentServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 宿舍床位学生分配实体类关键字段
|
||||
@Data
|
||||
@TableName("xg_dorm_bed_student")
|
||||
public class XgDormBedStudent extends TenantEntity {
|
||||
private Long studentId; // 学生ID
|
||||
private Long bedId; // 床位ID
|
||||
private Long roomId; // 房间ID
|
||||
private Long buildingId; // 宿舍楼ID
|
||||
private Long campusId; // 校区ID
|
||||
private String status; // 状态:0-正常,1-已退宿
|
||||
private Date assignTime; // 分配时间
|
||||
private Date checkoutTime; // 退宿时间
|
||||
private String remark; // 备注
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `xg/dorm/bedStudent/index.vue`
|
||||
**状态显示**: 住宿状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 住宿状态列 -->
|
||||
<el-table-column label="住宿状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === '0'" type="success">在住</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '1'" type="info">已退宿</el-tag>
|
||||
<el-tag v-else type="warning">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 退宿时间列 -->
|
||||
<el-table-column label="退宿时间" align="center" prop="checkoutTime" width="180">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.checkoutTime">
|
||||
{{ parseTime(scope.row.checkoutTime, '{y}-{m}-{d} {h}:{i}') }}
|
||||
</span>
|
||||
<span v-else class="text-muted">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的宿舍处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **休学**: 可选择保留宿舍或办理暂退宿(根据学校政策)
|
||||
- **退学**: 必须办理正式退宿,释放床位资源
|
||||
- **毕业**: 办理毕业退宿,释放床位资源
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, FU_XUE-复学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
-- @checkout_time: 退宿时间 (默认为当前时间)
|
||||
|
||||
SET @checkout_time = COALESCE(@checkout_time, NOW());
|
||||
-- 1. 备份原始数据到his表
|
||||
INSERT INTO xg_dorm_bed_student_his SELECT * FROM xg_dorm_bed_student WHERE student_id = @student_id;
|
||||
|
||||
-- 1. 退学/毕业:必须办理正式退宿
|
||||
-- 2. 清空学生信息表的住宿信息
|
||||
UPDATE xg_student_msg SET
|
||||
dormitory_building = NULL,
|
||||
dormitory_room = NULL,
|
||||
ext_field1 = NULL,
|
||||
update_time = NOW(),
|
||||
update_by = @operator_id
|
||||
WHERE id = @student_id;
|
||||
|
||||
-- 3. 处理宿舍住宿关系(退学、毕业时退宿)
|
||||
UPDATE xg_dorm_bed_student
|
||||
SET status = '1', -- 已退宿
|
||||
checkout_time = @checkout_time,
|
||||
update_by = @operator_id,
|
||||
SET status = '1',
|
||||
checkout_time = NOW(),
|
||||
update_time = NOW(),
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 学生', @change_type, '退宿')
|
||||
update_by = @operator_id
|
||||
WHERE student_id = @student_id
|
||||
AND status = '0' -- 当前在住
|
||||
AND deleted = '0'
|
||||
AND @change_type IN ('TUI_XUE', 'BI_YE');
|
||||
|
||||
-- 2. 处理进行中的宿舍申请
|
||||
UPDATE xg_dorm_application
|
||||
SET application_status = CASE
|
||||
WHEN application_type = '1' THEN 'cancel' -- 调宿申请:取消
|
||||
WHEN application_type = '2' THEN 'finish' -- 退宿申请:完成
|
||||
ELSE application_status
|
||||
END,
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND application_status IN ('draft', 'waiting') -- 草稿和待审核状态
|
||||
AND deleted = '0';
|
||||
|
||||
-- 3. 休学处理(可选:根据学校政策决定是否保留宿舍)
|
||||
-- 如果学校允许休学保留宿舍,则注释掉下面的UPDATE语句
|
||||
-- 如果需要休学退宿,取消下面的注释:
|
||||
-- UPDATE xg_dorm_bed_student
|
||||
-- SET status = '1', -- 已退宿
|
||||
-- checkout_time = @checkout_time,
|
||||
-- update_by = @operator_id,
|
||||
-- update_time = NOW(),
|
||||
-- remark = CONCAT(COALESCE(remark, ''), ' | 学生休学暂退宿')
|
||||
-- WHERE student_id = @student_id
|
||||
-- AND status = '0'
|
||||
-- AND deleted = '0'
|
||||
-- AND @change_type = 'XIU_XUE';
|
||||
```
|
||||
|
||||
## 🧠 心理健康管理
|
||||
|
||||
### 2. 心理咨询预约处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
|
||||
##### 咨询预约表 (xljk_consultation_appointment)
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `id` | bigint(20) | 主键ID | - |
|
||||
| `student_id` | bigint(20) | 学生ID | - |
|
||||
| `counselor_id` | bigint(20) | 咨询师ID | - |
|
||||
| `schedule_id` | bigint(20) | 预约时段ID | - |
|
||||
| `appointment_date` | date | 预约日期 | - |
|
||||
| `status` | char(1) | 状态(0待咨询 1已完成 2已取消 3未到访) | '0' |
|
||||
| `appointment_time` | varchar(20) | 预约时间段 | - |
|
||||
| `reason` | varchar(500) | 咨询原因 | NULL |
|
||||
| `consult_theme` | varchar(50) | 咨询主题 | NULL |
|
||||
|
||||
##### 未到访记录表 (xljk_consultation_no_show)
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| `student_id` | bigint(20) | 学生ID |
|
||||
| `appointment_id` | bigint(20) | 预约记录ID |
|
||||
| `no_show_date` | date | 未到访日期 |
|
||||
| `expire_date` | date | 限制到期日 |
|
||||
| `status` | char(1) | 状态(0生效中 1已过期 2已解除) |
|
||||
|
||||
#### 🎯 预约状态字典
|
||||
| 状态值 | 状态名称 | 说明 |
|
||||
|--------|----------|------|
|
||||
| `0` | 待咨询 | 已预约,等待咨询 |
|
||||
| `1` | 已完成 | 咨询已完成 |
|
||||
| `2` | 已取消 | 预约已取消 |
|
||||
| `3` | 未到访 | 预约时间已过,未到访 |
|
||||
|
||||
#### 🔄 心理咨询预约处理流程
|
||||
|
||||
##### 📋 处理逻辑说明
|
||||
- **预约取消**: 取消所有未来预约,状态改为"已取消"
|
||||
- **未到访处理**: 解除未到访限制,避免影响其他学生预约
|
||||
- **历史保留**: 保留已完成的咨询记录作为心理健康档案
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `XljkConsultationAppointment.java`
|
||||
**服务类**: `XljkConsultationAppointmentServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 心理咨询预约实体类关键字段
|
||||
@Data
|
||||
public class XljkConsultationAppointment {
|
||||
private Long id;
|
||||
private Long studentId;
|
||||
private Long counselorId;
|
||||
private Long scheduleId;
|
||||
private Date appointmentDate;
|
||||
private String status; // 状态:0-待咨询,1-已完成,2-已取消,3-未到访
|
||||
private String appointmentTime;
|
||||
private String reason;
|
||||
private String consultTheme;
|
||||
private Integer communicationDuration; // 沟通时长
|
||||
private String consultationContent; // 咨询内容
|
||||
private String counselorSuggestion; // 咨询师建议
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `xljk/consultation/appointment/index.vue`
|
||||
**状态显示**: 预约状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 预约状态列 -->
|
||||
<el-table-column label="预约状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === '0'" type="primary">待咨询</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '1'" type="success">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '2'" type="warning">已取消</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '3'" type="danger">未到访</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 预约日期列 -->
|
||||
<el-table-column label="预约日期" align="center" prop="appointmentDate" width="120">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.appointmentDate, '{y}-{m}-{d}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的心理咨询处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **休学**: 取消未来预约,保留历史咨询记录
|
||||
- **退学**: 取消未来预约,解除未到访限制
|
||||
- **毕业**: 取消未来预约,保留完整心理健康档案
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 1. 取消未来的心理咨询预约
|
||||
UPDATE xljk_consultation_appointment
|
||||
SET status = '2', -- 已取消
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND status = '0' -- 待咨询
|
||||
AND appointment_date >= CURDATE() -- 未来的预约
|
||||
AND deleted = 0;
|
||||
|
||||
-- 2. 处理未到访记录(解除限制)
|
||||
UPDATE xljk_consultation_no_show
|
||||
SET status = '2', -- 已解除
|
||||
expire_date = NOW(), -- 设置过期时间为当前时间
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND status = '0' -- 生效中
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
## 🎓 实践活动管理
|
||||
|
||||
### 3. 学生活动报名处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
|
||||
##### 活动报名表 (stgl_activity_registration)
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `id` | bigint(20) | 主键ID | - |
|
||||
| `activity_id` | bigint(20) | 活动ID | - |
|
||||
| `user_id` | bigint(20) | 用户ID | - |
|
||||
| `student_no` | varchar(50) | 学号 | - |
|
||||
| `student_name` | varchar(50) | 学生姓名 | - |
|
||||
| `registration_type` | varchar(10) | 报名类型(1个人 2团队) | - |
|
||||
| `team_id` | bigint(20) | 团队ID | NULL |
|
||||
| `registration_time` | datetime | 报名时间 | - |
|
||||
| `approval_status` | varchar(10) | 审核状态(0待审核 1通过 2驳回) | '0' |
|
||||
|
||||
**关键字段说明** (基于实体类代码分析):
|
||||
- `activityId`: 活动ID
|
||||
- `userId`: 用户ID
|
||||
- `studentNo`: 学号
|
||||
- `registrationType`: 报名类型(1个人 2团队)
|
||||
- `approvalStatus`: 审核状态(0待审核 1通过 2驳回)
|
||||
- `approvalTime`: 审核时间
|
||||
- `score`: 获得成绩
|
||||
| `approval_time` | datetime | 审核时间 | NULL |
|
||||
| `score` | varchar(20) | 获得成绩 | NULL |
|
||||
|
||||
#### 🎯 审核状态字典
|
||||
| 状态值 | 状态名称 | 说明 |
|
||||
|--------|----------|------|
|
||||
| `0` | 待审核 | 报名已提交,等待审核 |
|
||||
| `1` | 通过 | 审核通过,可以参加活动 |
|
||||
| `2` | 驳回 | 审核未通过 |
|
||||
|
||||
#### 🔄 学生活动报名处理流程
|
||||
|
||||
##### 📋 处理逻辑说明
|
||||
- **活动状态判断**: 需要关联活动表判断活动是否已开始或结束
|
||||
- **报名类型区分**: 个人报名和团队报名的处理逻辑不同
|
||||
- **成绩处理**: 已获得成绩的记录需要特殊处理
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `StglActivityRegistration.java`
|
||||
**服务类**: `StglActivityRegistrationServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 学生活动报名实体类关键字段
|
||||
@Data
|
||||
@TableName("stgl_activity_registration")
|
||||
public class StglActivityRegistration extends TenantEntity {
|
||||
private Long activityId; // 活动ID
|
||||
private Long userId; // 用户ID
|
||||
private String studentNo; // 学号
|
||||
private String studentName; // 学生姓名
|
||||
private String registrationType; // 报名类型:1-个人,2-团队
|
||||
private Long teamId; // 团队ID
|
||||
private Date registrationTime; // 报名时间
|
||||
private String approvalStatus; // 审核状态:0-待审核,1-通过,2-驳回
|
||||
private Date approvalTime; // 审核时间
|
||||
private Long approvalBy; // 审核人
|
||||
private String approvalRemark; // 审核意见
|
||||
private String score; // 获得成绩
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `stgl/activity/registration/index.vue`
|
||||
**状态显示**: 报名审核状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 审核状态列 -->
|
||||
<el-table-column label="审核状态" align="center" prop="approvalStatus" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.approvalStatus === '0'" type="warning">待审核</el-tag>
|
||||
<el-tag v-else-if="scope.row.approvalStatus === '1'" type="success">通过</el-tag>
|
||||
<el-tag v-else-if="scope.row.approvalStatus === '2'" type="danger">驳回</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 报名类型列 -->
|
||||
<el-table-column label="报名类型" align="center" prop="registrationType" width="100">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.registrationType === '1'">个人</span>
|
||||
<span v-else-if="scope.row.registrationType === '2'">团队</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的活动报名处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **休学**: 驳回未开始的活动报名,保留已完成活动的记录和成绩
|
||||
- **退学**: 驳回所有进行中的活动报名
|
||||
- **毕业**: 可选择保留已完成活动的记录和成绩,驳回进行中的报名
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_no: 学生学号
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 驳回进行中的活动报名
|
||||
UPDATE stgl_activity_registration
|
||||
SET approval_status = '2', -- 驳回状态
|
||||
approval_time = NOW(),
|
||||
approval_by = @operator_id,
|
||||
approval_remark = CONCAT('学生', @change_type, ',活动报名自动驳回'),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_no = @student_no
|
||||
AND approval_status = '1' -- 已通过的报名
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM stgl_activity a
|
||||
WHERE a.id = stgl_activity_registration.activity_id
|
||||
AND a.activity_start_time > NOW() -- 未开始的活动
|
||||
AND (@change_type = 'TUI_XUE' OR -- 退学:驳回所有进行中
|
||||
(@change_type IN ('XIU_XUE', 'BI_YE') AND a.activity_end_time > NOW())) -- 休学/毕业:只驳回未结束的
|
||||
)
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
### 4. 志愿者队伍管理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
**表名**: `stgl_volunteer_team` (队伍信息表)
|
||||
- 主要存储志愿者队伍的基本信息
|
||||
- 成员关系可能通过其他表关联或记录在日志中
|
||||
|
||||
#### 🔄 志愿者关系处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **队伍管理**: 志愿者队伍本身不因学生状态变更而改变
|
||||
- **成员关系**: 如果有专门的成员关系表,需要更新成员状态
|
||||
- **日志记录**: 记录志愿服务关系的变更情况
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_no: 学生学号
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 注意:stgl_volunteer_team表主要是队伍信息表
|
||||
-- 如果存在志愿者成员关系表,执行成员状态更新
|
||||
-- 这里以假设存在stgl_volunteer_member表为例
|
||||
|
||||
-- 如果存在志愿者成员关系表,执行:
|
||||
UPDATE stgl_volunteer_member
|
||||
SET member_status = 'INACTIVE',
|
||||
leave_time = NOW(),
|
||||
leave_reason = CONCAT('学生', @change_type),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_no = @student_no
|
||||
AND member_status = 'ACTIVE'
|
||||
AND deleted = 0;
|
||||
|
||||
-- 记录操作日志
|
||||
INSERT INTO sys_oper_log (
|
||||
title, business_type, method, request_method, operator_type,
|
||||
oper_name, dept_name, oper_url, oper_ip, oper_location,
|
||||
oper_param, json_result, status, error_msg, oper_time, cost_time
|
||||
) VALUES (
|
||||
'志愿者管理', 'OTHER', 'updateVolunteerStatus', 'UPDATE', 'MANAGE',
|
||||
'系统', '系统', '/volunteer/status/update', '127.0.0.1', '本地',
|
||||
CONCAT('学生', @student_no, '状态变更(', @change_type, '),志愿者关系处理'),
|
||||
'{}', 0, NULL, NOW(), 0
|
||||
);
|
||||
```
|
||||
|
||||
### 5. 实习信息终止处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
|
||||
##### 实习信息表 (zsjy_internship_info)
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `internship_id` | bigint(20) | 主键ID | - |
|
||||
| `student_id` | bigint(20) | 学生ID | - |
|
||||
| `student_no` | varchar(50) | 学号 | - |
|
||||
| `student_name` | varchar(100) | 学生姓名 | - |
|
||||
| `company_name` | varchar(200) | 实习单位名称 | - |
|
||||
| `position_name` | varchar(100) | 岗位名称 | - |
|
||||
| `start_date` | date | 实习开始日期 | - |
|
||||
| `end_date` | date | 实习结束日期 | - |
|
||||
| `actual_end_date` | date | 实际结束日期 | NULL |
|
||||
| `internship_status` | char(1) | 实习状态(1进行中 2已完成 3中断) | '1' |
|
||||
|
||||
**关键字段说明** (基于实体类代码分析):
|
||||
- `internshipId`: 实习ID
|
||||
- `studentId`: 学生ID
|
||||
- `studentNo`: 学号
|
||||
- `companyName`: 实习单位名称
|
||||
- `positionName`: 岗位名称
|
||||
- `startDate`: 实习开始日期
|
||||
- `endDate`: 实习结束日期
|
||||
- `actualEndDate`: 实际结束日期
|
||||
- `internshipStatus`: 实习状态(1进行中 2已完成 3中断)
|
||||
- `changeReason`: 变更原因
|
||||
| `internship_allowance` | decimal(10,2) | 实习津贴 | NULL |
|
||||
|
||||
#### 🎯 实习状态字典
|
||||
| 状态值 | 状态名称 | 说明 |
|
||||
|--------|----------|------|
|
||||
| `1` | 进行中 | 实习正在进行 |
|
||||
| `2` | 已完成 | 实习已按期完成 |
|
||||
| `3` | 中断 | 实习因故中断 |
|
||||
|
||||
#### 🔄 实习信息终止处理流程
|
||||
|
||||
##### 📋 处理逻辑说明
|
||||
- **状态判断**: 需要根据当前实习状态和学生变更类型决定处理方式
|
||||
- **时间管理**: 正确设置实际结束日期
|
||||
- **关联数据**: 实习相关的日报、月报、访问记录等会自动停止更新
|
||||
- **津贴结算**: 可能涉及实习津贴的结算处理
|
||||
|
||||
##### 💻 后端实现逻辑
|
||||
**实体类**: `ZsjyInternshipInfo.java`
|
||||
**服务类**: `ZsjyInternshipServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 实习信息实体类关键字段
|
||||
@Data
|
||||
@TableName("zsjy_internship_info")
|
||||
public class ZsjyInternshipInfo extends BaseEntity {
|
||||
private Long internshipId; // 实习ID
|
||||
private Long previousInternshipId; // 前一条实习记录ID
|
||||
private Long studentId; // 学生ID
|
||||
private String studentNo; // 学号
|
||||
private String studentName; // 学生姓名
|
||||
private String companyName; // 实习单位名称
|
||||
private String positionName; // 岗位名称
|
||||
private BigDecimal internshipAllowance; // 实习津贴
|
||||
private Date startDate; // 实习开始日期
|
||||
private Date endDate; // 实习结束日期
|
||||
private Date actualEndDate; // 实际结束日期
|
||||
private String internshipStatus; // 实习状态:1-进行中,2-已完成,3-中断
|
||||
private String changeReason; // 变更原因
|
||||
}
|
||||
```
|
||||
|
||||
##### 🎨 前端界面展示
|
||||
**管理界面**: `zsjy/internship/info/index.vue`
|
||||
**状态显示**: 实习状态的展示
|
||||
|
||||
```vue
|
||||
<!-- 实习状态列 -->
|
||||
<el-table-column label="实习状态" align="center" prop="internshipStatus" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.internshipStatus === '1'" type="primary">进行中</el-tag>
|
||||
<el-tag v-else-if="scope.row.internshipStatus === '2'" type="success">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.internshipStatus === '3'" type="warning">已中断</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 实习单位列 -->
|
||||
<el-table-column label="实习单位" align="center" prop="companyName" width="200" show-overflow-tooltip />
|
||||
|
||||
<!-- 实习时间列 -->
|
||||
<el-table-column label="实习时间" align="center" width="200">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }} 至
|
||||
{{ parseTime(scope.row.actualEndDate || scope.row.endDate, '{y}-{m}-{d}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
#### 🔄 学生状态变更时的实习信息处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **休学**: 设置为"中断"状态,保留重新实习的可能
|
||||
- **退学**: 设置为"中断"状态,终止实习关系
|
||||
- **毕业**: 如果实习已完成保持"已完成",否则设为"中断"
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 终止进行中的实习
|
||||
UPDATE zsjy_internship_info
|
||||
SET internship_status = CASE
|
||||
WHEN @change_type = 'BI_YE' AND internship_status = '2' THEN '2' -- 毕业:保持已完成状态
|
||||
ELSE '3' -- 休学/退学:设为中断
|
||||
END,
|
||||
actual_end_date = CASE
|
||||
WHEN @change_type IN ('XIU_XUE', 'TUI_XUE') THEN CURDATE()
|
||||
WHEN @change_type = 'BI_YE' AND internship_status != '2' THEN CURDATE()
|
||||
ELSE actual_end_date
|
||||
END,
|
||||
change_reason = CONCAT(COALESCE(change_reason, ''), ' | 学生', @change_type,
|
||||
CASE WHEN @change_type = 'BI_YE' AND internship_status = '2' THEN ',实习正常完成'
|
||||
ELSE ',实习中断' END),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND internship_status IN ('1', '2') -- 进行中或已完成的实习
|
||||
AND deleted = 0;
|
||||
|
||||
-- 注意:实习结束后,相关的日报、月报、统计、访问记录等数据会自动停止更新
|
||||
-- 如需清理历史数据,可根据业务需求另行处理
|
||||
```
|
||||
|
||||
## 📝 其他关联信息处理
|
||||
|
||||
### 6. 学生请假记录处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
|
||||
##### 请假记录表 (xg_student_leave)
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `id` | bigint(20) | 主键ID | - |
|
||||
| `student_id` | bigint(20) | 学生ID | - |
|
||||
| `leave_type` | varchar(20) | 请假类型 | - |
|
||||
| `leave_reason` | text | 请假原因 | - |
|
||||
| `leave_start_date` | date | 请假开始日期 | - |
|
||||
| `leave_end_date` | date | 请假结束日期 | - |
|
||||
| `leave_status` | varchar(20) | 请假状态 | - |
|
||||
| `cancel_reason` | varchar(500) | 取消原因 | NULL |
|
||||
|
||||
##### 销假记录表 (xg_student_cancel_leave)
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| `id` | bigint(20) | 主键ID |
|
||||
| `student_id` | bigint(20) | 学生ID |
|
||||
| `cancel_status` | varchar(20) | 销假状态 |
|
||||
|
||||
#### 🔄 请假记录处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **进行中请假**: 取消未结束的请假记录
|
||||
- **销假处理**: 更新相应的销假状态
|
||||
- **历史保留**: 保留已完成的请假记录
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 处理进行中的请假记录
|
||||
UPDATE xg_student_leave
|
||||
SET leave_status = 'CANCELLED', -- 取消状态
|
||||
cancel_reason = CONCAT('学生', @change_type, ',请假自动取消'),
|
||||
cancel_time = NOW(),
|
||||
cancel_by = @operator_id,
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND leave_status IN ('PENDING', 'APPROVED') -- 待审核、已通过
|
||||
AND leave_end_date >= CURDATE() -- 未结束的请假
|
||||
AND deleted = 0;
|
||||
|
||||
-- 处理相应的销假记录
|
||||
UPDATE xg_student_cancel_leave
|
||||
SET cancel_status = 'AUTO_CANCELLED',
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND cancel_status = 'PENDING'
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
### 7. 宿舍卫生检查处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
|
||||
##### 卫生检查学生评分表 (xg_dorm_hygiene_student_score)
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `id` | bigint(20) | 主键ID | - |
|
||||
| `student_id` | bigint(20) | 学生ID | - |
|
||||
| `check_id` | bigint(20) | 检查ID | - |
|
||||
| `check_date` | date | 检查日期 | - |
|
||||
| `score` | decimal(5,2) | 得分 | - |
|
||||
| `remark` | varchar(500) | 备注 | NULL |
|
||||
|
||||
#### 🔄 卫生检查处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **历史数据保留**: 卫生检查记录作为重要档案,通常不删除
|
||||
- **未来检查备注**: 为未来的卫生检查记录添加状态变更备注
|
||||
- **评分数据完整性**: 确保持有评分数据的完整性
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 为未来的卫生检查记录添加备注
|
||||
UPDATE xg_dorm_hygiene_student_score
|
||||
SET remark = CONCAT(COALESCE(remark, ''), ' | 学生', @change_type, ',卫生检查记录'),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND check_date >= CURDATE() -- 未来的检查
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
### 8. 宿舍违纪记录处理
|
||||
|
||||
#### 📊 数据库表结构
|
||||
|
||||
##### 宿舍违纪表 (xg_dorm_violation)
|
||||
| 字段名 | 类型 | 说明 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `id` | bigint(20) | 主键ID | - |
|
||||
| `student_id` | bigint(20) | 学生ID | - |
|
||||
| `violation_type` | varchar(50) | 违纪类型 | - |
|
||||
| `violation_date` | date | 违纪日期 | - |
|
||||
| `violation_description` | text | 违纪描述 | - |
|
||||
| `punishment` | varchar(200) | 处罚措施 | - |
|
||||
| `remark` | varchar(500) | 备注 | NULL |
|
||||
|
||||
#### 🔄 违纪记录处理逻辑
|
||||
|
||||
##### 📋 处理策略说明
|
||||
- **档案数据保留**: 违纪记录作为学生管理档案,必须永久保留
|
||||
- **状态变更备注**: 添加状态变更信息,便于档案管理
|
||||
- **历史追溯**: 确保违纪记录的完整性和可追溯性
|
||||
|
||||
##### 💾 SQL批量处理脚本
|
||||
```sql
|
||||
-- 参数说明:
|
||||
-- @student_id: 学生ID
|
||||
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
|
||||
-- @operator_id: 操作员ID
|
||||
|
||||
-- 为违纪记录添加状态变更备注
|
||||
UPDATE xg_dorm_violation
|
||||
SET remark = CONCAT(COALESCE(remark, ''), ' | 学生', @change_type, ',违纪记录归档'),
|
||||
update_by = @operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = @student_id
|
||||
AND deleted = 0;
|
||||
```
|
||||
|
||||
## 🔗 其他业务模块关联处理
|
||||
|
||||
### 1. 业务数据一致性保证
|
||||
|
||||
#### 🛡️ 事务处理要求
|
||||
```sql
|
||||
-- 建议在学生状态变更的大事务中包含所有其他业务处理
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. 更新学生学籍状态
|
||||
UPDATE xg_student_msg SET student_status = ? WHERE id = ?;
|
||||
|
||||
-- 2. 处理宿舍退宿
|
||||
UPDATE xg_dorm_bed_student SET status = '1' WHERE student_id = ?;
|
||||
|
||||
-- 3. 处理心理咨询预约
|
||||
UPDATE xljk_consultation_appointment SET status = '2' WHERE student_id = ?;
|
||||
|
||||
-- 4. 处理学生活动报名
|
||||
UPDATE stgl_activity_registration SET approval_status = '2' WHERE student_no = ?;
|
||||
|
||||
-- 5. 处理实习信息
|
||||
UPDATE zsjy_internship_info SET internship_status = '3' WHERE student_id = ?;
|
||||
|
||||
-- 6. 处理其他关联信息
|
||||
UPDATE xg_student_leave SET leave_status = 'CANCELLED' WHERE student_id = ?;
|
||||
|
||||
COMMIT;
|
||||
```
|
||||
|
||||
#### 📊 处理统计表
|
||||
|
||||
| 业务模块 | 涉及表数量 | 处理类型 | 重要程度 |
|
||||
|----------|------------|----------|----------|
|
||||
| 宿舍管理 | 2 (床位+申请) | 退宿处理 | ⭐⭐⭐⭐⭐ |
|
||||
| 心理健康 | 2 (预约+未到访) | 预约取消 | ⭐⭐⭐⭐ |
|
||||
| 实践活动 | 1 (报名表) | 报名驳回 | ⭐⭐⭐⭐ |
|
||||
| 实习管理 | 1 (实习表) | 状态中断 | ⭐⭐⭐⭐ |
|
||||
| 请假管理 | 2 (请假+销假) | 请假取消 | ⭐⭐⭐⭐ |
|
||||
| 卫生检查 | 1 (评分表) | 备注添加 | ⭐⭐⭐ |
|
||||
| 违纪记录 | 1 (违纪表) | 备注添加 | ⭐⭐⭐ |
|
||||
| **总计** | **11个表** | **状态更新+关系清理** | **⭐⭐⭐⭐⭐** |
|
||||
|
||||
### 2. 业务规则和约束
|
||||
|
||||
#### 📋 状态变更处理矩阵
|
||||
|
||||
| 当前状态 | 休学处理 | 退学处理 | 毕业处理 |
|
||||
|----------|----------|----------|----------|
|
||||
| 宿舍在住 | 可保留/退宿 | 必须退宿 | 必须退宿 |
|
||||
| 咨询预约 | 取消未来预约 | 取消未来预约 | 取消未来预约 |
|
||||
| 活动报名 | 驳回未结束活动 | 驳回进行中活动 | 保留已完成活动 |
|
||||
| 实习进行 | 中断(可恢复) | 中断(终止) | 保持完成状态 |
|
||||
| 请假进行 | 取消请假 | 取消请假 | 取消请假 |
|
||||
|
||||
#### ⚠️ 重要业务约束
|
||||
- **宿舍资源**: 退学/毕业必须释放宿舍资源,保证公平分配
|
||||
- **活动公平性**: 学生状态变更后不应继续参加学校组织的活动
|
||||
- **实习规范**: 实习中断需记录原因,便于管理和追溯
|
||||
- **档案完整性**: 所有历史记录必须保留,作为学生管理档案
|
||||
- **数据一致性**: 各业务模块的状态必须与学生学籍状态保持一致
|
||||
|
||||
### 3. 监控和审计要求
|
||||
|
||||
#### 📊 数据完整性检查
|
||||
```sql
|
||||
-- 检查其他业务处理结果的完整性
|
||||
SELECT
|
||||
'宿舍管理' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN status = '1' THEN 1 END) as processed_count
|
||||
FROM xg_dorm_bed_student
|
||||
WHERE student_id = @student_id
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'心理咨询' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN status = '2' THEN 1 END) as processed_count
|
||||
FROM xljk_consultation_appointment
|
||||
WHERE student_id = @student_id AND appointment_date >= CURDATE()
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'活动报名' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN approval_status = '2' THEN 1 END) as processed_count
|
||||
FROM stgl_activity_registration
|
||||
WHERE student_no = @student_no
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'实习信息' as module,
|
||||
COUNT(*) as total_count,
|
||||
COUNT(CASE WHEN internship_status = '3' THEN 1 END) as processed_count
|
||||
FROM zsjy_internship_info
|
||||
WHERE student_id = @student_id AND internship_status IN ('1', '2');
|
||||
```
|
||||
|
||||
#### 📝 审计日志记录
|
||||
```sql
|
||||
-- 记录其他业务处理的审计日志
|
||||
INSERT INTO sys_oper_log (
|
||||
title, business_type, method, request_method, operator_type,
|
||||
oper_name, dept_name, oper_url, oper_ip, oper_location,
|
||||
oper_param, json_result, status, error_msg, oper_time
|
||||
) VALUES (
|
||||
'其他业务处理', 'UPDATE', 'processOtherBusiness', 'PROCEDURE', 'MANAGE',
|
||||
@operator_name, @dept_name, '/other/business/process', @client_ip, @location,
|
||||
CONCAT('学生ID:', @student_id, ',学号:', @student_no, ',变更类型:', @change_type),
|
||||
@process_result_json, 0, NULL, NOW()
|
||||
);
|
||||
-- 4. 释放床位资源
|
||||
UPDATE xg_dorm_bed SET bed_status = '0'
|
||||
WHERE id IN (
|
||||
SELECT bed_id FROM xg_dorm_bed_student
|
||||
WHERE student_id = @student_id AND status = '1' AND deleted = '0'
|
||||
) AND deleted = '0';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 更新记录
|
||||
|
||||
- **2025-12-XX**: 分文档创建,包含其他业务处理逻辑
|
||||
- **2025-12-XX**: 基于代码分析完善技术实现细节和业务逻辑
|
||||
- **后续更新**: 根据实际业务需求持续完善
|
||||
|
||||
---
|
||||
|
||||
*本分文档详细说明学生状态变更时的其他业务模块处理逻辑和技术实现,包括宿舍、心理、实践、实习等各项业务的完整处理方案。*
|
||||
- **2025-12-XX**: 根据用户需求简化其他业务处理,删除心理健康、学生活动、实习等非核心业务
|
||||
- **后续更新**: 如需要其他业务处理,可根据实际业务需求重新添加
|
||||
+14
-93
@@ -111,21 +111,30 @@ BEGIN
|
||||
v_effective_date, p_operator_id, 'system', 1
|
||||
);
|
||||
|
||||
-- 4. 更新学生学籍状态
|
||||
-- 4. 备份原始数据到his表
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = p_student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = p_student_id;
|
||||
|
||||
-- 5. 更新学生学籍状态
|
||||
UPDATE xg_student_msg
|
||||
SET student_status = v_new_student_status,
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE id = p_student_id AND deleted = 0;
|
||||
|
||||
-- 5. 处理用户账号状态
|
||||
-- 6. 处理用户账号状态
|
||||
IF v_disable_user_account THEN
|
||||
UPDATE sys_user
|
||||
SET status = '1',
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time,
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | ', v_exit_reason, '-', v_current_time)
|
||||
WHERE user_name = p_student_no AND account_type = '2' AND del_flag = '0';
|
||||
update_time = v_current_time
|
||||
WHERE user_id = p_student_id AND account_type = '2' AND del_flag = '0';
|
||||
ELSE
|
||||
UPDATE sys_user
|
||||
SET status = '0',
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE user_id = p_student_id AND account_type = '2' AND del_flag = '0';
|
||||
END IF;
|
||||
|
||||
-- 6. 处理班级干部信息(休学、退学、毕业)
|
||||
@@ -156,59 +165,6 @@ BEGIN
|
||||
WHERE user_id = p_student_id AND status IN (0, 1, 2) AND deleted = 0;
|
||||
END IF;
|
||||
|
||||
-- 8. 处理经济资助 - 奖学金申请
|
||||
IF p_change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE') THEN
|
||||
UPDATE jcbt_scholarship_application
|
||||
SET current_status = CASE
|
||||
WHEN p_change_type = 'XIU_XUE' THEN 'WITHDRAWN' -- 休学:撤回
|
||||
WHEN p_change_type = 'TUI_XUE' THEN 'REJECTED' -- 退学:拒绝
|
||||
WHEN p_change_type = 'BI_YE' THEN
|
||||
CASE WHEN current_status = 'APPROVED' THEN 'APPROVED' -- 毕业:保持已通过
|
||||
ELSE 'WITHDRAWN' -- 其他状态撤回
|
||||
END
|
||||
ELSE current_status
|
||||
END,
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE student_id = p_student_id AND current_status NOT IN ('REJECTED') AND deleted = 0;
|
||||
END IF;
|
||||
|
||||
-- 9. 处理经济资助 - 勤工俭学申请
|
||||
IF p_change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE') THEN
|
||||
UPDATE jcbt_work_study_application
|
||||
SET status = 'CANCELLED',
|
||||
college_review_status = CASE
|
||||
WHEN college_review_status IS NOT NULL THEN 'REJECTED'
|
||||
ELSE college_review_status
|
||||
END,
|
||||
final_review_status = CASE
|
||||
WHEN final_review_status IS NOT NULL THEN 'REJECTED'
|
||||
ELSE final_review_status
|
||||
END,
|
||||
final_review_time = v_current_time,
|
||||
final_reviewer_id = p_operator_id,
|
||||
final_reviewer_name = '系统',
|
||||
final_review_comment = CONCAT(v_exit_reason, ',岗位申请自动终止'),
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE student_id = p_student_id
|
||||
AND status NOT IN ('CANCELLED', 'COLLEGE_REJECTED', 'FINAL_REJECTED')
|
||||
AND deleted = 0;
|
||||
END IF;
|
||||
|
||||
-- 10. 处理经济资助 - 贫困生认定
|
||||
IF p_change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE') THEN
|
||||
UPDATE jcbt_poverty_application
|
||||
SET application_status = CASE
|
||||
WHEN application_status = 'approved' THEN 'revoked' -- 撤销已通过的认定
|
||||
ELSE application_status
|
||||
END,
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE student_id = p_student_id
|
||||
AND application_status NOT IN ('cancel', 'invalid')
|
||||
AND deleted = 0;
|
||||
END IF;
|
||||
|
||||
-- 11. 处理宿舍住宿关系(退学、毕业)
|
||||
IF p_change_type IN ('TUI_XUE', 'BI_YE') THEN
|
||||
@@ -221,41 +177,6 @@ BEGIN
|
||||
WHERE student_id = p_student_id AND status = '0' AND deleted = '0';
|
||||
END IF;
|
||||
|
||||
-- 12. 取消心理咨询预约(休学、退学、毕业)
|
||||
IF p_change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE') THEN
|
||||
UPDATE xljk_consultation_appointment
|
||||
SET status = '2',
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE student_id = p_student_id AND status = '0'
|
||||
AND appointment_date >= CURDATE() AND deleted = 0;
|
||||
END IF;
|
||||
|
||||
-- 13. 取消学生活动报名(退学、毕业)
|
||||
IF p_change_type IN ('TUI_XUE', 'BI_YE') THEN
|
||||
UPDATE stgl_activity_registration
|
||||
SET approval_status = '3',
|
||||
approval_time = v_current_time,
|
||||
approval_by = p_operator_id,
|
||||
approval_remark = CONCAT(v_exit_reason, ',活动报名自动取消'),
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time
|
||||
WHERE student_no = p_student_no AND approval_status = '1'
|
||||
AND EXISTS (SELECT 1 FROM stgl_activity a
|
||||
WHERE a.id = stgl_activity_registration.activity_id
|
||||
AND a.activity_start_time > v_current_time);
|
||||
END IF;
|
||||
|
||||
-- 14. 终止实习(退学)
|
||||
IF p_change_type = 'TUI_XUE' THEN
|
||||
UPDATE zsjy_internship_info
|
||||
SET internship_status = '3',
|
||||
actual_end_date = CURDATE(),
|
||||
update_by = p_operator_id,
|
||||
update_time = v_current_time,
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 学生退学,实习中断')
|
||||
WHERE student_id = p_student_id AND internship_status = '1' AND deleted = 0;
|
||||
END IF;
|
||||
|
||||
-- 提交事务
|
||||
COMMIT;
|
||||
|
||||
+89
-17
@@ -9,54 +9,102 @@
|
||||
### 休学处理快速脚本
|
||||
|
||||
```sql
|
||||
-- 休学处理:保留账号,暂停业务
|
||||
-- 休学处理:禁用账号,暂停组织关系
|
||||
SET @student_id = 123456789;
|
||||
SET @student_no = '20240001';
|
||||
SET @operator_id = 1;
|
||||
|
||||
-- 备份原始数据
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = @student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = @student_id;
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = @student_id;
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = @student_id;
|
||||
|
||||
-- 更新核心状态
|
||||
UPDATE xg_student_msg SET student_status = '2', update_by = @operator_id, update_time = NOW() WHERE id = @student_id;
|
||||
UPDATE sys_user SET status = '1' WHERE user_id = @student_id AND account_type = '2';
|
||||
|
||||
-- 处理组织关系
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = '6', dismissal_date = CURDATE(), dismissal_reason = '学生休学' WHERE student_id = @student_id AND is_current = 1;
|
||||
UPDATE club_member SET member_status = '4' WHERE user_id = @student_id AND member_status IN ('0', '1', '2');
|
||||
UPDATE jcbt_scholarship_application SET current_status = 'WITHDRAWN' WHERE student_id = @student_id AND current_status IN ('PENDING', 'APPROVED');
|
||||
UPDATE jcbt_work_study_application SET status = 'CANCELLED' WHERE student_id = @student_id AND status NOT IN ('CANCELLED', 'COLLEGE_REJECTED', 'FINAL_REJECTED');
|
||||
UPDATE xljk_consultation_appointment SET status = '2' WHERE student_id = @student_id AND status = '0' AND appointment_date >= CURDATE();
|
||||
UPDATE stgl_activity_registration SET approval_status = 2 WHERE student_no = @student_no AND approval_status = 1;
|
||||
UPDATE zsjy_internship_info SET internship_status = '3', actual_end_date = CURDATE() WHERE student_id = @student_id AND internship_status = '1';
|
||||
UPDATE stgl_member SET status = 4 WHERE user_id = @student_id AND status IN (0, 1, 2);
|
||||
```
|
||||
|
||||
### 退学处理快速脚本
|
||||
|
||||
```sql
|
||||
-- 退学处理:禁用账号,终止所有业务
|
||||
-- 退学处理:禁用账号,终止组织关系和住宿
|
||||
SET @student_id = 123456789;
|
||||
SET @student_no = '20240001';
|
||||
SET @operator_id = 1;
|
||||
|
||||
-- 备份原始数据
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = @student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = @student_id;
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = @student_id;
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = @student_id;
|
||||
INSERT INTO xg_dorm_bed_student_his SELECT * FROM xg_dorm_bed_student WHERE student_id = @student_id;
|
||||
|
||||
-- 更新核心状态
|
||||
UPDATE xg_student_msg SET student_status = '4', update_by = @operator_id, update_time = NOW() WHERE id = @student_id;
|
||||
UPDATE sys_user SET status = '1' WHERE user_name = @student_no AND account_type = '2';
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = '4', dismissal_date = CURDATE() WHERE student_id = @student_id AND is_current = 1;
|
||||
UPDATE sys_user SET status = '1' WHERE user_id = @student_id AND account_type = '2';
|
||||
|
||||
-- 处理组织关系
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = '4', dismissal_date = CURDATE(), dismissal_reason = '学生退学' WHERE student_id = @student_id AND is_current = 1;
|
||||
UPDATE club_member SET member_status = '4' WHERE user_id = @student_id AND member_status IN ('0', '1', '2');
|
||||
UPDATE jcbt_scholarship_application SET current_status = 'WITHDRAWN' WHERE student_id = @student_id AND current_status IN ('PENDING', 'APPROVED');
|
||||
UPDATE jcbt_work_study_application SET status = 'CANCELLED' WHERE student_id = @student_id AND status NOT IN ('CANCELLED', 'COLLEGE_REJECTED', 'FINAL_REJECTED');
|
||||
UPDATE stgl_member SET status = 4 WHERE user_id = @student_id AND status IN (0, 1, 2);
|
||||
|
||||
-- 处理住宿关系
|
||||
UPDATE xg_student_msg SET dormitory_building = NULL, dormitory_room = NULL, ext_field1 = NULL, update_time = NOW(), update_by = @operator_id WHERE id = @student_id;
|
||||
UPDATE xg_dorm_bed_student SET status = '1', checkout_time = NOW() WHERE student_id = @student_id AND status = '0';
|
||||
UPDATE xljk_consultation_appointment SET status = '2' WHERE student_id = @student_id AND status = '0' AND appointment_date >= CURDATE();
|
||||
UPDATE stgl_activity_registration SET approval_status = 2 WHERE student_no = @student_no AND approval_status = 1;
|
||||
UPDATE zsjy_internship_info SET internship_status = '3', actual_end_date = CURDATE() WHERE student_id = @student_id AND internship_status = '1';
|
||||
UPDATE xg_dorm_bed SET bed_status = '0' WHERE id IN (SELECT bed_id FROM xg_dorm_bed_student WHERE student_id = @student_id AND status = '1');
|
||||
```
|
||||
|
||||
### 毕业处理快速脚本
|
||||
|
||||
```sql
|
||||
-- 毕业处理:归档所有业务
|
||||
-- 毕业处理:禁用账号,终止组织关系和住宿
|
||||
SET @student_id = 123456789;
|
||||
SET @student_no = '20240001';
|
||||
SET @operator_id = 1;
|
||||
|
||||
-- 备份原始数据
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = @student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = @student_id;
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = @student_id;
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = @student_id;
|
||||
INSERT INTO xg_dorm_bed_student_his SELECT * FROM xg_dorm_bed_student WHERE student_id = @student_id;
|
||||
|
||||
-- 更新核心状态
|
||||
UPDATE xg_student_msg SET student_status = '5', update_by = @operator_id, update_time = NOW() WHERE id = @student_id;
|
||||
UPDATE sys_user SET status = '1' WHERE user_name = @student_no AND account_type = '2';
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = '4', dismissal_date = CURDATE() WHERE student_id = @student_id AND is_current = 1;
|
||||
UPDATE sys_user SET status = '1' WHERE user_id = @student_id AND account_type = '2';
|
||||
|
||||
-- 处理组织关系
|
||||
UPDATE xg_class_pos_msg SET is_current = 0, cadre_status = '4', dismissal_date = CURDATE(), dismissal_reason = '学生毕业' WHERE student_id = @student_id AND is_current = 1;
|
||||
UPDATE club_member SET member_status = '4' WHERE user_id = @student_id AND member_status IN ('0', '1', '2');
|
||||
UPDATE stgl_member SET status = 4 WHERE user_id = @student_id AND status IN (0, 1, 2);
|
||||
|
||||
-- 处理住宿关系
|
||||
UPDATE xg_student_msg SET dormitory_building = NULL, dormitory_room = NULL, ext_field1 = NULL, update_time = NOW(), update_by = @operator_id WHERE id = @student_id;
|
||||
UPDATE xg_dorm_bed_student SET status = '1', checkout_time = NOW() WHERE student_id = @student_id AND status = '0';
|
||||
UPDATE xg_dorm_bed SET bed_status = '0' WHERE id IN (SELECT bed_id FROM xg_dorm_bed_student WHERE student_id = @student_id AND status = '1');
|
||||
```
|
||||
|
||||
### 复学处理快速脚本
|
||||
|
||||
```sql
|
||||
-- 复学处理:启用账号,恢复学籍状态
|
||||
SET @student_id = 123456789;
|
||||
SET @student_no = '20240001';
|
||||
SET @operator_id = 1;
|
||||
|
||||
-- 备份原始数据
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = @student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = @student_id;
|
||||
|
||||
-- 更新核心状态
|
||||
UPDATE xg_student_msg SET student_status = '3', update_by = @operator_id, update_time = NOW() WHERE id = @student_id;
|
||||
UPDATE sys_user SET status = '0' WHERE user_id = @student_id AND account_type = '2';
|
||||
```
|
||||
|
||||
## 🔧 批量处理脚本
|
||||
@@ -77,6 +125,12 @@ CREATE TEMPORARY TABLE student_leave_batch (
|
||||
-- 插入待处理的學生信息
|
||||
-- INSERT INTO student_leave_batch (student_id, student_no) VALUES (123, '20240001'), (456, '20240002');
|
||||
|
||||
-- 批量备份原始数据
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id IN (SELECT student_id FROM student_leave_batch);
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id IN (SELECT student_id FROM student_leave_batch);
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id IN (SELECT student_id FROM student_leave_batch);
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id IN (SELECT student_id FROM student_leave_batch);
|
||||
|
||||
-- 批量更新学生状态
|
||||
UPDATE xg_student_msg
|
||||
SET student_status = '2',
|
||||
@@ -85,6 +139,15 @@ SET student_status = '2',
|
||||
WHERE id IN (SELECT student_id FROM student_leave_batch)
|
||||
AND deleted = 0;
|
||||
|
||||
-- 批量禁用用户账号
|
||||
UPDATE sys_user
|
||||
SET status = '1',
|
||||
update_by = 1,
|
||||
update_time = NOW()
|
||||
WHERE user_id IN (SELECT student_id FROM student_leave_batch)
|
||||
AND account_type = '2'
|
||||
AND del_flag = '0';
|
||||
|
||||
-- 批量处理班级干部
|
||||
UPDATE xg_class_pos_msg
|
||||
SET is_current = 0,
|
||||
@@ -106,6 +169,15 @@ WHERE user_id IN (SELECT student_id FROM student_leave_batch)
|
||||
AND member_status IN ('0', '1', '2')
|
||||
AND deleted = 0;
|
||||
|
||||
-- 批量处理志愿者成员
|
||||
UPDATE stgl_member
|
||||
SET status = 4,
|
||||
update_by = 1,
|
||||
update_time = NOW()
|
||||
WHERE user_id IN (SELECT student_id FROM student_leave_batch)
|
||||
AND status IN (0, 1, 2)
|
||||
AND deleted = 0;
|
||||
|
||||
-- 批量处理奖学金申请
|
||||
UPDATE jcbt_scholarship_application
|
||||
SET current_status = 'WITHDRAWN',
|
||||
|
||||
+293
-49
@@ -1,71 +1,315 @@
|
||||
# 学生退学、休学、毕业处理文档
|
||||
# 学生状态变更处理脚本
|
||||
|
||||
## 📋 文档概述
|
||||
本项目包含用于处理学生退学、休学、复学、毕业状态变更的自动化脚本。
|
||||
|
||||
本目录包含完整的学生退学、休学、毕业处理文档体系,采用模块化组织方式,便于查阅和维护。
|
||||
## 📋 脚本说明
|
||||
|
||||
## 📚 文档结构
|
||||
### 脚本文件
|
||||
|
||||
### 📋 主文档
|
||||
- **[学生退学休学毕业处理清单.md](学生退学休学毕业处理清单.md)** - 总览文档,包含处理流程概览和各分文档导航
|
||||
1. **`process_student_changes.sh`** - 处理毕业、退学、休学的状态变更
|
||||
2. **`process_student_resume.sh`** - 处理复学的状态变更
|
||||
3. **`control_scripts.sh`** - 脚本控制程序(启动、停止、重启)
|
||||
4. **`start_services.sh`** - 一键启动所有服务
|
||||
5. **`stop_services.sh`** - 一键停止所有服务
|
||||
6. **`health_check.sh`** - 服务健康检查脚本
|
||||
7. **`data.conf`** - 数据库配置文件
|
||||
8. **`test_data.sql`** - 测试数据脚本
|
||||
9. **`optional_crontab_config.txt`** - 可选的定时任务配置(备用)
|
||||
10. **`demo.sh`** - 脚本使用演示
|
||||
|
||||
### 📋 分文档
|
||||
### 处理逻辑
|
||||
|
||||
#### 核心处理文档
|
||||
- **[01-核心状态修改.md](01-核心状态修改.md)** - 学生学籍状态、用户登录状态
|
||||
- **[02-组织关系处理.md](02-组织关系处理.md)** - 班级干部信息、社团成员关系
|
||||
- **[03-经济资助处理.md](03-经济资助处理.md)** - 奖学金申请、获奖记录、勤工俭学、贫困生认定
|
||||
- **[04-其他业务处理.md](04-其他业务处理.md)** - 住宿管理、心理健康、学生活动、志愿者、实习等
|
||||
#### 毕业/退学/休学处理 (`process_student_changes.sh`)
|
||||
处理类型:`XIU_XUE`(休学), `TUI_XUE`(退学), `BI_YE`(毕业)
|
||||
|
||||
#### 实施文档
|
||||
- **[06-完整SQL脚本.md](06-完整SQL脚本.md)** - 完整的数据库处理脚本和事务管理
|
||||
- **[07-快速执行脚本.md](07-快速执行脚本.md)** - 快速执行的简化脚本和批量处理
|
||||
**执行步骤:**
|
||||
1. 备份原始数据到his表
|
||||
2. 更新学生学籍状态
|
||||
3. 禁用用户账号
|
||||
4. 处理班级干部关系(取消现任职务)
|
||||
5. 处理社团成员关系(设置为已退出)
|
||||
6. 处理住宿关系(退学/毕业时退宿)
|
||||
7. 更新变更记录状态为已处理
|
||||
|
||||
### 🗃️ 数据文件
|
||||
- **dict字典.sql** - 字典数据
|
||||
- **hzdyjs_xg.sql** - 数据库结构和基础数据
|
||||
- **xg_student_status_change.sql** - 学生状态变更相关SQL
|
||||
#### 复学处理 (`process_student_resume.sh`)
|
||||
处理类型:`FU_XUE`(复学)
|
||||
|
||||
## 🎯 处理流程
|
||||
**执行步骤:**
|
||||
1. 备份原始数据到his表
|
||||
2. 更新学生学籍状态为复学
|
||||
3. 启用用户账号
|
||||
4. 更新变更记录状态为已处理
|
||||
|
||||
```
|
||||
1. 阅读主文档了解概览 → 学生退学休学毕业处理清单.md
|
||||
2. 根据业务模块查阅分文档 → 01-04各业务模块文档
|
||||
3. 选择合适的实施方式 → 06完整脚本 或 07快速脚本
|
||||
4. 执行处理并验证结果
|
||||
## 🔧 配置说明
|
||||
|
||||
### data.conf 配置
|
||||
|
||||
```bash
|
||||
# Database configuration
|
||||
DB_HOST="localhost" # 数据库主机
|
||||
DB_PORT="3306" # 数据库端口
|
||||
DB_NAME="hzdyjs_xg" # 数据库名
|
||||
DB_USER="root" # 数据库用户名
|
||||
DB_PASS="password" # 数据库密码
|
||||
|
||||
# Script configuration
|
||||
LOG_DIR="/var/log/student_status_change" # 日志目录
|
||||
SCRIPT_DIR="/path/to/scripts" # 脚本目录
|
||||
LOCK_FILE="${SCRIPT_DIR}/script.lock" # 锁文件
|
||||
|
||||
# Processing configuration
|
||||
BATCH_SIZE=100 # 每次处理记录数
|
||||
MAX_RETRY=3 # 最大重试次数
|
||||
RETRY_DELAY=5 # 重试间隔(秒)
|
||||
CYCLE_INTERVAL=600 # 循环间隔时间(秒),默认10分钟
|
||||
```
|
||||
|
||||
## ⚠️ 重要提醒
|
||||
## 🚀 使用方法
|
||||
|
||||
- **数据备份**: 执行任何修改操作前务必备份相关数据
|
||||
- **权限控制**: 确保操作人员具有相应权限
|
||||
- **事务处理**: 建议使用数据库事务确保数据一致性
|
||||
- **日志记录**: 记录所有操作日志便于审计
|
||||
### 1. 配置数据库连接
|
||||
|
||||
## 📊 涉及业务模块统计
|
||||
编辑 `data.conf` 文件,设置正确的数据库连接信息:
|
||||
|
||||
| 模块 | 涉及表数量 | 重要程度 |
|
||||
|------|-----------|----------|
|
||||
| 核心状态管理 | 2 | ⭐⭐⭐⭐⭐ |
|
||||
| 组织关系 | 2 | ⭐⭐⭐⭐⭐ |
|
||||
| 经济资助 | 4 | ⭐⭐⭐⭐ |
|
||||
| 住宿管理 | 1 | ⭐⭐⭐⭐⭐ |
|
||||
| 心理健康 | 1 | ⭐⭐⭐⭐ |
|
||||
| 实践活动 | 3 | ⭐⭐⭐⭐ |
|
||||
| 其他信息 | 3 | ⭐⭐⭐ |
|
||||
```bash
|
||||
DB_HOST="your_db_host"
|
||||
DB_PORT="3306"
|
||||
DB_NAME="hzdyjs_xg"
|
||||
DB_USER="your_username"
|
||||
DB_PASS="your_password"
|
||||
```
|
||||
|
||||
## 🔄 状态映射关系
|
||||
### 2. 启动服务
|
||||
|
||||
- **休学**: `student_status=2`,用户账号保留,可恢复业务
|
||||
- **退学**: `student_status=4`,`sys_user.status=1`,终止所有业务
|
||||
- **毕业**: `student_status=5`,`sys_user.status=1`,归档处理
|
||||
脚本采用持续运行模式,启动后会自动循环处理:
|
||||
|
||||
## 📅 更新记录
|
||||
```bash
|
||||
# 启动所有服务(持续运行模式)
|
||||
./start_services.sh
|
||||
|
||||
- **2025-12-XX**: 完成文档模块化拆分,原有内容完整保留
|
||||
- **拆分说明**: 将原来1100+行的单文档拆分为1个主文档 + 6个分文档
|
||||
- **优化内容**: 基于奖学金获奖记录业务逻辑深度分析,完善了相关处理逻辑
|
||||
# 查看服务状态
|
||||
./control_scripts.sh statusall
|
||||
```
|
||||
|
||||
#### 持续运行模式说明
|
||||
|
||||
- **启动方式**: `./start_services.sh` 一次性启动所有服务
|
||||
- **运行逻辑**: 每个脚本启动后进入while循环,持续监控和处理数据
|
||||
- **处理周期**: 检查数据库 → 处理未处理记录 → 等待10分钟 → 重复循环
|
||||
- **并发控制**: 通过锁文件确保同一脚本只运行一个实例
|
||||
- **自动重启**: 如果脚本异常退出,可以通过控制脚本重启
|
||||
|
||||
### 3. 手动执行脚本(一次性)
|
||||
|
||||
如需手动执行单个脚本处理一次:
|
||||
|
||||
```bash
|
||||
# 处理毕业/退学/休学(一次性执行)
|
||||
./process_student_changes.sh
|
||||
|
||||
# 处理复学(一次性执行)
|
||||
./process_student_resume.sh
|
||||
```
|
||||
|
||||
### 4. 停止服务
|
||||
|
||||
```bash
|
||||
# 正常停止所有服务
|
||||
./stop_services.sh
|
||||
|
||||
# 强制停止所有服务(如果正常停止失败)
|
||||
./stop_services.sh force
|
||||
```
|
||||
|
||||
### 5. 健康检查
|
||||
|
||||
```bash
|
||||
# 执行健康检查
|
||||
./health_check.sh
|
||||
|
||||
# 执行检查并生成详细报告
|
||||
./health_check.sh report
|
||||
```
|
||||
```
|
||||
|
||||
### 3. 使用控制脚本管理
|
||||
|
||||
```bash
|
||||
# 启动指定脚本
|
||||
./control_scripts.sh start changes # 启动状态变更处理脚本
|
||||
./control_scripts.sh start resume # 启动复学处理脚本
|
||||
|
||||
# 停止指定脚本
|
||||
./control_scripts.sh stop changes # 停止状态变更处理脚本
|
||||
./control_scripts.sh stop resume # 停止复学处理脚本
|
||||
|
||||
# 重启指定脚本
|
||||
./control_scripts.sh restart changes # 重启状态变更处理脚本
|
||||
./control_scripts.sh restart resume # 重启复学处理脚本
|
||||
|
||||
# 查看脚本状态
|
||||
./control_scripts.sh status changes # 查看状态变更处理脚本状态
|
||||
./control_scripts.sh status resume # 查看复学处理脚本状态
|
||||
|
||||
# 批量操作
|
||||
./control_scripts.sh startall # 启动所有脚本
|
||||
./control_scripts.sh stopall # 停止所有脚本
|
||||
./control_scripts.sh statusall # 查看所有脚本状态
|
||||
```
|
||||
|
||||
## 📊 数据表说明
|
||||
|
||||
### 核心表
|
||||
|
||||
- **`xg_student_status_change`** - 学生状态变更记录表
|
||||
- `process_status`: 处理状态 (0=未处理,1=已处理)
|
||||
- `change_type`: 变更类型 (XIU_XUE/TUI_XUE/FU_XUE/BI_YE)
|
||||
|
||||
### 业务表
|
||||
|
||||
- **`xg_student_msg`** - 学生基本信息表
|
||||
- **`sys_user`** - 系统用户表
|
||||
- **`xg_class_pos_msg`** - 班级干部信息表
|
||||
- **`club_member`** - 社团成员表
|
||||
- **`stgl_member`** - 志愿者成员表
|
||||
- **`xg_dorm_bed_student`** - 宿舍床位分配表
|
||||
- **`xg_dorm_bed`** - 宿舍床位表
|
||||
|
||||
### 历史表
|
||||
|
||||
所有主表都有对应的his表用于数据备份:
|
||||
- `xg_student_msg_his`
|
||||
- `sys_user_his`
|
||||
- `xg_class_pos_msg_his`
|
||||
- `club_member_his`
|
||||
- `stgl_member_his`
|
||||
- `xg_dorm_bed_student_his`
|
||||
|
||||
## 📝 日志说明
|
||||
|
||||
### 日志文件位置
|
||||
- 日志目录:`/var/log/student_status_change/`
|
||||
- 日志格式:`process_student_changes_YYYYMMDD_HHMMSS.log`
|
||||
|
||||
### 日志内容
|
||||
- 脚本启动/停止信息
|
||||
- 数据库连接状态
|
||||
- 每条记录的处理详情
|
||||
- 错误信息和重试记录
|
||||
- 处理结果统计
|
||||
|
||||
### 示例日志
|
||||
```
|
||||
[2025-01-01 10:00:00] [INFO] Starting student status change processing script
|
||||
[2025-01-01 10:00:01] [INFO] Database connection successful
|
||||
[2025-01-01 10:00:02] [INFO] Processing student change - ID: 123, Student: 20240001 (456), Type: TUI_XUE
|
||||
[2025-01-01 10:00:03] [INFO] Successfully processed student change - ID: 123, Student: 20240001
|
||||
[2025-01-01 10:00:03] [INFO] Processing completed - Processed: 1, Failed: 0
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 安全提醒
|
||||
1. **数据备份**: 脚本会自动备份数据到his表,但建议在运行前手动备份重要数据
|
||||
2. **权限控制**: 确保运行脚本的用户有数据库操作权限
|
||||
3. **网络安全**: 数据库密码等敏感信息请妥善保管
|
||||
|
||||
### 使用限制
|
||||
1. **并发控制**: 同一脚本只允许一个实例运行(通过锁文件控制)
|
||||
2. **批量处理**: 每次最多处理100条记录,避免数据库负载过高
|
||||
3. **错误重试**: 处理失败时会自动重试,最多3次
|
||||
|
||||
### 监控建议
|
||||
1. **日志监控**: 定期检查日志文件,关注错误信息
|
||||
2. **数据库监控**: 监控数据库连接和性能
|
||||
3. **业务监控**: 检查处理结果是否符合预期
|
||||
4. **健康检查**: 使用 `./health_check.sh` 脚本定期检查服务状态
|
||||
|
||||
## 🔧 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **数据库连接失败**
|
||||
- 检查 `data.conf` 中的数据库配置
|
||||
- 确认数据库服务正在运行
|
||||
- 验证用户权限
|
||||
|
||||
2. **脚本重复运行**
|
||||
- 删除对应的锁文件:`rm -f script.lock`
|
||||
- 检查是否有残留进程并终止
|
||||
|
||||
3. **处理失败**
|
||||
- 查看日志文件了解具体错误
|
||||
- 检查数据库数据完整性
|
||||
- 手动处理失败的记录
|
||||
|
||||
### 紧急停止
|
||||
|
||||
```bash
|
||||
# 强制停止所有相关进程
|
||||
pkill -f "process_student_changes.sh"
|
||||
pkill -f "process_student_resume.sh"
|
||||
|
||||
# 清理锁文件
|
||||
rm -f *.lock
|
||||
rm -f pids/*.pid
|
||||
```
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如遇到问题,请:
|
||||
1. 查看日志文件获取详细错误信息
|
||||
2. 检查数据库连接和权限配置
|
||||
3. 确认相关数据表结构是否正确
|
||||
4. 联系技术支持团队
|
||||
|
||||
## 🔄 运行模式说明
|
||||
|
||||
### 持续运行模式(推荐)
|
||||
|
||||
脚本采用持续运行模式,启动后自动循环执行:
|
||||
|
||||
1. **启动脚本**: `./start_services.sh`
|
||||
2. **处理逻辑**: 检查未处理的记录 → 处理业务 → 等待10分钟 → 重复
|
||||
3. **停止脚本**: `./stop_services.sh`
|
||||
|
||||
### 可选的定时任务模式
|
||||
|
||||
如果需要使用crontab模式(不推荐),参考 `optional_crontab_config.txt` 文件:
|
||||
|
||||
```bash
|
||||
# 添加定时任务(仅在特殊情况下使用)
|
||||
crontab -e
|
||||
# 参考配置文件内容
|
||||
```
|
||||
|
||||
### 运行模式对比
|
||||
|
||||
| 特性 | 持续运行模式 | Crontab模式 |
|
||||
|------|-------------|-------------|
|
||||
| 启动方式 | `./start_services.sh` | crontab配置 |
|
||||
| 执行频率 | 每10分钟自动 | 可自定义时间 |
|
||||
| 资源占用 | 常驻进程 | 按需启动 |
|
||||
| 监控便利性 | 更容易监控 | 需要额外配置 |
|
||||
| 维护复杂度 | 较低 | 较高 |
|
||||
|
||||
**推荐使用持续运行模式**,简单可靠,易于监控管理。
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 💡 使用指南
|
||||
1. **查看演示**: 运行 `./demo.sh` 查看脚本使用说明
|
||||
2. **配置数据库**: 编辑 `data.conf` 配置数据库连接信息
|
||||
3. **启动服务**: 使用 `./start_services.sh` 启动持续运行的服务
|
||||
4. **监控运行**: 使用 `./health_check.sh` 检查服务状态
|
||||
5. **停止服务**: 需要时使用 `./stop_services.sh` 停止服务
|
||||
|
||||
### 🧪 测试步骤
|
||||
1. **插入测试数据**: 执行 `test_data.sql` 插入测试记录
|
||||
2. **启动服务**: `./start_services.sh`
|
||||
3. **观察日志**: 查看 `/var/log/student_status_change/` 目录的日志
|
||||
4. **检查结果**: 确认 `xg_student_status_change.process_status` 已更新为1
|
||||
|
||||
---
|
||||
|
||||
*本项目采用模块化文档管理方式,确保文档的可维护性和可读性。*
|
||||
**最后更新**: 2025-01-01
|
||||
**版本**: v1.0.0
|
||||
Executable
+304
@@ -0,0 +1,304 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理脚本控制程序
|
||||
# 用于启动、停止、重启处理脚本
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: Configuration file $CONFIG_FILE not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# Script definitions
|
||||
declare -A SCRIPTS=(
|
||||
["changes"]="process_student_changes.sh"
|
||||
["resume"]="process_student_resume.sh"
|
||||
)
|
||||
|
||||
# PID files
|
||||
PID_DIR="${SCRIPT_DIR}/pids"
|
||||
mkdir -p "$PID_DIR"
|
||||
|
||||
# Functions
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] [$level] $message"
|
||||
}
|
||||
|
||||
get_pid_file() {
|
||||
local script_name="$1"
|
||||
echo "${PID_DIR}/${script_name}.pid"
|
||||
}
|
||||
|
||||
get_lock_file() {
|
||||
local script_name="$1"
|
||||
echo "${SCRIPT_DIR}/${script_name}.lock"
|
||||
}
|
||||
|
||||
is_running() {
|
||||
local script_name="$1"
|
||||
local pid_file=$(get_pid_file "$script_name")
|
||||
local lock_file=$(get_lock_file "$script_name")
|
||||
|
||||
# Check PID file
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid=$(cat "$pid_file")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
return 0 # Running
|
||||
else
|
||||
log "WARN" "Removing stale PID file for $script_name"
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check lock file
|
||||
if [[ -f "$lock_file" ]]; then
|
||||
local lock_pid=$(cat "$lock_file")
|
||||
if kill -0 "$lock_pid" 2>/dev/null; then
|
||||
return 0 # Running
|
||||
else
|
||||
log "WARN" "Removing stale lock file for $script_name"
|
||||
rm -f "$lock_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1 # Not running
|
||||
}
|
||||
|
||||
start_script() {
|
||||
local script_name="$1"
|
||||
local script_file="${SCRIPT_DIR}/${SCRIPTS[$script_name]}"
|
||||
local pid_file=$(get_pid_file "$script_name")
|
||||
|
||||
if [[ ! -f "$script_file" ]]; then
|
||||
log "ERROR" "Script file not found: $script_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if is_running "$script_name"; then
|
||||
log "INFO" "$script_name is already running"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "INFO" "Starting $script_name..."
|
||||
chmod +x "$script_file"
|
||||
|
||||
# Start script in background
|
||||
nohup "$script_file" > /dev/null 2>&1 &
|
||||
local pid=$!
|
||||
|
||||
# Wait a moment for script to start
|
||||
sleep 2
|
||||
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
echo $pid > "$pid_file"
|
||||
log "INFO" "$script_name started successfully (PID: $pid)"
|
||||
return 0
|
||||
else
|
||||
log "ERROR" "Failed to start $script_name"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
stop_script() {
|
||||
local script_name="$1"
|
||||
local pid_file=$(get_pid_file "$script_name")
|
||||
local lock_file=$(get_lock_file "$script_name")
|
||||
local stopped=false
|
||||
|
||||
log "INFO" "Stopping $script_name..."
|
||||
|
||||
# Try to stop by PID file
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid=$(cat "$pid_file")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
kill "$pid"
|
||||
sleep 2
|
||||
if ! kill -0 "$pid" 2>/dev/null; then
|
||||
log "INFO" "$script_name stopped successfully (PID: $pid)"
|
||||
stopped=true
|
||||
fi
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
|
||||
# Try to stop by lock file
|
||||
if [[ -f "$lock_file" ]]; then
|
||||
local lock_pid=$(cat "$lock_file")
|
||||
if kill -0 "$lock_pid" 2>/dev/null; then
|
||||
kill "$lock_pid"
|
||||
sleep 2
|
||||
if ! kill -0 "$lock_pid" 2>/dev/null; then
|
||||
log "INFO" "$script_name stopped successfully (PID: $lock_pid)"
|
||||
stopped=true
|
||||
fi
|
||||
fi
|
||||
rm -f "$lock_file"
|
||||
fi
|
||||
|
||||
if [[ "$stopped" == false ]]; then
|
||||
log "WARN" "$script_name may not have been running or failed to stop gracefully"
|
||||
fi
|
||||
}
|
||||
|
||||
restart_script() {
|
||||
local script_name="$1"
|
||||
log "INFO" "Restarting $script_name..."
|
||||
stop_script "$script_name"
|
||||
sleep 3
|
||||
start_script "$script_name"
|
||||
}
|
||||
|
||||
status_script() {
|
||||
local script_name="$1"
|
||||
if is_running "$script_name"; then
|
||||
local pid_file=$(get_pid_file "$script_name")
|
||||
local lock_file=$(get_lock_file "$script_name")
|
||||
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid=$(cat "$pid_file")
|
||||
log "INFO" "$script_name is running (PID: $pid)"
|
||||
elif [[ -f "$lock_file" ]]; then
|
||||
local lock_pid=$(cat "$lock_file")
|
||||
log "INFO" "$script_name is running (PID: $lock_pid)"
|
||||
else
|
||||
log "INFO" "$script_name status unknown"
|
||||
fi
|
||||
else
|
||||
log "INFO" "$script_name is not running"
|
||||
fi
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 <command> <script_name>
|
||||
|
||||
Commands:
|
||||
start Start the specified script
|
||||
stop Stop the specified script
|
||||
restart Restart the specified script
|
||||
status Show status of the specified script
|
||||
startall Start all scripts
|
||||
stopall Stop all scripts
|
||||
statusall Show status of all scripts
|
||||
|
||||
Script names:
|
||||
changes Student status changes script (休学/退学/毕业)
|
||||
resume Student resume script (复学)
|
||||
all All scripts
|
||||
|
||||
Examples:
|
||||
$0 start changes # Start changes processing script
|
||||
$0 stop resume # Stop resume processing script
|
||||
$0 restart changes # Restart changes processing script
|
||||
$0 status all # Show status of all scripts
|
||||
$0 startall # Start all scripts
|
||||
$0 stopall # Stop all scripts
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
local command="${1:-}"
|
||||
local script_name="${2:-}"
|
||||
|
||||
case "$command" in
|
||||
start)
|
||||
if [[ "$script_name" == "all" ]]; then
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
start_script "$script"
|
||||
done
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
start_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
if [[ "$script_name" == "all" ]]; then
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
stop_script "$script"
|
||||
done
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
stop_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
if [[ "$script_name" == "all" ]]; then
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
restart_script "$script"
|
||||
done
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
restart_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
status)
|
||||
if [[ "$script_name" == "all" ]]; then
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
status_script "$script"
|
||||
done
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
status_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
startall)
|
||||
log "INFO" "Starting all scripts..."
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
start_script "$script"
|
||||
done
|
||||
;;
|
||||
|
||||
stopall)
|
||||
log "INFO" "Stopping all scripts..."
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
stop_script "$script"
|
||||
done
|
||||
;;
|
||||
|
||||
statusall)
|
||||
log "INFO" "Checking status of all scripts..."
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
status_script "$script"
|
||||
done
|
||||
;;
|
||||
|
||||
*)
|
||||
log "ERROR" "Unknown command: $command"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -0,0 +1,17 @@
|
||||
# Database configuration
|
||||
DB_HOST="localhost"
|
||||
DB_PORT="3306"
|
||||
DB_NAME="hzdyjs_xg"
|
||||
DB_USER="root"
|
||||
DB_PASS="password"
|
||||
|
||||
# Script configuration
|
||||
LOG_DIR="/var/log/student_status_change"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOCK_FILE="${SCRIPT_DIR}/script.lock"
|
||||
|
||||
# Processing configuration
|
||||
BATCH_SIZE=100
|
||||
MAX_RETRY=3
|
||||
RETRY_DELAY=5
|
||||
CYCLE_INTERVAL=600 # 循环间隔时间(秒),默认10分钟
|
||||
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理脚本演示
|
||||
# 展示如何使用这些脚本
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo "========================================"
|
||||
echo " 学生状态变更处理脚本演示"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
echo "脚本位置: $SCRIPT_DIR"
|
||||
echo ""
|
||||
|
||||
echo "📋 脚本文件说明:"
|
||||
echo " process_student_changes.sh - 处理毕业/退学/休学的状态变更"
|
||||
echo " process_student_resume.sh - 处理复学的状态变更"
|
||||
echo " control_scripts.sh - 脚本控制程序"
|
||||
echo " start_services.sh - 一键启动所有服务"
|
||||
echo " stop_services.sh - 一键停止所有服务"
|
||||
echo " health_check.sh - 服务健康检查"
|
||||
echo ""
|
||||
|
||||
echo "🔧 配置文件:"
|
||||
echo " data.conf - 数据库配置"
|
||||
echo " test_data.sql - 测试数据"
|
||||
echo ""
|
||||
|
||||
echo "📖 使用步骤:"
|
||||
echo ""
|
||||
|
||||
echo "1️⃣ 配置数据库连接:"
|
||||
echo " vim data.conf"
|
||||
echo " # 修改数据库连接信息"
|
||||
echo ""
|
||||
|
||||
echo "2️⃣ 启动服务(持续运行模式):"
|
||||
echo " ./start_services.sh"
|
||||
echo ""
|
||||
|
||||
echo "3️⃣ 查看服务状态:"
|
||||
echo " ./control_scripts.sh statusall"
|
||||
echo ""
|
||||
|
||||
echo "4️⃣ 执行健康检查:"
|
||||
echo " ./health_check.sh"
|
||||
echo ""
|
||||
|
||||
echo "5️⃣ 停止服务:"
|
||||
echo " ./stop_services.sh"
|
||||
echo ""
|
||||
|
||||
echo "📊 运行模式说明:"
|
||||
echo "• 脚本启动后进入持续运行模式"
|
||||
echo "• 每10分钟自动检查和处理一次数据"
|
||||
echo "• 支持并发控制,避免重复运行"
|
||||
echo "• 完整的日志记录和错误处理"
|
||||
echo ""
|
||||
|
||||
echo "🧪 测试数据:"
|
||||
echo "• 运行 test_data.sql 插入测试数据"
|
||||
echo "• 脚本会自动处理 process_status = 0 的记录"
|
||||
echo ""
|
||||
|
||||
echo "📝 日志位置:"
|
||||
echo "• /var/log/student_status_change/"
|
||||
echo "• 包含详细的处理日志和错误信息"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ 注意事项:"
|
||||
echo "• 确保数据库连接正确"
|
||||
echo "• 确保用户有足够的数据库权限"
|
||||
echo "• 定期检查日志文件"
|
||||
echo "• 监控磁盘空间使用情况"
|
||||
echo ""
|
||||
|
||||
echo "========================================"
|
||||
echo " 演示完成"
|
||||
echo "========================================"
|
||||
Executable
+359
@@ -0,0 +1,359 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理服务健康检查脚本
|
||||
# 用于监控服务运行状态和数据库连接
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Load configuration
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo -e "${RED}Error: Configuration file $CONFIG_FILE not found!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# Functions
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${timestamp} [$level] $message"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✓ $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}✗ $1${NC}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠ $1${NC}"
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${BLUE}ℹ $1${NC}"
|
||||
}
|
||||
|
||||
# Check database connection
|
||||
check_database() {
|
||||
info "Checking database connection..."
|
||||
|
||||
local db_test
|
||||
if db_test=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "SELECT 1 as test;" 2>/dev/null); then
|
||||
if echo "$db_test" | grep -q "test"; then
|
||||
success "Database connection successful"
|
||||
return 0
|
||||
else
|
||||
error "Database query failed"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
error "Database connection failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check service status
|
||||
check_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
info "Checking $service_desc..."
|
||||
|
||||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||||
error "Control script not found or not executable: $CONTROL_SCRIPT"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local status_output
|
||||
status_output=$("$CONTROL_SCRIPT" status "$service_name" 2>/dev/null)
|
||||
|
||||
if echo "$status_output" | grep -q "is running"; then
|
||||
success "$service_desc is running"
|
||||
|
||||
# Extract PID if available
|
||||
local pid
|
||||
pid=$(echo "$status_output" | grep -o "PID: [0-9]*" | cut -d' ' -f2)
|
||||
if [[ -n "$pid" ]]; then
|
||||
info " Process ID: $pid"
|
||||
fi
|
||||
|
||||
return 0
|
||||
else
|
||||
error "$service_desc is not running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check log files
|
||||
check_logs() {
|
||||
info "Checking log files..."
|
||||
|
||||
if [[ ! -d "$LOG_DIR" ]]; then
|
||||
warning "Log directory does not exist: $LOG_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Count log files
|
||||
local log_count
|
||||
log_count=$(find "$LOG_DIR" -name "*.log" -type f | wc -l)
|
||||
|
||||
if [[ $log_count -gt 0 ]]; then
|
||||
success "Found $log_count log files"
|
||||
|
||||
# Check for recent errors
|
||||
local recent_errors
|
||||
recent_errors=$(find "$LOG_DIR" -name "*.log" -type f -mmin -60 -exec grep -l "ERROR" {} \; | wc -l)
|
||||
|
||||
if [[ $recent_errors -gt 0 ]]; then
|
||||
warning "Found $recent_errors log files with recent errors (last 60 minutes)"
|
||||
else
|
||||
info "No recent errors found in log files"
|
||||
fi
|
||||
|
||||
return 0
|
||||
else
|
||||
warning "No log files found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check pending records
|
||||
check_pending_records() {
|
||||
info "Checking pending records in database..."
|
||||
|
||||
local pending_changes pending_resume
|
||||
|
||||
# Check changes (XIU_XUE, TUI_XUE, BI_YE)
|
||||
pending_changes=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "
|
||||
SELECT COUNT(*) as count FROM xg_student_status_change
|
||||
WHERE process_status = 0
|
||||
AND change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE')
|
||||
AND deleted = 0;
|
||||
" 2>/dev/null | tail -n1)
|
||||
|
||||
# Check resume (FU_XUE)
|
||||
pending_resume=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "
|
||||
SELECT COUNT(*) as count FROM xg_student_status_change
|
||||
WHERE process_status = 0
|
||||
AND change_type = 'FU_XUE'
|
||||
AND deleted = 0;
|
||||
" 2>/dev/null | tail -n1)
|
||||
|
||||
# Remove potential header
|
||||
pending_changes=$(echo "$pending_changes" | grep -E '^[0-9]+$')
|
||||
pending_resume=$(echo "$pending_resume" | grep -E '^[0-9]+$')
|
||||
|
||||
if [[ -z "$pending_changes" ]]; then
|
||||
pending_changes="0"
|
||||
fi
|
||||
|
||||
if [[ -z "$pending_resume" ]]; then
|
||||
pending_resume="0"
|
||||
fi
|
||||
|
||||
local total_pending=$((pending_changes + pending_resume))
|
||||
|
||||
if [[ $total_pending -gt 0 ]]; then
|
||||
info "Found $total_pending pending records ($pending_changes changes, $pending_resume resume)"
|
||||
if [[ $pending_changes -gt 0 ]]; then
|
||||
warning " $pending_changes records waiting for changes processing"
|
||||
fi
|
||||
if [[ $pending_resume -gt 0 ]]; then
|
||||
warning " $pending_resume records waiting for resume processing"
|
||||
fi
|
||||
else
|
||||
success "No pending records found"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Check disk space
|
||||
check_disk_space() {
|
||||
info "Checking disk space..."
|
||||
|
||||
local log_disk_usage
|
||||
log_disk_usage=$(df "$LOG_DIR" 2>/dev/null | tail -n1 | awk '{print $5}' | sed 's/%//')
|
||||
|
||||
if [[ -z "$log_disk_usage" ]]; then
|
||||
warning "Cannot determine log directory disk usage"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ $log_disk_usage -gt 90 ]]; then
|
||||
error "Log directory disk usage is ${log_disk_usage}% - consider cleaning up old logs"
|
||||
return 1
|
||||
elif [[ $log_disk_usage -gt 75 ]]; then
|
||||
warning "Log directory disk usage is ${log_disk_usage}%"
|
||||
else
|
||||
success "Log directory disk usage is ${log_disk_usage}%"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Generate health report
|
||||
generate_report() {
|
||||
local report_file="${LOG_DIR}/health_check_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
{
|
||||
echo "=== 学生状态变更处理服务健康检查报告 ==="
|
||||
echo "检查时间: $(date)"
|
||||
echo "检查主机: $(hostname)"
|
||||
echo ""
|
||||
|
||||
echo "=== 数据库连接检查 ==="
|
||||
if check_database; then
|
||||
echo "状态: 正常"
|
||||
else
|
||||
echo "状态: 异常"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== 服务状态检查 ==="
|
||||
echo "学生状态变更处理服务 (休学/退学/毕业):"
|
||||
if check_service "changes" "学生状态变更处理服务"; then
|
||||
echo "状态: 运行中"
|
||||
else
|
||||
echo "状态: 未运行"
|
||||
fi
|
||||
|
||||
echo "学生复学处理服务:"
|
||||
if check_service "resume" "学生复学处理服务"; then
|
||||
echo "状态: 运行中"
|
||||
else
|
||||
echo "状态: 未运行"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== 待处理记录检查 ==="
|
||||
check_pending_records
|
||||
echo ""
|
||||
|
||||
echo "=== 日志文件检查 ==="
|
||||
check_logs
|
||||
echo ""
|
||||
|
||||
echo "=== 磁盘空间检查 ==="
|
||||
check_disk_space
|
||||
echo ""
|
||||
|
||||
echo "=== 配置信息 ==="
|
||||
echo "数据库主机: $DB_HOST:$DB_PORT"
|
||||
echo "数据库名称: $DB_NAME"
|
||||
echo "日志目录: $LOG_DIR"
|
||||
echo "脚本目录: $SCRIPT_DIR"
|
||||
echo ""
|
||||
|
||||
echo "报告生成完成"
|
||||
|
||||
} > "$report_file" 2>/dev/null
|
||||
|
||||
if [[ -f "$report_file" ]]; then
|
||||
success "Health check report generated: $report_file"
|
||||
else
|
||||
error "Failed to generate health check report"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
local generate_report="${1:-false}"
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " 学生状态变更处理服务健康检查"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# Perform all checks
|
||||
check_database
|
||||
echo ""
|
||||
|
||||
check_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
check_service "resume" "学生复学处理服务"
|
||||
echo ""
|
||||
|
||||
check_pending_records
|
||||
echo ""
|
||||
|
||||
check_logs
|
||||
echo ""
|
||||
|
||||
check_disk_space
|
||||
echo ""
|
||||
|
||||
# Generate report if requested
|
||||
if [[ "$generate_report" == "report" ]]; then
|
||||
generate_report
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
success "健康检查完成"
|
||||
echo ""
|
||||
|
||||
if [[ "$generate_report" == "report" ]]; then
|
||||
echo "详细报告已保存到日志目录"
|
||||
fi
|
||||
|
||||
echo "使用方法:"
|
||||
echo " $0 # 执行健康检查"
|
||||
echo " $0 report # 执行检查并生成报告"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [report]
|
||||
|
||||
执行学生状态变更处理服务的健康检查。
|
||||
|
||||
Options:
|
||||
report 生成详细的健康检查报告
|
||||
|
||||
检查内容:
|
||||
- 数据库连接状态
|
||||
- 服务运行状态
|
||||
- 待处理记录数量
|
||||
- 日志文件状态
|
||||
- 磁盘空间使用情况
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
case "${1:-}" in
|
||||
report)
|
||||
main "report"
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
;;
|
||||
"")
|
||||
main
|
||||
;;
|
||||
*)
|
||||
error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
+6685
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,69 @@
|
||||
# ===========================================
|
||||
# 学生状态变更处理脚本 - 可选的Crontab配置
|
||||
# ===========================================
|
||||
|
||||
# 注意:脚本现在采用持续运行模式,默认每10分钟自动处理一次
|
||||
# 此配置文件仅供特殊情况下的备用配置使用
|
||||
|
||||
# 如果不使用持续运行模式,可以使用以下crontab配置:
|
||||
# 1. 将以下内容添加到系统的 crontab 中:crontab -e
|
||||
# 2. 根据实际需要调整执行时间和频率
|
||||
# 3. 确保脚本路径正确
|
||||
# 4. 确保用户有执行权限
|
||||
|
||||
# 脚本所在目录(请根据实际情况修改)
|
||||
SCRIPT_DIR="/path/to/student_status_scripts"
|
||||
|
||||
# 每天早上8点执行学生状态变更处理
|
||||
0 8 * * * $SCRIPT_DIR/process_student_changes.sh
|
||||
|
||||
# 每天早上8点30分执行学生复学处理
|
||||
30 8 * * * $SCRIPT_DIR/process_student_resume.sh
|
||||
|
||||
# 每小时执行一次健康检查
|
||||
0 * * * * $SCRIPT_DIR/health_check.sh report
|
||||
|
||||
# 每周一早上6点重启所有服务(可选,用于定期重启确保稳定性)
|
||||
0 6 * * 1 $SCRIPT_DIR/stop_services.sh && sleep 5 && $SCRIPT_DIR/start_services.sh
|
||||
|
||||
# 每天晚上10点清理旧日志文件(保留7天)
|
||||
0 22 * * * find $SCRIPT_DIR/logs -name "*.log" -type f -mtime +7 -delete
|
||||
|
||||
# 每分钟检查服务状态,如果服务停止则自动重启(可选)
|
||||
# */1 * * * * $SCRIPT_DIR/control_scripts.sh statusall >/dev/null 2>&1 || ($SCRIPT_DIR/stop_services.sh force && $SCRIPT_DIR/start_services.sh)
|
||||
|
||||
# ===========================================
|
||||
# Crontab 语法说明
|
||||
# ===========================================
|
||||
# 分 时 日 月 周 命令
|
||||
# * * * * * command
|
||||
#
|
||||
# 字段说明:
|
||||
# 分 - 0-59
|
||||
# 时 - 0-23
|
||||
# 日 - 1-31
|
||||
# 月 - 1-12
|
||||
# 周 - 0-7 (0和7都表示星期日)
|
||||
#
|
||||
# 常用示例:
|
||||
# 0 8 * * * - 每天早上8点
|
||||
# */30 * * * * - 每30分钟
|
||||
# 0 */2 * * * - 每2小时
|
||||
# 0 9-17 * * 1-5 - 周一到周五的9点到17点,每小时执行一次
|
||||
# @reboot - 系统重启时执行
|
||||
|
||||
# ===========================================
|
||||
# 监控和告警建议
|
||||
# ===========================================
|
||||
|
||||
# 1. 监控日志中的ERROR关键字
|
||||
# 可以使用logwatch或自定义脚本监控日志
|
||||
|
||||
# 2. 监控数据库连接
|
||||
# */5 * * * * mysql -h host -u user -p pass -e "SELECT 1;" || echo "DB connection failed" | mail -s "DB Alert" admin@example.com
|
||||
|
||||
# 3. 监控磁盘空间
|
||||
# */30 * * * * df /var/log | awk 'NR==2 {if($5>90) print "Disk usage high: "$5}' | mail -s "Disk Alert" admin@example.com
|
||||
|
||||
# 4. 监控进程状态
|
||||
# */5 * * * * pgrep -f "process_student_changes.sh" >/dev/null || echo "Process died" | mail -s "Process Alert" admin@example.com
|
||||
Executable
+293
@@ -0,0 +1,293 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理脚本 - 毕业/退学/休学
|
||||
# 处理类型: XIU_XUE(休学), TUI_XUE(退学), BI_YE(毕业)
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: Configuration file $CONFIG_FILE not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# Create log directory
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Log file
|
||||
LOG_FILE="${LOG_DIR}/process_student_changes_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# Lock file to prevent multiple instances
|
||||
LOCK_FILE="${SCRIPT_DIR}/process_student_changes.lock"
|
||||
|
||||
# Functions
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
error_exit() {
|
||||
local message="$1"
|
||||
log "ERROR" "$message"
|
||||
# Remove lock file
|
||||
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if script is already running
|
||||
if [[ -f "$LOCK_FILE" ]]; then
|
||||
if kill -0 $(cat "$LOCK_FILE") 2>/dev/null; then
|
||||
log "INFO" "Script is already running (PID: $(cat "$LOCK_FILE"))"
|
||||
exit 1
|
||||
else
|
||||
log "WARN" "Removing stale lock file"
|
||||
rm -f "$LOCK_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create lock file
|
||||
echo $$ > "$LOCK_FILE"
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
||||
log "INFO" "Script execution completed"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# Database functions
|
||||
execute_sql() {
|
||||
local sql="$1"
|
||||
local result
|
||||
|
||||
result=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "$sql" 2>&1)
|
||||
local exit_code=$?
|
||||
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
log "ERROR" "SQL execution failed: $sql"
|
||||
log "ERROR" "MySQL error: $result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$result"
|
||||
}
|
||||
|
||||
# Process student status change
|
||||
process_student_change() {
|
||||
local record_id="$1"
|
||||
local student_id="$2"
|
||||
local student_no="$3"
|
||||
local change_type="$4"
|
||||
local operator_id="${5:-1}"
|
||||
|
||||
log "INFO" "Processing student change - ID: $record_id, Student: $student_no ($student_id), Type: $change_type"
|
||||
|
||||
# Start transaction
|
||||
local transaction_sql="
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. Backup original data to his tables
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = $student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = $student_id;
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = $student_id;
|
||||
INSERT INTO club_member_his SELECT * FROM club_member WHERE user_id = $student_id;
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = $student_id;
|
||||
INSERT INTO xg_dorm_bed_student_his SELECT * FROM xg_dorm_bed_student WHERE student_id = $student_id;
|
||||
|
||||
-- 2. Update student status
|
||||
UPDATE xg_student_msg SET
|
||||
student_status = CASE
|
||||
WHEN '$change_type' = 'XIU_XUE' THEN '2'
|
||||
WHEN '$change_type' = 'TUI_XUE' THEN '4'
|
||||
WHEN '$change_type' = 'BI_YE' THEN '5'
|
||||
ELSE student_status
|
||||
END,
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = $student_id;
|
||||
|
||||
-- 3. Disable user account
|
||||
UPDATE sys_user SET
|
||||
status = '1',
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE user_id = $student_id AND account_type = '2';
|
||||
|
||||
-- 4. Process class position (cadre) - only for XIU_XUE, TUI_XUE, BI_YE
|
||||
UPDATE xg_class_pos_msg SET
|
||||
is_current = 0,
|
||||
cadre_status = CASE
|
||||
WHEN '$change_type' = 'XIU_XUE' THEN '6'
|
||||
WHEN '$change_type' IN ('TUI_XUE', 'BI_YE') THEN '4'
|
||||
ELSE cadre_status
|
||||
END,
|
||||
dismissal_date = CURDATE(),
|
||||
dismissal_reason = CASE
|
||||
WHEN '$change_type' = 'XIU_XUE' THEN '学生休学'
|
||||
WHEN '$change_type' = 'TUI_XUE' THEN '学生退学'
|
||||
WHEN '$change_type' = 'BI_YE' THEN '学生毕业'
|
||||
ELSE dismissal_reason
|
||||
END,
|
||||
term_end_date = CURDATE(),
|
||||
term_duration = TIMESTAMPDIFF(MONTH, term_start_date, CURDATE()),
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE student_id = $student_id AND is_current = 1;
|
||||
|
||||
-- 5. Process club membership - only for XIU_XUE, TUI_XUE, BI_YE
|
||||
UPDATE club_member SET
|
||||
member_status = '4',
|
||||
update_by = $operator_id,
|
||||
update_time = NOW(),
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 退出原因:',
|
||||
CASE
|
||||
WHEN '$change_type' = 'XIU_XUE' THEN '学生休学'
|
||||
WHEN '$change_type' = 'TUI_XUE' THEN '学生退学'
|
||||
WHEN '$change_type' = 'BI_YE' THEN '学生毕业'
|
||||
ELSE '学生状态变更'
|
||||
END, ' - ', NOW())
|
||||
WHERE user_id = $student_id AND member_status IN ('0', '1', '2');
|
||||
|
||||
-- 6. Process volunteer membership - only for XIU_XUE, TUI_XUE, BI_YE
|
||||
UPDATE stgl_member SET
|
||||
status = 4,
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE user_id = $student_id AND status IN (0, 1, 2);
|
||||
|
||||
-- 7. Process dormitory - only for TUI_XUE, BI_YE
|
||||
UPDATE xg_student_msg SET
|
||||
dormitory_building = NULL,
|
||||
dormitory_room = NULL,
|
||||
ext_field1 = NULL,
|
||||
update_time = NOW(),
|
||||
update_by = $operator_id
|
||||
WHERE id = $student_id;
|
||||
|
||||
UPDATE xg_dorm_bed_student SET
|
||||
status = '1',
|
||||
checkout_time = NOW(),
|
||||
update_time = NOW(),
|
||||
update_by = $operator_id
|
||||
WHERE student_id = $student_id AND status = '0';
|
||||
|
||||
UPDATE xg_dorm_bed SET
|
||||
bed_status = '0'
|
||||
WHERE id IN (
|
||||
SELECT bed_id FROM xg_dorm_bed_student
|
||||
WHERE student_id = $student_id AND status = '1'
|
||||
);
|
||||
|
||||
-- 8. Update change record status
|
||||
UPDATE xg_student_status_change SET
|
||||
process_status = 1,
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = $record_id;
|
||||
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
# Execute transaction
|
||||
if execute_sql "$transaction_sql"; then
|
||||
log "INFO" "Successfully processed student change - ID: $record_id, Student: $student_no"
|
||||
return 0
|
||||
else
|
||||
log "ERROR" "Failed to process student change - ID: $record_id, Student: $student_no"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "INFO" "Starting student status change processing daemon"
|
||||
log "INFO" "Processing types: XIU_XUE(休学), TUI_XUE(退学), BI_YE(毕业)"
|
||||
log "INFO" "Running in continuous mode with 10-minute intervals"
|
||||
|
||||
# Test database connection
|
||||
log "INFO" "Testing database connection..."
|
||||
if ! execute_sql "SELECT 1;" >/dev/null 2>&1; then
|
||||
error_exit "Database connection failed"
|
||||
fi
|
||||
log "INFO" "Database connection successful"
|
||||
|
||||
# Main processing loop
|
||||
while true; do
|
||||
log "INFO" "Starting new processing cycle"
|
||||
|
||||
# Get unprocessed records
|
||||
local query_sql="
|
||||
SELECT id, student_id, student_no, change_type, operator_id
|
||||
FROM xg_student_status_change
|
||||
WHERE process_status = 0
|
||||
AND change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE')
|
||||
AND deleted = 0
|
||||
ORDER BY create_time ASC
|
||||
LIMIT $BATCH_SIZE;
|
||||
"
|
||||
|
||||
local records
|
||||
records=$(execute_sql "$query_sql")
|
||||
|
||||
# Check if there are records to process
|
||||
local record_count
|
||||
record_count=$(echo "$records" | wc -l)
|
||||
|
||||
if [[ $record_count -le 1 ]]; then
|
||||
log "INFO" "No unprocessed records found, waiting..."
|
||||
else
|
||||
# Remove header line
|
||||
records=$(echo "$records" | tail -n +2)
|
||||
|
||||
local processed_count=0
|
||||
local failed_count=0
|
||||
|
||||
# Process each record
|
||||
while IFS=$'\t' read -r record_id student_id student_no change_type operator_id; do
|
||||
# Skip empty lines
|
||||
[[ -z "$record_id" ]] && continue
|
||||
|
||||
local retry_count=0
|
||||
local success=false
|
||||
|
||||
while [[ $retry_count -lt $MAX_RETRY && $success == false ]]; do
|
||||
if process_student_change "$record_id" "$student_id" "$student_no" "$change_type" "$operator_id"; then
|
||||
success=true
|
||||
((processed_count++))
|
||||
else
|
||||
((retry_count++))
|
||||
if [[ $retry_count -lt $MAX_RETRY ]]; then
|
||||
log "WARN" "Processing failed, retrying in $RETRY_DELAY seconds... (attempt $retry_count/$MAX_RETRY)"
|
||||
sleep $RETRY_DELAY
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $success == false ]]; then
|
||||
((failed_count++))
|
||||
log "ERROR" "Failed to process record after $MAX_RETRY attempts - ID: $record_id"
|
||||
fi
|
||||
|
||||
done <<< "$records"
|
||||
|
||||
log "INFO" "Processing cycle completed - Processed: $processed_count, Failed: $failed_count"
|
||||
fi
|
||||
|
||||
# Wait for configured interval before next cycle
|
||||
log "INFO" "Waiting $CYCLE_INTERVAL seconds before next processing cycle..."
|
||||
sleep $CYCLE_INTERVAL
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Executable
+219
@@ -0,0 +1,219 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理脚本 - 复学
|
||||
# 处理类型: FU_XUE(复学)
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: Configuration file $CONFIG_FILE not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# Create log directory
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Log file
|
||||
LOG_FILE="${LOG_DIR}/process_student_resume_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# Lock file to prevent multiple instances
|
||||
LOCK_FILE="${SCRIPT_DIR}/process_student_resume.lock"
|
||||
|
||||
# Functions
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
error_exit() {
|
||||
local message="$1"
|
||||
log "ERROR" "$message"
|
||||
# Remove lock file
|
||||
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if script is already running
|
||||
if [[ -f "$LOCK_FILE" ]]; then
|
||||
if kill -0 $(cat "$LOCK_FILE") 2>/dev/null; then
|
||||
log "INFO" "Script is already running (PID: $(cat "$LOCK_FILE"))"
|
||||
exit 1
|
||||
else
|
||||
log "WARN" "Removing stale lock file"
|
||||
rm -f "$LOCK_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create lock file
|
||||
echo $$ > "$LOCK_FILE"
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
||||
log "INFO" "Script execution completed"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# Database functions
|
||||
execute_sql() {
|
||||
local sql="$1"
|
||||
local result
|
||||
|
||||
result=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "$sql" 2>&1)
|
||||
local exit_code=$?
|
||||
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
log "ERROR" "SQL execution failed: $sql"
|
||||
log "ERROR" "MySQL error: $result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$result"
|
||||
}
|
||||
|
||||
# Process student resume
|
||||
process_student_resume() {
|
||||
local record_id="$1"
|
||||
local student_id="$2"
|
||||
local student_no="$3"
|
||||
local change_type="$4"
|
||||
local operator_id="${5:-1}"
|
||||
|
||||
log "INFO" "Processing student resume - ID: $record_id, Student: $student_no ($student_id), Type: $change_type"
|
||||
|
||||
# Start transaction
|
||||
local transaction_sql="
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. Backup original data to his tables
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = $student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = $student_id;
|
||||
|
||||
-- 2. Update student status to resume (复学)
|
||||
UPDATE xg_student_msg SET
|
||||
student_status = '3',
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = $student_id;
|
||||
|
||||
-- 3. Enable user account
|
||||
UPDATE sys_user SET
|
||||
status = '0',
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE user_id = $student_id AND account_type = '2';
|
||||
|
||||
-- 4. Update change record status
|
||||
UPDATE xg_student_status_change SET
|
||||
process_status = 1,
|
||||
update_by = $operator_id,
|
||||
update_time = NOW()
|
||||
WHERE id = $record_id;
|
||||
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
# Execute transaction
|
||||
if execute_sql "$transaction_sql"; then
|
||||
log "INFO" "Successfully processed student resume - ID: $record_id, Student: $student_no"
|
||||
return 0
|
||||
else
|
||||
log "ERROR" "Failed to process student resume - ID: $record_id, Student: $student_no"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "INFO" "Starting student resume processing daemon"
|
||||
log "INFO" "Processing type: FU_XUE(复学)"
|
||||
log "INFO" "Running in continuous mode with 10-minute intervals"
|
||||
|
||||
# Test database connection
|
||||
log "INFO" "Testing database connection..."
|
||||
if ! execute_sql "SELECT 1;" >/dev/null 2>&1; then
|
||||
error_exit "Database connection failed"
|
||||
fi
|
||||
log "INFO" "Database connection successful"
|
||||
|
||||
# Main processing loop
|
||||
while true; do
|
||||
log "INFO" "Starting new resume processing cycle"
|
||||
|
||||
# Get unprocessed records
|
||||
local query_sql="
|
||||
SELECT id, student_id, student_no, change_type, operator_id
|
||||
FROM xg_student_status_change
|
||||
WHERE process_status = 0
|
||||
AND change_type = 'FU_XUE'
|
||||
AND deleted = 0
|
||||
ORDER BY create_time ASC
|
||||
LIMIT $BATCH_SIZE;
|
||||
"
|
||||
|
||||
local records
|
||||
records=$(execute_sql "$query_sql")
|
||||
|
||||
# Check if there are records to process
|
||||
local record_count
|
||||
record_count=$(echo "$records" | wc -l)
|
||||
|
||||
if [[ $record_count -le 1 ]]; then
|
||||
log "INFO" "No unprocessed resume records found, waiting..."
|
||||
else
|
||||
# Remove header line
|
||||
records=$(echo "$records" | tail -n +2)
|
||||
|
||||
local processed_count=0
|
||||
local failed_count=0
|
||||
|
||||
# Process each record
|
||||
while IFS=$'\t' read -r record_id student_id student_no change_type operator_id; do
|
||||
# Skip empty lines
|
||||
[[ -z "$record_id" ]] && continue
|
||||
|
||||
local retry_count=0
|
||||
local success=false
|
||||
|
||||
while [[ $retry_count -lt $MAX_RETRY && $success == false ]]; do
|
||||
if process_student_resume "$record_id" "$student_id" "$student_no" "$change_type" "$operator_id"; then
|
||||
success=true
|
||||
((processed_count++))
|
||||
else
|
||||
((retry_count++))
|
||||
if [[ $retry_count -lt $MAX_RETRY ]]; then
|
||||
log "WARN" "Processing failed, retrying in $RETRY_DELAY seconds... (attempt $retry_count/$MAX_RETRY)"
|
||||
sleep $RETRY_DELAY
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $success == false ]]; then
|
||||
((failed_count++))
|
||||
log "ERROR" "Failed to process record after $MAX_RETRY attempts - ID: $record_id"
|
||||
fi
|
||||
|
||||
done <<< "$records"
|
||||
|
||||
log "INFO" "Resume processing cycle completed - Processed: $processed_count, Failed: $failed_count"
|
||||
fi
|
||||
|
||||
# Wait for configured interval before next cycle
|
||||
log "INFO" "Waiting $CYCLE_INTERVAL seconds before next resume processing cycle..."
|
||||
sleep $CYCLE_INTERVAL
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理服务启动脚本
|
||||
# 用于启动所有相关的处理服务
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${timestamp} [$level] $message"
|
||||
}
|
||||
|
||||
success() {
|
||||
log "${GREEN}SUCCESS${NC}" "$1"
|
||||
}
|
||||
|
||||
error() {
|
||||
log "${RED}ERROR${NC}" "$1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
log "${YELLOW}WARNING${NC}" "$1"
|
||||
}
|
||||
|
||||
# Check if control script exists and is executable
|
||||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||||
error "Control script not found or not executable: $CONTROL_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to start a service
|
||||
start_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Starting $service_desc..."
|
||||
if "$CONTROL_SCRIPT" start "$service_name"; then
|
||||
success "$service_desc started successfully"
|
||||
return 0
|
||||
else
|
||||
error "Failed to start $service_desc"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check service status
|
||||
check_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Checking $service_desc status..."
|
||||
if "$CONTROL_SCRIPT" status "$service_name" | grep -q "is running"; then
|
||||
success "$service_desc is running"
|
||||
return 0
|
||||
else
|
||||
warning "$service_desc is not running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "INFO" "=== 学生状态变更处理服务启动脚本 ==="
|
||||
log "INFO" "Starting all student status change processing services..."
|
||||
|
||||
local failed_services=()
|
||||
|
||||
# Start changes processing service
|
||||
if ! start_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"; then
|
||||
failed_services+=("changes")
|
||||
fi
|
||||
|
||||
# Start resume processing service
|
||||
if ! start_service "resume" "学生复学处理服务"; then
|
||||
failed_services+=("resume")
|
||||
fi
|
||||
|
||||
# Wait a moment for services to fully start
|
||||
sleep 3
|
||||
|
||||
log "INFO" "=== 服务状态检查 ==="
|
||||
|
||||
# Check all services status
|
||||
check_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
check_service "resume" "学生复学处理服务"
|
||||
|
||||
# Summary
|
||||
log "INFO" "=== 启动完成 ==="
|
||||
if [[ ${#failed_services[@]} -eq 0 ]]; then
|
||||
success "所有服务启动成功"
|
||||
echo ""
|
||||
echo "服务控制命令:"
|
||||
echo " 查看状态: $CONTROL_SCRIPT statusall"
|
||||
echo " 停止服务: $CONTROL_SCRIPT stopall"
|
||||
echo " 重启服务: $CONTROL_SCRIPT restart changes|resume"
|
||||
echo ""
|
||||
echo "日志文件位置: /var/log/student_status_change/"
|
||||
else
|
||||
error "以下服务启动失败: ${failed_services[*]}"
|
||||
echo ""
|
||||
echo "故障排除:"
|
||||
echo "1. 检查数据库配置: cat data.conf"
|
||||
echo "2. 查看日志文件: tail -f /var/log/student_status_change/*.log"
|
||||
echo "3. 检查数据库连接: mysql -h\$DB_HOST -P\$DB_PORT -u\$DB_USER -p\$DB_PASS \$DB_NAME -e 'SELECT 1;'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Executable
+177
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理服务停止脚本
|
||||
# 用于停止所有相关的处理服务
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${timestamp} [$level] $message"
|
||||
}
|
||||
|
||||
success() {
|
||||
log "${GREEN}SUCCESS${NC}" "$1"
|
||||
}
|
||||
|
||||
error() {
|
||||
log "${RED}ERROR${NC}" "$1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
log "${YELLOW}WARNING${NC}" "$1"
|
||||
}
|
||||
|
||||
# Check if control script exists and is executable
|
||||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||||
error "Control script not found or not executable: $CONTROL_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to stop a service
|
||||
stop_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Stopping $service_desc..."
|
||||
if "$CONTROL_SCRIPT" stop "$service_name"; then
|
||||
success "$service_desc stopped successfully"
|
||||
return 0
|
||||
else
|
||||
warning "$service_desc may not have been running"
|
||||
return 0 # Not treating this as a hard error
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check service status after stop
|
||||
check_service_stopped() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Verifying $service_desc has stopped..."
|
||||
if "$CONTROL_SCRIPT" status "$service_name" | grep -q "is not running"; then
|
||||
success "$service_desc confirmed stopped"
|
||||
return 0
|
||||
else
|
||||
warning "$service_desc may still be running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to force kill if needed
|
||||
force_kill_service() {
|
||||
local service_name="$1"
|
||||
local script_pattern="$2"
|
||||
local service_desc="$3"
|
||||
|
||||
log "INFO" "Force killing $service_desc..."
|
||||
if pkill -f "$script_pattern"; then
|
||||
sleep 2
|
||||
success "$service_desc force killed"
|
||||
return 0
|
||||
else
|
||||
warning "No processes found for $service_desc"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
local force_kill="${1:-false}"
|
||||
|
||||
log "INFO" "=== 学生状态变更处理服务停止脚本 ==="
|
||||
|
||||
if [[ "$force_kill" == "force" ]]; then
|
||||
log "INFO" "Performing force stop of all services..."
|
||||
|
||||
# Force kill all related processes
|
||||
force_kill_service "changes" "process_student_changes.sh" "学生状态变更处理服务"
|
||||
force_kill_service "resume" "process_student_resume.sh" "学生复学处理服务"
|
||||
|
||||
# Clean up lock and PID files
|
||||
log "INFO" "Cleaning up lock and PID files..."
|
||||
rm -f "${SCRIPT_DIR}"/*.lock
|
||||
rm -f "${SCRIPT_DIR}/pids"/*.pid
|
||||
|
||||
success "Force stop completed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "INFO" "Stopping all student status change processing services..."
|
||||
|
||||
# Stop services gracefully
|
||||
stop_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
stop_service "resume" "学生复学处理服务"
|
||||
|
||||
# Wait a moment for services to fully stop
|
||||
sleep 3
|
||||
|
||||
log "INFO" "=== 服务状态验证 ==="
|
||||
|
||||
# Check all services are stopped
|
||||
check_service_stopped "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
check_service_stopped "resume" "学生复学处理服务"
|
||||
|
||||
# Final cleanup
|
||||
log "INFO" "Performing final cleanup..."
|
||||
rm -f "${SCRIPT_DIR}"/*.lock 2>/dev/null || true
|
||||
rm -f "${SCRIPT_DIR}/pids"/*.pid 2>/dev/null || true
|
||||
|
||||
log "INFO" "=== 停止完成 ==="
|
||||
success "所有服务已停止"
|
||||
|
||||
echo ""
|
||||
echo "如果服务未能正常停止,请使用强制停止:"
|
||||
echo " $0 force"
|
||||
echo ""
|
||||
echo "重新启动服务:"
|
||||
echo " ./start_services.sh"
|
||||
}
|
||||
|
||||
# Show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [force]
|
||||
|
||||
停止所有学生状态变更处理服务。
|
||||
|
||||
Options:
|
||||
force 强制杀死所有相关进程并清理锁文件
|
||||
|
||||
Examples:
|
||||
$0 # 正常停止所有服务
|
||||
$0 force # 强制停止所有服务
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
case "${1:-}" in
|
||||
force)
|
||||
main "force"
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
;;
|
||||
"")
|
||||
main
|
||||
;;
|
||||
*)
|
||||
error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,104 @@
|
||||
-- ===========================================
|
||||
-- 学生状态变更处理测试数据
|
||||
-- 用于测试自动化处理脚本
|
||||
-- ===========================================
|
||||
|
||||
-- 注意:请根据实际情况修改学生ID和学号
|
||||
|
||||
-- 插入测试数据到 xg_student_status_change 表
|
||||
-- 状态:0=未处理,1=已处理
|
||||
|
||||
-- 测试休学处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10001, 10001, '20240001', 'XIU_XUE', NOW(),
|
||||
CURDATE(), '学生申请休学', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 测试退学处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10002, 10002, '20240002', 'TUI_XUE', NOW(),
|
||||
CURDATE(), '学生申请退学', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 测试毕业处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10003, 10003, '20240003', 'BI_YE', NOW(),
|
||||
CURDATE(), '学生毕业处理', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 测试复学处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10004, 10004, '20240004', 'FU_XUE', NOW(),
|
||||
CURDATE(), '学生申请复学', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 批量测试数据(休学)
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) SELECT
|
||||
20000 + (@row_number := @row_number + 1),
|
||||
20000 + @row_number,
|
||||
CONCAT('2024', LPAD(@row_number, 4, '0')),
|
||||
'XIU_XUE',
|
||||
NOW(),
|
||||
CURDATE(),
|
||||
CONCAT('批量测试休学-', @row_number),
|
||||
1,
|
||||
'manual',
|
||||
0
|
||||
FROM (SELECT @row_number := 0) r
|
||||
CROSS JOIN (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) nums;
|
||||
|
||||
-- 批量测试数据(退学)
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) SELECT
|
||||
30000 + (@row_number2 := @row_number2 + 1),
|
||||
30000 + @row_number2,
|
||||
CONCAT('2024', LPAD(@row_number2 + 10, 4, '0')),
|
||||
'TUI_XUE',
|
||||
NOW(),
|
||||
CURDATE(),
|
||||
CONCAT('批量测试退学-', @row_number2),
|
||||
1,
|
||||
'manual',
|
||||
0
|
||||
FROM (SELECT @row_number2 := 0) r2
|
||||
CROSS JOIN (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) nums2;
|
||||
|
||||
-- 查询测试数据
|
||||
SELECT
|
||||
'测试数据插入完成' as status,
|
||||
COUNT(*) as total_test_records
|
||||
FROM xg_student_status_change
|
||||
WHERE id >= 10001;
|
||||
|
||||
-- 按类型统计
|
||||
SELECT
|
||||
change_type,
|
||||
COUNT(*) as count
|
||||
FROM xg_student_status_change
|
||||
WHERE id >= 10001
|
||||
GROUP BY change_type
|
||||
ORDER BY change_type;
|
||||
|
||||
-- ===========================================
|
||||
-- 清理测试数据的SQL(执行前请确认)
|
||||
-- ===========================================
|
||||
|
||||
-- DELETE FROM xg_student_status_change WHERE id >= 10001;
|
||||
-- COMMIT;
|
||||
+25
-29
@@ -11,8 +11,8 @@
|
||||
### 📋 核心指导文档
|
||||
- **[01-核心状态修改.md](01-核心状态修改.md)** - 学生学籍状态、用户登录状态
|
||||
- **[02-组织关系处理.md](02-组织关系处理.md)** - 班级干部信息、社团成员关系
|
||||
- **[03-经济资助处理.md](03-经济资助处理.md)** - 奖学金申请、获奖记录、勤工俭学、贫困生认定
|
||||
- **[04-其他业务处理.md](04-其他业务处理.md)** - 住宿管理、心理健康、学生活动、志愿者、实习等
|
||||
- **[03-经济资助处理.md](03-经济资助处理.md)** - 非核心业务,已简化处理
|
||||
- **[04-其他业务处理.md](04-其他业务处理.md)** - 住宿管理退宿处理
|
||||
|
||||
### 🛠️ 实施文档
|
||||
- **[06-完整SQL脚本.md](06-完整SQL脚本.md)** - 完整的数据库处理脚本和事务管理
|
||||
@@ -40,19 +40,20 @@
|
||||
学生退学、休学、毕业处理涉及多个业务模块的联动更新,具体处理内容请参考各分文档:
|
||||
|
||||
### 📋 处理步骤
|
||||
1. **确定变更类型**: 休学(TUI_XUE)/退学(XIU_XUE)/复学(FU_XUE)/毕业(BI_YE)
|
||||
1. **确定变更类型**: 休学(XIU_XUE)/退学(TUI_XUE)/复学(FU_XUE)/毕业(BI_YE)
|
||||
2. **创建状态变更记录**: 插入 `xg_student_status_change` 表记录
|
||||
3. **核心状态修改**: 更新 `xg_student_msg.student_status` 和 `sys_user.status`
|
||||
4. **组织关系处理**: 处理班级干部、社团成员等关系变更
|
||||
5. **经济资助处理**: 处理奖学金、勤工俭学、贫困生认定等业务
|
||||
6. **其他业务处理**: 处理宿舍、心理咨询、学生活动、实习等
|
||||
3. **备份原始数据**: 将相关表数据备份到对应的his表
|
||||
4. **核心状态修改**: 更新 `xg_student_msg.student_status` 和 `sys_user.status`
|
||||
5. **组织关系处理**: 处理班级干部、社团成员等关系变更(仅退学、休学、毕业时)
|
||||
6. **住宿管理处理**: 处理宿舍退宿(仅退学、毕业时)
|
||||
7. **更新处理状态**: 将 `xg_student_status_change.process_status` 设为1
|
||||
8. **数据验证**: 确保所有相关数据已正确处理
|
||||
|
||||
### 🔄 状态映射关系
|
||||
- **休学**: `student_status='2'`,`sys_user.status` 保持不变,可恢复业务
|
||||
- **退学**: `student_status='4'`,`sys_user.status='1'`,终止所有业务
|
||||
- **毕业**: `student_status='5'`,`sys_user.status='1'`,归档处理
|
||||
- **休学**: `student_status='2'`,`sys_user.status='1'`,终止组织关系
|
||||
- **退学**: `student_status='4'`,`sys_user.status='1'`,终止组织关系和住宿
|
||||
- **复学**: `student_status='3'`,`sys_user.status='0'`,恢复账号
|
||||
- **毕业**: `student_status='5'`,`sys_user.status='1'`,终止组织关系和住宿
|
||||
|
||||
### 🏗️ 技术架构
|
||||
基于代码分析,主要涉及以下技术组件:
|
||||
@@ -60,40 +61,35 @@
|
||||
- `XgStudentMsg`: 学生基本信息实体
|
||||
- `XgStudentStatusChange`: 学生状态变更记录实体
|
||||
- `XgClassPosMsg`: 班级干部信息实体
|
||||
- `StglMember`: 社团成员关系实体
|
||||
- `JcbtScholarshipApplication`: 奖学金申请实体
|
||||
- `JcbtWorkStudyApplication`: 勤工俭学申请实体
|
||||
- `JcbtPovertyApplication`: 贫困生认定申请实体
|
||||
- `ClubMember`: 社团成员关系实体
|
||||
- `StglMember`: 志愿者成员关系实体
|
||||
- `XgDormBedStudent`: 宿舍床位分配实体
|
||||
- **业务服务**:
|
||||
- `XgStudentStatusChangeServiceImpl`: 学生状态变更服务
|
||||
- `XgClassPosMsgServiceImpl`: 班级干部管理服务
|
||||
- `XljkConsultationAppointmentServiceImpl`: 心理咨询预约服务
|
||||
- `JcbtScholarshipApplicationServiceImpl`: 奖学金申请服务
|
||||
- `XgDormBedStudentServiceImpl`: 宿舍管理服务
|
||||
- **数据访问**: MyBatis-Plus Mapper接口和XML配置
|
||||
- **事务管理**: Spring `@Transactional` 声明式事务
|
||||
- **状态机**: 通过状态字段值变化实现业务状态流转
|
||||
- **工作流引擎**: Warm-Flow工作流框架处理复杂审批流程
|
||||
- **his表备份**: 所有数据修改前自动备份到历史表
|
||||
|
||||
### 🎯 业务处理策略
|
||||
- ✅ **核心状态**: 必须修改
|
||||
- ✅ **进行中流程**: 全部终止
|
||||
- ✅ **组织关系**: 全部解除
|
||||
- ✅ **历史记录**: 保留(奖惩、考核由班主任管理)
|
||||
- ✅ **关联业务**: 视具体情况终止
|
||||
- ✅ **核心状态**: 必须修改(学籍状态+用户账号状态)
|
||||
- ✅ **his表备份**: 所有修改前备份原始数据
|
||||
- ✅ **组织关系**: 退学、休学、毕业时解除干部和社团关系
|
||||
- ✅ **住宿管理**: 退学、毕业时处理退宿
|
||||
- ✅ **复学处理**: 仅涉及核心状态恢复
|
||||
|
||||
## 📊 数据库表统计
|
||||
|
||||
涉及的数据库表总数:**25个核心表**
|
||||
涉及的数据库表总数:**8个核心表**
|
||||
|
||||
| 模块 | 涉及表数量 | 重要程度 | 核心表名 |
|
||||
|------|-----------|----------|----------|
|
||||
| 核心状态管理 | 3 | ⭐⭐⭐⭐⭐ | `xg_student_msg`, `sys_user`, `xg_student_status_change` |
|
||||
| 组织关系 | 2 | ⭐⭐⭐⭐⭐ | `xg_class_pos_msg`, `stgl_member` |
|
||||
| 经济资助 | 4 | ⭐⭐⭐⭐ | `jcbt_scholarship_application`, `jcbt_scholarship_award`, `jcbt_work_study_application`, `jcbt_poverty_application` |
|
||||
| 住宿管理 | 3 | ⭐⭐⭐⭐⭐ | `xg_dorm_bed_student`, `xg_dorm_application`, `xg_dorm_hygiene_student_score` |
|
||||
| 心理健康 | 4 | ⭐⭐⭐⭐ | `xljk_consultation_appointment`, `xljk_consultation_record`, `xljk_consultation_no_show`, `xljk_evaluation_detail` |
|
||||
| 实践活动 | 4 | ⭐⭐⭐⭐ | `stgl_activity_registration`, `stgl_volunteer_team`, `zsjy_internship_info`, `xg_student_leave` |
|
||||
| 其他信息 | 5 | ⭐⭐⭐ | `xg_dorm_violation`, `sys_oper_log`, `sys_dict_data`, `sys_dict_type`, `flow_instance` |
|
||||
| 组织关系 | 3 | ⭐⭐⭐⭐⭐ | `xg_class_pos_msg`, `club_member`, `stgl_member` |
|
||||
| 住宿管理 | 2 | ⭐⭐⭐⭐⭐ | `xg_dorm_bed_student`, `xg_dorm_bed` |
|
||||
| his表备份 | 8 | ⭐⭐⭐⭐⭐ | 各主表对应的his表 |
|
||||
|
||||
## ⚠️ 重要注意事项
|
||||
|
||||
|
||||
Reference in new issue
Block a user