最终版提交
This commit is contained in:
parent
dfb1c4a7b7
commit
2a816e4abf
|
|
@ -63,6 +63,7 @@ public class StudyClassUserController extends BaseController
|
|||
|
||||
/**
|
||||
* 根据班级ID查询用户列表(包括老师和学生)
|
||||
* 使用前端传入的分页参数
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('study:classUser:list')")
|
||||
@GetMapping("/list/{classId}")
|
||||
|
|
@ -372,6 +373,12 @@ public class StudyClassUserController extends BaseController
|
|||
}
|
||||
remark.append("班级名称:").append(importData.getClassName());
|
||||
user.setRemark(remark.toString());
|
||||
logger.info("导入数据 - 信息编号={}, 班级名称=[{}], remark=[{}]",
|
||||
importData.getUserId(), importData.getClassName(), user.getRemark());
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("导入数据 - 信息编号={}, 班级名称为空", importData.getUserId());
|
||||
}
|
||||
String studentStatus = convertStudentStatus(importData.getStudentStatus());
|
||||
if (StringUtils.isNotEmpty(studentStatus))
|
||||
|
|
@ -485,16 +492,25 @@ public class StudyClassUserController extends BaseController
|
|||
return null;
|
||||
}
|
||||
String value = studentStatus.trim();
|
||||
// 中文转英文
|
||||
if ("在押".equals(value))
|
||||
{
|
||||
return "incarcerated";
|
||||
}
|
||||
if ("已释放".equals(value))
|
||||
if ("已释放".equals(value) || "释放".equals(value))
|
||||
{
|
||||
return "released";
|
||||
}
|
||||
if ("外出".equals(value))
|
||||
{
|
||||
return "out";
|
||||
}
|
||||
if ("假释".equals(value))
|
||||
{
|
||||
return "parole";
|
||||
}
|
||||
// 如果已经是英文值,直接返回
|
||||
if ("incarcerated".equals(value) || "released".equals(value))
|
||||
if ("incarcerated".equals(value) || "released".equals(value) || "out".equals(value) || "parole".equals(value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ public class StudentImportData
|
|||
@Excel(name = "入监时间", sort = 13, width = 30, dateFormat = "yyyy-MM-dd", prompt = "日期格式:2024-01-01")
|
||||
private Date entryDate;
|
||||
|
||||
/** 状态(在押/已释放) */
|
||||
@Excel(name = "状态", sort = 14, readConverterExp = "在押=在押,已释放=已释放", prompt = "填写:在押 或 已释放")
|
||||
/** 状态(在押/已释放/外出/假释) */
|
||||
@Excel(name = "状态", sort = 14, readConverterExp = "在押=在押,已释放=已释放,释放=释放,外出=外出,假释=假释", prompt = "填写:在押、已释放、外出、假释")
|
||||
private String studentStatus;
|
||||
|
||||
public String getClassName()
|
||||
|
|
|
|||
|
|
@ -869,11 +869,13 @@ public class StudyClassUserServiceImpl implements IStudyClassUserService
|
|||
{
|
||||
if (StringUtils.isNotEmpty(cls.getClassName()))
|
||||
{
|
||||
// 同时存储原始名称和trim后的名称,增加匹配成功率
|
||||
classNameToIdMap.put(cls.getClassName(), cls.getId());
|
||||
classNameToIdMap.put(cls.getClassName().trim(), cls.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("预加载班级映射完成,共 {} 个班级", classNameToIdMap.size());
|
||||
logger.info("预加载班级映射完成,共 {} 个班级,映射内容: {}", allClasses != null ? allClasses.size() : 0, classNameToIdMap);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -1022,51 +1024,96 @@ public class StudyClassUserServiceImpl implements IStudyClassUserService
|
|||
}
|
||||
|
||||
// 尝试分配班级(使用缓存的班级映射,直接插入关联记录)
|
||||
// ✅ 使用原始的信息编号作为userId(因为insertUser后userId可能被自增覆盖)
|
||||
Long studentIdForClass = infoNo;
|
||||
if (StringUtils.isNotEmpty(user.getRemark()))
|
||||
{
|
||||
try
|
||||
{
|
||||
String remark = user.getRemark();
|
||||
logger.info("新增用户班级分配 - 用户ID={}, remark={}", studentIdForClass, remark);
|
||||
int idx = remark.indexOf("班级名称:");
|
||||
if (idx >= 0)
|
||||
{
|
||||
String className = remark.substring(idx + 5).trim();
|
||||
logger.info("新增用户班级分配 - 提取的班级名称=[{}], 长度={}", className, className.length());
|
||||
if (StringUtils.isNotEmpty(className))
|
||||
{
|
||||
// 尝试多种匹配方式
|
||||
Long classId = classNameToIdMap.get(className);
|
||||
if (classId == null)
|
||||
{
|
||||
// 尝试去除所有空白字符后匹配
|
||||
String classNameNoSpace = className.replaceAll("\\s+", "");
|
||||
classId = classNameToIdMap.get(classNameNoSpace);
|
||||
logger.info("新增用户班级分配 - 去空格后尝试匹配: [{}]", classNameNoSpace);
|
||||
}
|
||||
logger.info("新增用户班级分配 - 班级名称=[{}], 查找到的classId={}", className, classId);
|
||||
if (classId != null)
|
||||
{
|
||||
// ✅ 先禁用所有活跃班级(确保一致性,虽然新用户不应该有)
|
||||
studentClassMapper.deactivateAllActiveClassesByStudentId(user.getUserId());
|
||||
// ✅ 先禁用所有活跃班级
|
||||
studentClassMapper.deactivateAllActiveClassesByStudentId(studentIdForClass);
|
||||
|
||||
// 插入学员-班级关联
|
||||
StudyStudentClass studentClass = new StudyStudentClass();
|
||||
studentClass.setStudentId(user.getUserId());
|
||||
studentClass.setClassId(classId);
|
||||
studentClass.setStatus(1); // 在读状态
|
||||
studentClass.setJoinTime(new Date());
|
||||
studentClassMapper.insertStudentClass(studentClass);
|
||||
logger.info("为学员 {} 分配班级 {} 成功", infoNo, className);
|
||||
// ✅ 检查是否已存在该班级关联(可能是之前的记录)
|
||||
StudyStudentClass query = new StudyStudentClass();
|
||||
query.setStudentId(studentIdForClass);
|
||||
query.setClassId(classId);
|
||||
List<StudyStudentClass> existingList = studentClassMapper.selectStudentClassList(query);
|
||||
|
||||
if (existingList != null && !existingList.isEmpty())
|
||||
{
|
||||
// 已存在,更新状态为活跃
|
||||
StudyStudentClass existing = existingList.get(0);
|
||||
existing.setStatus(1);
|
||||
existing.setJoinTime(new Date());
|
||||
studentClassMapper.updateStudentClass(existing);
|
||||
logger.info("为学员 {} 激活已有班级 {} (classId={}) 成功", infoNo, className, classId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 不存在,插入新记录
|
||||
StudyStudentClass studentClass = new StudyStudentClass();
|
||||
studentClass.setStudentId(studentIdForClass);
|
||||
studentClass.setClassId(classId);
|
||||
studentClass.setStatus(1);
|
||||
studentClass.setJoinTime(new Date());
|
||||
studentClassMapper.insertStudentClass(studentClass);
|
||||
logger.info("为学员 {} 分配班级 {} (classId={}) 成功", infoNo, className, classId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 班级不存在,抛出异常
|
||||
throw new ServiceException("班级 [" + className + "] 不存在,请先创建该班级");
|
||||
// 班级不存在,记录警告但不中断
|
||||
logger.warn("班级 [{}] 不存在于映射中,可用班级: {}", className, classNameToIdMap.keySet());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("新增用户班级分配 - remark中未找到'班级名称:'");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.warn("为学员 {} 分配班级时失败: {}", infoNo, ex.getMessage());
|
||||
logger.error("为学员 {} 分配班级时失败: {}", infoNo, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("新增用户班级分配 - remark为空,跳过班级分配");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 用户已存在(可能是正常用户或已删除用户)
|
||||
boolean isDeleted = "2".equals(u.getDelFlag());
|
||||
|
||||
// 如果不支持更新且用户未被删除,报错提示已存在
|
||||
if (!isUpdateSupport && !isDeleted)
|
||||
{
|
||||
throw new ServiceException("信息编号[" + infoNoStr + "]已存在,如需更新请勾选\"更新已存在数据\"");
|
||||
}
|
||||
|
||||
// 强制覆盖所有字段
|
||||
u.setNickName(prisonerName);
|
||||
u.setPrisonArea(user.getPrisonArea());
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
AND u.register_type = 'student'
|
||||
AND u.prison_area = #{prisonArea}
|
||||
AND sc.class_id = #{classId}
|
||||
AND sc.status = 1
|
||||
</select>
|
||||
|
||||
<!-- 根据用户ID列表批量查询用户(不包含数据权限过滤) -->
|
||||
|
|
@ -297,8 +298,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="studentStatus != null and studentStatus != ''">student_status,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="userId != null and userId != ''">#{userId},</if>
|
||||
<if test="deptId != null and deptId != ''">#{deptId},</if>
|
||||
<if test="userId != null and userId != 0">#{userId},</if>
|
||||
<if test="deptId != null and deptId != 0">#{deptId},</if>
|
||||
<if test="userName != null and userName != ''">#{userName},</if>
|
||||
<choose>
|
||||
<when test="nickName != null and nickName != ''">#{nickName}</when>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 根据班级ID查询用户列表
|
||||
// 根据班级ID查询用户列表(后端返回全部数据,前端分页)
|
||||
export function listClassUsers(classId) {
|
||||
return request({
|
||||
url: '/study/classUser/list/' + classId,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 99999
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -886,26 +886,28 @@ export default {
|
|||
}
|
||||
});
|
||||
|
||||
// ✅ 自动设置检测到的监区并加载班级选项(但不重置当前选择)
|
||||
if (detectedPrisonArea) {
|
||||
this.filterPrisonArea = detectedPrisonArea;
|
||||
console.log('[课程分配编辑] 自动设置监区:', detectedPrisonArea);
|
||||
// 手动加载该监区的班级选项(不调用onPrisonChange,避免重置选择)
|
||||
getClassesByPrison(detectedPrisonArea).then(res => {
|
||||
this.classOptions = (res.data || []).map(item => ({
|
||||
...item,
|
||||
id: Number(item.id)
|
||||
}));
|
||||
console.log('[课程分配编辑] 班级选项已加载:', this.classOptions.length);
|
||||
}).catch(() => {
|
||||
this.classOptions = [];
|
||||
});
|
||||
}
|
||||
// ✅ 自动设置检测到的监区并加载班级选项(等待加载完成后再处理学生)
|
||||
const loadClassOptionsPromise = detectedPrisonArea
|
||||
? getClassesByPrison(detectedPrisonArea).then(res => {
|
||||
this.filterPrisonArea = detectedPrisonArea;
|
||||
this.classOptions = (res.data || []).map(item => ({
|
||||
...item,
|
||||
id: Number(item.id)
|
||||
}));
|
||||
console.log('[课程分配编辑] 自动设置监区:', detectedPrisonArea);
|
||||
console.log('[课程分配编辑] 班级选项已加载:', this.classOptions.length);
|
||||
}).catch(() => {
|
||||
this.classOptions = [];
|
||||
})
|
||||
: Promise.resolve();
|
||||
|
||||
// ✅ 等待班级选项加载完成后再处理学生
|
||||
loadClassOptionsPromise.then(() => {
|
||||
// 根据学生ID查找他们所属的班级,然后按班级分组
|
||||
const classStudentMap = new Map(); // Map<classId, { classId, className, students: [] }>
|
||||
console.log('[课程分配编辑] 开始查询学生班级,学生总数:', studentIds.size);
|
||||
console.log('[课程分配编辑] allStudentOptions数量:', this.allStudentOptions.length);
|
||||
console.log('[课程分配编辑] classOptions数量:', this.classOptions.length);
|
||||
const studentPromises = Array.from(studentIds).map(studentId => {
|
||||
return getClassesByStudentId(studentId).then(classResponse => {
|
||||
const userClassId = classResponse && classResponse.data ? Number(classResponse.data) : null;
|
||||
|
|
@ -1001,7 +1003,8 @@ export default {
|
|||
this.$modal.msgError("处理学生分组失败: " + (error.message || error));
|
||||
this.open = false;
|
||||
});
|
||||
}).catch(error => {
|
||||
}); // 闭合 loadClassOptionsPromise.then
|
||||
}).catch(error => {
|
||||
console.error('获取课程分配列表失败:', error);
|
||||
this.$modal.msgError("获取课程分配信息失败: " + (error.message || error));
|
||||
this.open = false;
|
||||
|
|
|
|||
|
|
@ -40,11 +40,6 @@
|
|||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px">
|
||||
<el-option v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学员状态" prop="studentStatus">
|
||||
<el-select v-model="queryParams.studentStatus" placeholder="学员状态" clearable style="width: 240px">
|
||||
<el-option v-for="dict in uniqueStudentStatusDicts" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
|
|
@ -314,6 +309,16 @@
|
|||
<el-date-picker v-model="form.entryDate" type="date" placeholder="选择入监时间" value-format="yyyy-MM-dd" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="studentStatus">
|
||||
<el-select v-model="form.studentStatus" placeholder="请选择状态" style="width: 100%">
|
||||
<el-option label="在押" value="incarcerated"></el-option>
|
||||
<el-option label="外出" value="out"></el-option>
|
||||
<el-option label="假释" value="parole"></el-option>
|
||||
<el-option label="释放" value="released"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
|
|
@ -1243,6 +1248,11 @@ export default {
|
|||
},
|
||||
/** 提交按钮(新增/编辑学员) */
|
||||
submitForm() {
|
||||
// ✅ 如果手动输入了信息编号,将其设置为userId
|
||||
if (this.form.manualUserId && !this.form.userId) {
|
||||
this.form.userId = Number(this.form.manualUserId);
|
||||
}
|
||||
|
||||
// ✅ 自动生成userName(学员不需要登录账号,但后端必填)
|
||||
// 优先使用信息编号,没有则用昵称
|
||||
if (!this.form.userName) {
|
||||
|
|
@ -1278,8 +1288,8 @@ export default {
|
|||
return Promise.resolve();
|
||||
};
|
||||
|
||||
// 编辑模式
|
||||
if (this.form.userId != null && this.form.userId !== undefined) {
|
||||
// 编辑模式(使用isEditMode判断,而不是userId)
|
||||
if (this.isEditMode) {
|
||||
updateUser(this.form).then(response => {
|
||||
const updated = response.data || this.form;
|
||||
const userId = updated.userId || this.form.userId;
|
||||
|
|
@ -1290,7 +1300,15 @@ export default {
|
|||
});
|
||||
});
|
||||
} else {
|
||||
// 新增模式
|
||||
// 新增模式 - 检查信息编号是否已存在
|
||||
if (this.form.userId) {
|
||||
// 检查userId是否已存在
|
||||
const existingUser = this.userList.find(u => u.userId == this.form.userId);
|
||||
if (existingUser) {
|
||||
this.$modal.msgError(`信息编号 ${this.form.userId} 已存在,请使用其他编号`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
addUser(this.form).then(response => {
|
||||
const created = response.data || {};
|
||||
const userId = created.userId;
|
||||
|
|
@ -1342,7 +1360,7 @@ export default {
|
|||
classAssignMode: 'auto',
|
||||
classId: undefined,
|
||||
originalClassId: undefined,
|
||||
studentStatus: undefined
|
||||
studentStatus: 'incarcerated'
|
||||
};
|
||||
this.isStudentForm = false;
|
||||
this.isEditMode = false;
|
||||
|
|
|
|||
|
|
@ -410,8 +410,11 @@ export default {
|
|||
};
|
||||
},
|
||||
created() {
|
||||
// 首屏只加载课件列表,减少首次进入延迟
|
||||
// 加载课件列表和搜索下拉框选项
|
||||
this.getList();
|
||||
this.getSubjectOptions();
|
||||
this.getCourseOptions();
|
||||
this.getClassOptions();
|
||||
},
|
||||
methods: {
|
||||
/** 查询课件列表 */
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
<el-option label="全部" value="" />
|
||||
<el-option label="单选题" value="single" />
|
||||
<el-option label="多选题" value="multiple" />
|
||||
<el-option label="判断题" value="judge" />
|
||||
<el-option label="填空题" value="fill" />
|
||||
<el-option label="简答题" value="essay" />
|
||||
</el-select>
|
||||
|
|
@ -123,7 +122,6 @@
|
|||
<el-select v-model="itemForm.questionType" placeholder="请选择题型" style="width: 100%">
|
||||
<el-option label="单选题" value="single" />
|
||||
<el-option label="多选题" value="multiple" />
|
||||
<el-option label="判断题" value="judge" />
|
||||
<el-option label="填空题" value="fill" />
|
||||
<el-option label="简答题" value="essay" />
|
||||
</el-select>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
-- ============================================
|
||||
-- 删除 user_id >= 100 的用户及其关联数据
|
||||
-- 只删除:用户、学习记录、语音评测、课程分配
|
||||
-- 只删除:用户、学习记录、语音评测、课程分配、班级关联、角色关联
|
||||
-- 保留:admin(1), ry(2) 等系统用户
|
||||
-- 执行前请先备份数据库!
|
||||
-- ============================================
|
||||
|
|
@ -31,7 +31,14 @@ DELETE FROM voice_evaluation WHERE student_id >= 100;
|
|||
DELETE FROM course_assignment WHERE student_id >= 100;
|
||||
|
||||
-- ============================================
|
||||
-- 4. 删除用户
|
||||
-- 4. 删除班级关联和角色关联
|
||||
-- ============================================
|
||||
|
||||
DELETE FROM student_class WHERE student_id >= 100;
|
||||
DELETE FROM sys_user_role WHERE user_id >= 100;
|
||||
|
||||
-- ============================================
|
||||
-- 5. 删除用户
|
||||
-- ============================================
|
||||
|
||||
DELETE FROM sys_user WHERE user_id >= 100;
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue
Block a user