本分文档详细说明学生退学、休学、毕业、复学处理中的组织关系处理内容,包括班级干部信息和社团成员关系的变更逻辑。
表名: xg_class_pos_msg
主键: id (bigint(20), 雪花ID)
核心关联字段:
class_id: 班级ID,关联 xg_class_msg.idstudent_id: 学生ID,关联 xg_student_msg.idstudent_no: 学号student_name: 学生姓名(冗余字段)基于数据库表结构 xg_class_pos_msg,关键字段如下:
| 字段名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
is_current |
tinyint(1) | 是否现任(0-非现任,1-现任) | 1 |
cadre_status |
char(1) | 职务任职状态(关联stu_cadre_status字典) | 1 |
appointment_date |
date | 任职日期 | - |
term_start_date |
date | 任期开始日期 | - |
term_end_date |
date | 任期结束日期 | NULL |
term_duration |
int(11) | 任期时长(月) | 12 |
dismissal_date |
date | 离任日期 | NULL |
dismissal_reason |
varchar(200) | 离任原因 | NULL |
appointment_method |
varchar(20) | 任命方式(appointment/election/recommendation) | appointment |
系统使用 stu_cadre_status 字典类型,具体定义如下:
| 状态值 | 状态名称 | 说明 | 样式类 |
|---|---|---|---|
1 |
在任 | 正常任职状态 | primary |
2 |
到期 | 任期自然到期 | success |
3 |
辞职 | 干部主动辞职 | warning |
4 |
免职 | 被免去职务 | danger |
5 |
调任 | 职务调整调动 | info |
6 |
休学 | 因学生休学离任 | danger |
关键字段说明 (基于实体类代码分析):
isCurrent: 是否现任 (0-非现任,1-现任)cadreStatus: 学生职务任职状态dismissalDate: 离任日期dismissalReason: 离任原因termStartDate: 任期开始日期termEndDate: 任期结束日期termDuration: 任期时长(月)1. 验证干部信息存在性和状态
2. 计算任期时长 (term_start_date 到 term_end_date)
3. 更新干部状态为非现任 (is_current = 0)
4. 设置离任状态和原因
5. 更新任期结束日期和离任日期
6. 删除用户角色关联 (sys_user_role)
7. 记录操作日志
控制器接口: POST /xgClassPosMsg/xgClassPosMsg/dismiss/{id}
核心方法: XgClassPosMsgServiceImpl.dismissCadre()
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean dismissCadre(Long id, Date termEndDate, String cadreStatus, String dismissalReason) {
// 1. 查询并验证干部信息
XgClassPosMsg classPosMsg = baseMapper.selectById(id);
// 2. 计算任期时长
Long termDuration = calculateTermDuration(classPosMsg.getTermStartDate(), termEndDate);
// 3. 更新干部信息
XgClassPosMsg updateEntity = new XgClassPosMsg();
updateEntity.setId(id);
updateEntity.setTermEndDate(termEndDate);
updateEntity.setTermDuration(termDuration);
updateEntity.setCadreStatus(cadreStatus);
updateEntity.setDismissalReason(dismissalReason);
updateEntity.setDismissalDate(termEndDate);
updateEntity.setIsCurrent(0L); // 设置为非现任
baseMapper.updateById(updateEntity);
// 4. 删除用户角色关联
sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getUserId, classPosMsg.getStudentId()));
return true;
}
文件位置: web/src/views/xg/xsjcxx/xgClassPosMsg/xgClassPosMsg/index.vue
离任按钮: 仅对 is_current = 1 的干部显示
<!-- 离任按钮 -->
<el-tooltip content="离任" placement="top">
<el-button
link
type="warning"
icon="ArrowDown"
@click="handleDismissal(scope.row)"
v-if="scope.row.isCurrent === 1"
></el-button>
</el-tooltip>
<!-- 离任对话框 -->
<el-dialog title="班级干部离任" v-model="dismissalDialog.visible" width="500px" append-to-body>
<el-form ref="dismissalFormRef" :model="dismissalForm" :rules="dismissalRules" label-width="140px">
<!-- 当前信息(只读) -->
<el-form-item label="班级名称" prop="className">
<el-input v-model="dismissalForm.className" disabled />
</el-form-item>
<el-form-item label="学生姓名" prop="studentName">
<el-input v-model="dismissalForm.studentName" disabled />
</el-form-item>
<el-form-item label="任期开始日期" prop="termStartDate">
<el-input v-model="dismissalForm.termStartDate" disabled />
</el-form-item>
<!-- 离任信息(可填写) -->
<el-form-item label="任期结束日期" prop="termEndDate">
<el-date-picker
clearable
v-model="dismissalForm.termEndDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择任期结束日期"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="离任状态" prop="cadreStatus">
<el-select v-model="dismissalForm.cadreStatus" placeholder="请选择离任状态">
<el-option label="到期" value="2" />
<el-option label="辞职" value="3" />
<el-option label="免职" value="4" />
<el-option label="调任" value="5" />
<el-option label="休学" value="6" />
</el-select>
</el-form-item>
<el-form-item label="离任原因" prop="dismissalReason">
<el-input v-model="dismissalForm.dismissalReason" type="textarea" placeholder="请输入离任原因" />
</el-form-item>
</el-form>
</el-dialog>
cadre_status = '6'(休学),is_current = 0,dismissal_reason = '学生休学'cadre_status = '4'(免职),is_current = 0,dismissal_reason = '学生退学'cadre_status = '4'(免职),is_current = 0,dismissal_reason = '学生毕业'-- 参数说明:
-- @student_id: 学生ID
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
-- @operator_id: 操作员ID
-- @dismissal_date: 离任日期 (默认为当前日期)
SET @dismissal_date = COALESCE(@dismissal_date, CURDATE());
-- 1. 更新干部状态(休学)
UPDATE xg_class_pos_msg
SET is_current = 0,
cadre_status = '6', -- 休学状态
term_end_date = @dismissal_date,
dismissal_date = @dismissal_date,
dismissal_reason = '学生休学',
term_duration = TIMESTAMPDIFF(MONTH, term_start_date, @dismissal_date),
update_by = @operator_id,
update_time = NOW()
WHERE student_id = @student_id
AND is_current = 1
AND deleted = 0
AND @change_type = 'XIU_XUE';
-- 2. 更新干部状态(退学/毕业)
UPDATE xg_class_pos_msg
SET is_current = 0,
cadre_status = '4', -- 免职状态
term_end_date = @dismissal_date,
dismissal_date = @dismissal_date,
dismissal_reason = CASE
WHEN @change_type = 'TUI_XUE' THEN '学生退学'
WHEN @change_type = 'BI_YE' THEN '学生毕业'
ELSE '学生状态变更'
END,
term_duration = TIMESTAMPDIFF(MONTH, term_start_date, @dismissal_date),
update_by = @operator_id,
update_time = NOW()
WHERE student_id = @student_id
AND is_current = 1
AND deleted = 0
AND @change_type IN ('TUI_XUE', 'BI_YE');
表名: stgl_member (原名 club_member,现已重构)
主键: id (bigint(20))
核心关联字段:
user_id: 用户ID,关联学生用户IDstudent_no: 学号student_name: 学生姓名(冗余字段)relation_id: 关联ID(社团ID或志愿者队伍ID)member_type: 成员类型(1-社团成员,2-志愿者)系统使用 stgl_member_status 字典类型,具体定义如下:
| 状态值 | 状态名称 | 说明 | 样式类 |
|---|---|---|---|
0 |
待审核 | 申请加入,等待审核 | warning |
1 |
审核中 | 正在审核中 | info |
2 |
已加入 | 正式成员 | success |
3 |
已驳回 | 审核未通过 | danger |
4 |
已退出 | 已退出组织 | danger |
关键字段说明 (基于实体类代码分析):
memberType: 成员类型 (1-社团成员,2-志愿者)userId: 用户ID,对应学生IDstudentNo: 学号studentName: 学生姓名roleType: 角色类型 (社长、副社长、部长、普通成员)joinTime: 加入时间status: 状态 (0-待审核,1-审核中,2-已加入,3-已驳回,4-已退出)所在模块: ruoyi-stgl (社团管理模块)
实体类: StglMember.java
服务类: StglMemberServiceImpl.java
// 社团成员实体类关键字段
@Data
@TableName("stgl_member")
public class StglMember extends TenantEntity {
private Long userId; // 用户ID
private String studentNo; // 学号
private String studentName; // 学生姓名
private Integer memberType; // 成员类型:1-社团成员,2-志愿者
private Long relationId; // 关联ID
private Integer status; // 状态:0-待审核,1-审核中,2-已加入,3-已驳回,4-已退出
private String roleType; // 角色类型
private Date joinTime; // 加入时间
}
管理界面: stgl/member/index.vue
状态显示: 使用字典标签显示成员状态
<!-- 成员状态列 -->
<el-table-column label="状态" align="center" prop="status" width="100">
<template #default="scope">
<dict-tag :options="stgl_member_status" :value="scope.row.status" />
</template>
</el-table-column>
4(已退出),退出原因为"学生休学"4(已退出),退出原因为"学生退学"4(已退出),退出原因为"学生毕业"-- 参数说明:
-- @student_id: 学生ID (对应user_id)
-- @change_type: 变更类型 (XIU_XUE-休学, TUI_XUE-退学, BI_YE-毕业)
-- @operator_id: 操作员ID
-- 更新社团/志愿者成员状态为已退出
UPDATE stgl_member
SET 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 status IN (0, 1, 2) -- 待审核、审核中、已加入
AND deleted = 0;
表名: sys_user_role
关联逻辑: 当干部离任时,需要清理对应的用户角色关联
// 在干部离任时执行角色清理
int deleteCount = sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getUserId, classPosMsg.getStudentId()));
-- 建议在学生状态变更的大事务中包含组织关系处理
START TRANSACTION;
-- 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 = ?, term_end_date = NOW(), dismissal_date = NOW(), dismissal_reason = ? WHERE student_id = ?;
-- 3. 处理社团成员关系(仅退学、休学、毕业时)
UPDATE stgl_member SET status = 4 WHERE user_id = ?;
-- 4. 清理用户角色(如果需要)
DELETE FROM sys_user_role WHERE user_id = ?;
COMMIT;
| 处理类型 | 涉及表数量 | 主要操作 |
|---|---|---|
| 班级干部 | 2 (干部表+角色表) | 更新状态+清理权限 |
| 社团成员 | 1 (成员表) | 更新状态 |
| 总计 | 3个表 | 状态更新+权限清理 |
本分文档详细说明学生状态变更时的组织关系处理逻辑和技术实现,包括班级干部职务和社团成员关系的清理。