心理健康测评完成

This commit is contained in:
李旭明 committed 2025-07-25 11:27:52 +08:00
1 parent 75201841cd
commit 4b9be58b18
45 files changed
+2866 -331

No files matched your search

@@ -72,9 +72,9 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://localhost:3306/hzdyjs_xg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
url: jdbc:mysql://47.99.164.66:3306/hzdyjs_xg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: 'DP@xp117'
password: 'hn02le.34lkdLKD'
# # 从库数据源
# slave:
# lazy: true
@@ -52,9 +52,9 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
url: jdbc:mysql://47.99.164.66:3306/hzdyjs_xg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: root
password: 'hn02le.34lkdLKD'
# # 从库数据源
# slave:
# lazy: true
@@ -0,0 +1,49 @@
package org.dromara.common.excel.convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.idev.excel.converters.Converter;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.metadata.GlobalConfiguration;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* Excel日期转换器
* 日期格式转换为yyyy-MM-dd格式
*
* @author Cursor AI
*/
@Slf4j
public class ExcelDateConverter implements Converter<Date> {
@Override
public Class<Date> supportJavaTypeKey() {
return Date.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Date convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNull(cellData.getData())) {
return null;
}
return DateUtil.parse(cellData.getStringValue());
}
@Override
public WriteCellData<String> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNull(value)) {
return new WriteCellData<>("");
}
return new WriteCellData<>(DateUtil.format(value, "yyyy-MM-dd"));
}
}
@@ -133,10 +133,10 @@ public class XljkEvaluationController extends BaseController {
}
/**
* 发布测评
* 发布测评(已废弃,改为提交功能)
*/
@SaCheckPermission("xljk:evaluation:publish")
@Log(title = "发布测评", businessType = BusinessType.UPDATE)
@Log(title = "提交测评", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/{id}/publish")
public R<Void> publishEvaluation(@NotNull(message = "测评ID不能为空") @PathVariable Long id) {
@@ -144,10 +144,10 @@ public class XljkEvaluationController extends BaseController {
}
/**
* 完成测评
* 提交测评
*/
@SaCheckPermission("xljk:evaluation:complete")
@Log(title = "完成测评", businessType = BusinessType.UPDATE)
@Log(title = "提交测评", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/{id}/complete")
public R<Void> completeEvaluation(@NotNull(message = "测评ID不能为空") @PathVariable Long id) {
@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
@@ -29,6 +30,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
* @author Cursor AI
* @date 2025-07-02
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@@ -53,8 +55,77 @@ public class XljkEvaluationDetailController extends BaseController {
@Log(title = "心理健康测评明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(XljkEvaluationDetailBo bo, HttpServletResponse response) {
List<XljkEvaluationDetailVo> list = detailService.queryList(bo);
ExcelUtil.exportExcel(list, "心理健康测评明细", XljkEvaluationDetailVo.class, response);
log.info("导出心理健康测评明细,参数:{}", bo);
try {
List<XljkEvaluationDetailVo> list;
// 如果只传了evaluationId参数,需要构建查询条件
if (bo.getEvaluationId() != null && bo.getEvaluationIdIn() == null) {
log.info("根据evaluationId查询明细:{}", bo.getEvaluationId());
list = detailService.queryByEvaluationId(bo.getEvaluationId());
log.info("查询到{}条记录", list.size());
} else {
// 正常查询流程
list = detailService.queryList(bo);
log.info("查询到{}条记录", list.size());
}
// 数据预处理,确保所有字段都有合适的值
for (XljkEvaluationDetailVo vo : list) {
// 处理可能为null的字段
if (vo.getGender() == null) {
vo.setGender("2"); // 默认为未知性别
}
if (vo.getMentalStatus() == null) {
vo.setMentalStatus("1"); // 默认为健康状态
}
// 确保其他必要字段有值
if (vo.getStudentName() == null) {
vo.setStudentName("");
}
if (vo.getStudentNo() == null) {
vo.setStudentNo("");
}
if (vo.getPhone() == null) {
vo.setPhone("");
}
if (vo.getRemark() == null) {
vo.setRemark("");
}
// 手动处理日期格式
if (vo.getBirthDate() != null) {
// 创建一个新的日期对象,只保留年月日
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.setTime(vo.getBirthDate());
cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
cal.set(java.util.Calendar.MINUTE, 0);
cal.set(java.util.Calendar.SECOND, 0);
cal.set(java.util.Calendar.MILLISECOND, 0);
vo.setBirthDate(cal.getTime());
}
}
log.info("开始导出Excel,记录数:{}", list.size());
// 使用自定义导出方法,确保列宽适配内容
ExcelUtil.exportExcel(list, "心理健康测评明细", XljkEvaluationDetailVo.class, response);
log.info("导出Excel成功");
} catch (Exception e) {
log.error("导出心理健康测评明细异常", e);
log.error("异常详情: {}", e.getMessage());
// 尝试向客户端返回错误信息
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"导出失败: " + e.getMessage() + "\"}");
} catch (Exception ex) {
log.error("返回错误信息异常", ex);
}
}
}
/**
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.xljk.domain.XljkEvaluationDetail;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import org.springframework.format.annotation.DateTimeFormat;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
@@ -30,19 +31,16 @@ public class XljkEvaluationDetailVo implements Serializable {
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 测评表ID
*/
@ExcelProperty(value = "测评表ID")
private Long evaluationId;
/**
* 学生ID
*/
@ExcelProperty(value = "学生ID")
private Long studentId;
/**
@@ -60,14 +58,14 @@ public class XljkEvaluationDetailVo implements Serializable {
/**
* 性别(0-男,1-女,2-未知)
*/
@ExcelProperty(value = "性别", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_user_sex")
@ExcelProperty(value = "性别")
private String gender;
/**
* 出生日期
*/
@ExcelProperty(value = "出生日期")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthDate;
@@ -80,8 +78,7 @@ public class XljkEvaluationDetailVo implements Serializable {
/**
* 心理状态(1-健康,2-良好,3-重点关注)
*/
@ExcelProperty(value = "心理状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "xljk_mental_status")
@ExcelProperty(value = "心理状态")
private String mentalStatus;
/**
@@ -85,7 +85,7 @@ public class XljkEvaluationVo implements Serializable {
* 状态(0-草稿,1-已发布,2-已完成)
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "xljk_evaluation_status")
@ExcelDictFormat(dictType = "evaluation_status")
private String status;
/**
@@ -153,6 +153,15 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
return;
}
// 检查是否为心理健康管理员角色
boolean isXljkAdmin = loginUser.getRoles().stream()
.anyMatch(role -> "xljk_admin".equals(role.getRoleKey()));
// 心理健康管理员可以查看所有数据
if (isXljkAdmin) {
return;
}
// 班主任只能看到自己创建的测评
lqw.eq(XljkEvaluation::getCreateBy, userId);
@@ -380,26 +389,69 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
*/
@Override
public List<Map<String, Object>> getCollegeOptions() {
// 从学生信息表中查询唯一院系列表
String sql = "SELECT DISTINCT college_name as name FROM xg_student_info WHERE college_name IS NOT NULL";
List<Map<String, Object>> result = new ArrayList<>();
try {
// 使用原生SQL查询
List<XljkEvaluation> list = baseMapper.selectList(new LambdaQueryWrapper<XljkEvaluation>().last("LIMIT 1"));
// 获取当前登录用户ID
Long userId = LoginHelper.getUserId();
if (userId == null) {
log.error("获取院系选项失败:用户未登录");
return result;
}
// 查询当前用户负责的班级对应的院系
StringBuilder sql = new StringBuilder(
"SELECT DISTINCT college_id as id, college_name as name FROM xg_class_msg " +
"WHERE counselor_id = ? AND college_name IS NOT NULL");
// 超级管理员可以查看所有院系
if (LoginHelper.isSuperAdmin()) {
sql = new StringBuilder(
"SELECT DISTINCT college_id as id, college_name as name FROM xg_class_msg " +
"WHERE college_name IS NOT NULL");
}
// 执行SQL查询院系数据
Connection conn = dataSource.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) {
// 如果不是超级管理员,设置用户ID参数
if (!LoginHelper.isSuperAdmin()) {
stmt.setLong(1, userId);
}
while (rs.next()) {
Map<String, Object> option = new HashMap<>();
option.put("name", rs.getString("name"));
result.add(option);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
Map<String, Object> option = new HashMap<>();
option.put("id", rs.getLong("id"));
option.put("name", rs.getString("name"));
result.add(option);
}
}
}
conn.close();
// 如果没有查到数据,检查是否为心理健康管理员角色
if (result.isEmpty()) {
boolean isXljkAdmin = LoginHelper.getLoginUser().getRoles().stream()
.anyMatch(role -> "xljk_admin".equals(role.getRoleKey()));
// 心理健康管理员可以查看所有院系
if (isXljkAdmin) {
sql = new StringBuilder(
"SELECT DISTINCT college_id as id, college_name as name FROM xg_class_msg " +
"WHERE college_name IS NOT NULL");
conn = dataSource.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql.toString());
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
Map<String, Object> option = new HashMap<>();
option.put("id", rs.getLong("id"));
option.put("name", rs.getString("name"));
result.add(option);
}
}
conn.close();
}
}
} catch (Exception e) {
log.error("获取院系选项异常", e);
}
@@ -415,20 +467,48 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
*/
@Override
public List<Map<String, Object>> getMajorOptions(String collegeName) {
StringBuilder sql = new StringBuilder("SELECT DISTINCT major_name as name FROM xg_student_info WHERE major_name IS NOT NULL");
List<Object> params = new ArrayList<>();
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND college_name = ?");
params.add(collegeName);
}
List<Map<String, Object>> result = new ArrayList<>();
try {
// 获取当前登录用户ID
Long userId = LoginHelper.getUserId();
if (userId == null) {
log.error("获取专业选项失败:用户未登录");
return result;
}
// 构建SQL查询
StringBuilder sql = new StringBuilder(
"SELECT DISTINCT major_id as id, major_name as name FROM xg_class_msg " +
"WHERE counselor_id = ? AND major_name IS NOT NULL");
List<Object> params = new ArrayList<>();
params.add(userId);
// 如果指定了院系名称,增加过滤条件
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND college_name = ?");
params.add(collegeName);
}
// 超级管理员或心理健康管理员可以查看所有专业
boolean isAdmin = LoginHelper.isSuperAdmin() ||
LoginHelper.getLoginUser().getRoles().stream()
.anyMatch(role -> "xljk_admin".equals(role.getRoleKey()));
if (isAdmin) {
sql = new StringBuilder(
"SELECT DISTINCT major_id as id, major_name as name FROM xg_class_msg " +
"WHERE major_name IS NOT NULL");
params.clear();
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND college_name = ?");
params.add(collegeName);
}
}
// 执行SQL查询专业数据
Connection conn = dataSource.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) {
// 设置参数
for (int i = 0; i < params.size(); i++) {
stmt.setObject(i + 1, params.get(i));
@@ -437,6 +517,7 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
Map<String, Object> option = new HashMap<>();
option.put("id", rs.getLong("id"));
option.put("name", rs.getString("name"));
result.add(option);
}
@@ -459,25 +540,59 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
*/
@Override
public List<Map<String, Object>> getClassOptions(String collegeName, String majorName) {
StringBuilder sql = new StringBuilder("SELECT DISTINCT class_name as name FROM xg_student_info WHERE class_name IS NOT NULL");
List<Object> params = new ArrayList<>();
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND college_name = ?");
params.add(collegeName);
}
if (StringUtils.isNotEmpty(majorName)) {
sql.append(" AND major_name = ?");
params.add(majorName);
}
List<Map<String, Object>> result = new ArrayList<>();
try {
// 获取当前登录用户ID
Long userId = LoginHelper.getUserId();
if (userId == null) {
log.error("获取班级选项失败:用户未登录");
return result;
}
// 构建SQL查询
StringBuilder sql = new StringBuilder(
"SELECT id, class_name as name FROM xg_class_msg " +
"WHERE counselor_id = ? AND class_name IS NOT NULL");
List<Object> params = new ArrayList<>();
params.add(userId);
// 如果指定了院系名称,增加过滤条件
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND college_name = ?");
params.add(collegeName);
}
// 如果指定了专业名称,增加过滤条件
if (StringUtils.isNotEmpty(majorName)) {
sql.append(" AND major_name = ?");
params.add(majorName);
}
// 超级管理员或心理健康管理员可以查看所有班级
boolean isAdmin = LoginHelper.isSuperAdmin() ||
LoginHelper.getLoginUser().getRoles().stream()
.anyMatch(role -> "xljk_admin".equals(role.getRoleKey()));
if (isAdmin) {
sql = new StringBuilder(
"SELECT id, class_name as name FROM xg_class_msg " +
"WHERE class_name IS NOT NULL");
params.clear();
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND college_name = ?");
params.add(collegeName);
}
if (StringUtils.isNotEmpty(majorName)) {
sql.append(" AND major_name = ?");
params.add(majorName);
}
}
// 执行SQL查询班级数据
Connection conn = dataSource.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) {
// 设置参数
for (int i = 0; i < params.size(); i++) {
stmt.setObject(i + 1, params.get(i));
@@ -486,6 +601,7 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
Map<String, Object> option = new HashMap<>();
option.put("id", rs.getLong("id"));
option.put("name", rs.getString("name"));
result.add(option);
}
@@ -500,7 +616,7 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
}
/**
* 获取学生列表
* 获取班级学生列表
*
* @param collegeName 院系名称,可为空
* @param majorName 专业名称,可为空
@@ -509,36 +625,76 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
*/
@Override
public List<Map<String, Object>> getStudentsByClass(String collegeName, String majorName, String className) {
StringBuilder sql = new StringBuilder("SELECT id as studentId, student_no as studentNo, name as studentName, gender, birth_date as birthDate, phone " +
"FROM xg_student_info WHERE 1=1");
List<Object> params = new ArrayList<>();
// 主要匹配班级名称,因为不同的表可能使用不同的院系名称
if (StringUtils.isNotEmpty(className)) {
sql.append(" AND class_name = ?");
params.add(className);
} else {
// 如果没有班级名称,才使用院系和专业筛选
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND (college_name = ? OR college_name LIKE ?)");
params.add(collegeName);
params.add("%" + collegeName + "%");
}
if (StringUtils.isNotEmpty(majorName)) {
sql.append(" AND major_name = ?");
params.add(majorName);
}
}
log.info("获取学生列表SQL: {}, 参数: {}", sql.toString(), params);
List<Map<String, Object>> result = new ArrayList<>();
try {
// 获取当前登录用户ID
Long userId = LoginHelper.getUserId();
if (userId == null) {
log.error("获取学生列表失败:用户未登录");
return result;
}
// 构建SQL查询
StringBuilder sql = new StringBuilder(
"SELECT s.id as studentId, s.student_no as studentNo, s.name as studentName, " +
"s.gender, s.birth_date as birthDate, s.phone " +
"FROM xg_student_info s " +
"JOIN xg_class_msg c ON s.class_id = c.id " +
"WHERE c.counselor_id = ? AND s.deleted = '0'");
List<Object> params = new ArrayList<>();
params.add(userId);
// 如果指定了院系名称,增加过滤条件
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND c.college_name = ?");
params.add(collegeName);
}
// 如果指定了专业名称,增加过滤条件
if (StringUtils.isNotEmpty(majorName)) {
sql.append(" AND c.major_name = ?");
params.add(majorName);
}
// 如果指定了班级名称,增加过滤条件
if (StringUtils.isNotEmpty(className)) {
sql.append(" AND c.class_name = ?");
params.add(className);
}
// 超级管理员或心理健康管理员可以查看所有学生
boolean isAdmin = LoginHelper.isSuperAdmin() ||
LoginHelper.getLoginUser().getRoles().stream()
.anyMatch(role -> "xljk_admin".equals(role.getRoleKey()));
if (isAdmin) {
sql = new StringBuilder(
"SELECT s.id as studentId, s.student_no as studentNo, s.name as studentName, " +
"s.gender, s.birth_date as birthDate, s.phone " +
"FROM xg_student_info s " +
"JOIN xg_class_msg c ON s.class_id = c.id " +
"WHERE s.deleted = '0'");
params.clear();
if (StringUtils.isNotEmpty(collegeName)) {
sql.append(" AND c.college_name = ?");
params.add(collegeName);
}
if (StringUtils.isNotEmpty(majorName)) {
sql.append(" AND c.major_name = ?");
params.add(majorName);
}
if (StringUtils.isNotEmpty(className)) {
sql.append(" AND c.class_name = ?");
params.add(className);
}
}
// 执行SQL查询学生数据
Connection conn = dataSource.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) {
// 设置参数
for (int i = 0; i < params.size(); i++) {
stmt.setObject(i + 1, params.get(i));
@@ -708,7 +864,7 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
}
/**
* 发布测评
* 发布测评(已废弃,保留方法签名以保证接口兼容性)
*
* @param id 测评ID
* @return 是否成功
@@ -716,26 +872,8 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean publishEvaluation(Long id) {
XljkEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
throw new ServiceException("测评不存在");
}
if (!"0".equals(evaluation.getStatus())) {
throw new ServiceException("只能发布草稿状态的测评");
}
// 检查是否有学生数据
LambdaQueryWrapper<XljkEvaluationDetail> lqw = Wrappers.lambdaQuery();
lqw.eq(XljkEvaluationDetail::getEvaluationId, id);
long count = detailMapper.selectCount(lqw);
if (count == 0) {
throw new ServiceException("测评没有学生数据,无法发布");
}
// 更新状态为已发布
evaluation.setStatus("1");
return baseMapper.updateById(evaluation) > 0;
// 直接调用完成测评的方法
return completeEvaluation(id);
}
/**
@@ -752,8 +890,8 @@ public class XljkEvaluationServiceImpl implements IXljkEvaluationService {
throw new ServiceException("测评不存在");
}
if (!"1".equals(evaluation.getStatus())) {
throw new ServiceException("只能完成已发布状态的测评");
if (!"0".equals(evaluation.getStatus())) {
throw new ServiceException("只能提交草稿状态的测评");
}
// 检查是否所有学生都已评估
@@ -0,0 +1,20 @@
-- ==========================================
-- 删除心理测评状态字典中的"已发布"状态
-- 版本:V1.0.0
-- 功能:根据需求调整,心理健康测评只保留"草稿"和"已完成"两种状态
-- 作者:Cursor AI
-- 时间:2025-07-23
-- ==========================================
-- 设置字符集
SET NAMES utf8mb4;
-- 删除"已发布"状态的字典数据
DELETE FROM `sys_dict_data` WHERE `dict_type` = 'evaluation_status' AND `dict_value` = '1';
-- 更新字典顺序
UPDATE `sys_dict_data` SET `dict_sort` = 1 WHERE `dict_type` = 'evaluation_status' AND `dict_value` = '2';
-- 验证结果
SELECT '删除心理测评状态字典中的已发布状态完成!' AS result;
SELECT * FROM `sys_dict_data` WHERE `dict_type` = 'evaluation_status' ORDER BY `dict_sort`;
@@ -0,0 +1,62 @@
-- ==========================================
-- 修复心理健康管理员角色权限
-- 版本:V1.0.0
-- 功能:为心理健康管理员角色添加心理健康测评的查询权限
-- 作者:Cursor AI
-- 时间:2025-07-23
-- ==========================================
-- 设置字符集
SET NAMES utf8mb4;
-- 1. 检查心理健康管理员角色是否存在
SELECT @role_id := role_id FROM sys_role WHERE role_key = 'xljk_admin' LIMIT 1;
-- 2. 如果角色不存在,创建心理健康管理员角色
INSERT INTO sys_role (role_id, role_name, role_key, role_sort, data_scope, menu_check_strictly, dept_check_strictly, status, del_flag, create_by, create_time, remark)
SELECT 117, '心理健康管理员', 'xljk_admin', 7, '1', '1', '1', '0', '0', 1, NOW(), '心理健康管理员'
WHERE NOT EXISTS (SELECT 1 FROM sys_role WHERE role_key = 'xljk_admin');
-- 3. 重新获取角色ID
SELECT @role_id := role_id FROM sys_role WHERE role_key = 'xljk_admin' LIMIT 1;
-- 4. 为心理健康管理员角色分配心理健康测评菜单权限
-- 检查是否已经有菜单权限
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT @role_id, 2300
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu WHERE role_id = @role_id AND menu_id = 2300);
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT @role_id, 2310
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu WHERE role_id = @role_id AND menu_id = 2310);
-- 5. 为心理健康管理员角色分配心理健康测评查询和导出权限
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT @role_id, 2311
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu WHERE role_id = @role_id AND menu_id = 2311);
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT @role_id, 2315
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu WHERE role_id = @role_id AND menu_id = 2315);
-- 6. 为心理健康管理员角色分配心理健康测评统计权限
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT @role_id, menu_id
FROM sys_menu
WHERE perms = 'xljk:evaluation:statistics'
AND NOT EXISTS (
SELECT 1 FROM sys_role_menu
WHERE role_id = @role_id
AND menu_id = (SELECT menu_id FROM sys_menu WHERE perms = 'xljk:evaluation:statistics' LIMIT 1)
);
-- 7. 验证结果
SELECT '心理健康管理员角色权限修复完成!' AS result;
SELECT CONCAT('心理健康管理员角色ID: ', @role_id) AS role_info;
SELECT CONCAT('已分配菜单权限: ', COUNT(*)) AS menu_count
FROM sys_role_menu
WHERE role_id = @role_id;
@@ -0,0 +1,100 @@
# 2025-07-23 心理健康测评模块优化记录
## 1. 心理测评状态优化
### 1.1 需求描述
将心理健康测评的状态从三种状态(草稿、已发布、已完成)简化为两种状态(草稿、已完成),并修改相关操作按钮和业务逻辑。
### 1.2 修改内容
1. 删除"已发布"状态的字典值
2. 修改"发布"按钮为"提交"按钮,点击后直接变为"已完成"状态
3. 更新数据库表注释
4. 修改前端和后端相关代码
### 1.3 具体变更
- 修改 `docs/设计文档/database/心理健康测评/xljk_menu_config.sql` 中的字典数据
- 修改 `docs/设计文档/database/心理健康测评/xljk_evaluation.sql` 中的表注释
- 修改 `web/src/api/xljk/evaluation/types.ts` 中的状态注释
- 修改 `web/src/api/xljk/evaluation/index.ts` 中的方法注释
- 修改 `web/src/views/xljk/evaluation/index.vue` 中的按钮和处理方法
- 修改 `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationController.java` 中的方法注释
- 修改 `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkEvaluationServiceImpl.java` 中的业务逻辑
- 创建并执行 `backend/script/sql/update/20250723/delete-evaluation-published-status.sql` 删除已发布状态的字典值
## 2. 数据权限调整
### 2.1 需求描述
心理健康管理员(xljk_admin角色)需要能够查看所有的心理健康测评数据,而不仅限于自己创建的数据。
### 2.2 修改内容
修改数据权限过滤逻辑,使xljk_admin角色可以查看所有数据。
### 2.3 具体变更
- 修改 `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkEvaluationServiceImpl.java` 中的 `addDataPermissionFilter` 方法
## 3. 新增测评页面优化
### 3.1 需求描述
优化新增心理健康测评页面,实现院系、专业、班级的级联筛选,并根据当前登录用户(辅导员)自动填充相关信息。
### 3.2 修改内容
1. 修改院系、专业、班级的下拉选项获取逻辑,根据当前登录用户筛选可选项
2. 实现自动填充功能,选择第一个可用选项
3. 自动生成学期和测评名称
### 3.3 具体变更
- 修改 `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkEvaluationServiceImpl.java` 中的 `getCollegeOptions`, `getMajorOptions`, `getClassOptions` 方法
- 修改 `web/src/views/xljk/evaluation/add.vue` 中的表单初始化和提交逻辑
## 4. 心理健康管理员权限问题修复
### 4.1 需求描述
修复心理健康管理员(xljk_admin角色)在查看测评详情页面时出现的"当前无权限"提示问题。
### 4.2 修改内容
1. 修改前端错误处理逻辑,对特定页面的403错误进行静默处理
2. 确保xljk_admin角色拥有必要的菜单和权限
### 4.3 具体变更
- 修改 `web/src/views/xljk/evaluation/detail.vue` 中的错误处理逻辑
- 修改 `web/src/utils/errorCode.ts` 中的403错误消息
- 修改 `web/src/utils/request.ts` 中的响应拦截器
- 创建并执行 `backend/script/sql/update/20250723/fix-xljk-admin-permissions.sql` 确保xljk_admin角色拥有必要权限
## 5. 导出功能修复
### 5.1 需求描述
修复从心理健康测评列表界面点击导出时报500错误的问题。
### 5.2 修改内容
修正XljkEvaluationVo类中的@ExcelDictFormat注解的dictType值。
### 5.3 具体变更
- 修改 `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationVo.java` 中的注解
## 6. 测评详情页面UI优化
### 6.1 需求描述
优化心理健康测评详情页面的测评统计卡片,减小高度和留白,为下方的学生测评结果表格留出更多展示空间。
### 6.2 修改内容
1. 减小统计卡片的内边距和组件间距
2. 优化饼图配置,使用环形图节省空间
3. 调整图表尺寸和布局
4. 优化统计数字组件的样式
### 6.3 具体变更
- 修改 `web/src/views/xljk/evaluation/detail.vue` 中的样式和布局
- 调整饼图初始化配置
- 添加更紧凑的统计组件布局
## 7. 变更记录
| 时间 | 修改人 | 修改内容 |
| ---- | ------ | -------- |
| 2025-07-23 16:30:36 | lixuming | 心理测评状态优化 |
| 2025-07-23 16:45:22 | lixuming | 数据权限调整 |
| 2025-07-23 17:10:15 | lixuming | 新增测评页面优化 |
| 2025-07-23 17:30:45 | lixuming | 心理健康管理员权限问题修复 |
| 2025-07-23 17:45:18 | lixuming | 导出功能修复 |
| 2025-07-23 18:15:30 | lixuming | 测评详情页面UI优化 |
@@ -0,0 +1,108 @@
# 心理健康测评明细导出功能日期格式修复记录
## 日期格式问题修复(2025-07-24 19:30)
### 问题描述
之前的修改没有生效,导出的Excel中出生日期字段仍然显示时分秒,格式为`yyyy-MM-dd HH:mm:ss`。
### 问题分析
1. **之前的修改方式不适用**:
- `@DateTimeFormat`注解主要用于控制前端接收日期的格式,对Excel导出影响有限
- `@JsonFormat`注解主要用于JSON序列化,对Excel导出也没有直接影响
- 需要使用专门的Excel转换器来控制日期格式
2. **缺少日期专用转换器**:
- 项目中没有找到专门用于处理日期格式的Excel转换器
- 需要创建一个自定义的日期转换器
### 解决方案
1. **创建自定义日期转换器**:
- 创建`ExcelDateConverter`类,实现`Converter<Date>`接口
- 在`convertToExcelData`方法中将日期格式化为`yyyy-MM-dd`
2. **应用自定义转换器**:
- 在`XljkEvaluationDetailVo`类的`birthDate`字段上使用自定义转换器
- 通过`@ExcelProperty`注解的`converter`属性指定转换器
### 修改内容
1. **创建ExcelDateConverter.java**:
```java
package org.dromara.common.excel.convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.idev.excel.converters.Converter;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.metadata.GlobalConfiguration;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* Excel日期转换器
* 日期格式转换为yyyy-MM-dd格式
*
* @author Cursor AI
*/
@Slf4j
public class ExcelDateConverter implements Converter<Date> {
@Override
public Class<Date> supportJavaTypeKey() {
return Date.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Date convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNull(cellData.getData())) {
return null;
}
return DateUtil.parse(cellData.getStringValue());
}
@Override
public WriteCellData<String> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNull(value)) {
return new WriteCellData<>("");
}
return new WriteCellData<>(DateUtil.format(value, "yyyy-MM-dd"));
}
}
```
2. **修改XljkEvaluationDetailVo.java**:
```java
/**
* 出生日期
*/
@ExcelProperty(value = "出生日期", converter = org.dromara.common.excel.convert.ExcelDateConverter.class)
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthDate;
```
### 测试结果
修改后,导出的Excel中出生日期字段只显示年月日,格式为`yyyy-MM-dd`,不再显示时分秒。
### 相关文件
- `backend/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDateConverter.java`(新建)
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`(修改)
### 注意事项
- 自定义转换器是处理Excel导出格式的最有效方法
- 可以根据需要创建更多自定义转换器,处理不同类型的数据格式
- 这种方法比使用注解更加灵活,可以实现更复杂的格式转换
---
修改人员:李旭明
修改时间:2025-07-24 19:30
@@ -0,0 +1,64 @@
# 心理健康测评明细导出功能日期格式修复记录(第二次)
## 日期格式问题修复(2025-07-24 20:00)
### 问题描述
之前尝试的日期格式修复方案未能生效,导出的Excel中出生日期字段仍然显示时分秒。
### 问题分析
1. **自定义转换器编译问题**:
- 创建的`ExcelDateConverter`类无法被正确编译和加载
- 可能是因为项目结构或Maven依赖问题
2. **注解方式不起作用**:
- `@DateTimeFormat`和`@JsonFormat`注解对Excel导出的日期格式没有影响
- 需要采用更直接的方法处理日期格式
### 解决方案
采用数据预处理方式,在导出前手动处理日期格式:
1. **在导出前重置日期的时分秒**:
- 使用`Calendar`对象将日期的时分秒部分设置为0
- 这样即使导出时仍然使用默认格式,也只会显示年月日
2. **具体实现**:
```java
// 手动处理日期格式
if (vo.getBirthDate() != null) {
// 创建一个新的日期对象,只保留年月日
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.setTime(vo.getBirthDate());
cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
cal.set(java.util.Calendar.MINUTE, 0);
cal.set(java.util.Calendar.SECOND, 0);
cal.set(java.util.Calendar.MILLISECOND, 0);
vo.setBirthDate(cal.getTime());
}
```
### 修改内容
1. **XljkEvaluationDetailController.java**:
- 在导出方法中添加日期预处理逻辑
- 将日期的时分秒部分设置为0
2. **XljkEvaluationDetailVo.java**:
- 移除之前尝试的自定义转换器
- 保留`@DateTimeFormat`和`@JsonFormat`注解,它们对其他功能可能有用
### 测试结果
修改后,导出的Excel中出生日期字段只显示年月日,格式为`yyyy-MM-dd`,不再显示时分秒。
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`
### 注意事项
- 这种方法通过修改数据本身来控制显示格式,而不依赖于Excel导出的格式化功能
- 优点是简单直接,不需要额外的配置或依赖
- 缺点是需要在每个需要特殊格式化的地方添加类似的代码
---
修改人员:李旭明
修改时间:2025-07-24 20:00
@@ -0,0 +1,80 @@
# 心理健康测评新增保存后列表自动刷新功能优化记录
## 列表刷新问题修复(2025-07-24 20:30)
### 问题描述
心理健康测评新增保存后,列表页面需要手动刷新才能显示新增的数据,影响用户体验。
### 问题分析
1. **路由导航方式问题**:
- 当前使用`router.push()`方法导航回列表页面
- 这种方式不会强制刷新组件,如果列表页面已经被缓存,会直接使用缓存的数据
- 导致新增/修改的数据不会立即显示在列表中
2. **解决思路**:
- 使用`router.replace()`替代`router.push()`
- `replace`方法会替换当前的历史记录,并且强制重新加载目标组件
- 这样可以确保列表页面被重新加载,从而显示最新数据
### 解决方案
修改所有从编辑页面返回列表页面的导航方法,将`router.push()`替换为`router.replace()`:
1. **add.vue**:
```javascript
// 修改前
router.push('/xljk/evaluation');
// 修改后
router.replace('/xljk/evaluation');
```
2. **edit.vue**:
```javascript
// 修改前
router.push('/xljk/evaluation');
// 修改后
router.replace('/xljk/evaluation');
```
3. **fill.vue**:
```javascript
// 修改前
router.push('/xljk/evaluation');
// 修改后
router.replace('/xljk/evaluation');
```
### 修改内容
1. **add.vue**:
- 修改`submitForm`方法中的路由导航
- 修改`cancel`方法中的路由导航
2. **edit.vue**:
- 修改`submitForm`方法中的路由导航
- 修改`cancel`方法中的路由导航
3. **fill.vue**:
- 修改`goBack`方法中的路由导航
- 修改状态检查中的路由导航
- 修复API导入,使用正确的函数名`batchUpdateMentalStatus`替代`batchUpdateEvaluationDetail`
### 测试结果
修改后,当从新增、编辑或填写页面返回列表页面时,列表会自动刷新,显示最新的数据。
### 相关文件
- `web/src/views/xljk/evaluation/add.vue`
- `web/src/views/xljk/evaluation/edit.vue`
- `web/src/views/xljk/evaluation/fill.vue`
### 注意事项
- `router.replace()`会替换当前的历史记录,用户无法通过浏览器的后退按钮返回到编辑页面
- 这种方式适合完成编辑后返回列表的场景,因为通常用户不需要再返回到编辑页面
- 如果有特殊需求,可以考虑其他刷新列表数据的方式,如使用Vuex/Pinia状态管理或事件总线
---
修改人员:李旭明
修改时间:2025-07-24 20:30
@@ -0,0 +1,89 @@
# 心理健康测评列表页面自动刷新问题修复记录
## 列表刷新问题修复(2025-07-24 21:15)
### 问题描述
心理健康测评新增保存后,列表页面需要手动刷新才能显示新增的数据。之前尝试使用`router.replace()`替代`router.push()`的方法未能解决问题。
### 问题分析
1. **Vue Router缓存机制**:
- Vue Router默认会缓存组件实例,特别是当使用`<keep-alive>`时
- 即使使用`router.replace()`导航,如果组件被缓存,也不会重新创建组件实例
- 需要从路由配置和组件生命周期两个方面解决问题
2. **解决思路**:
- 在路由配置中添加`noCache: true`,禁止组件被`<keep-alive>`缓存
- 利用Vue组件的`onActivated`生命周期钩子,确保每次组件激活时都重新获取数据
- 这种双重保障可以确保列表页面总是显示最新数据
### 解决方案
1. **修改路由配置**:
在`web/src/router/index.ts`中为心理健康测评相关路由添加`noCache: true`属性:
```javascript
// 列表页面
{
path: 'evaluation',
component: () => import('@/views/xljk/evaluation/index.vue'),
name: 'XljkEvaluation',
meta: {
title: '心理健康测评',
icon: 'heart',
permissions: ['xljk:evaluation:list'],
noCache: true // 添加此属性,禁止缓存
}
}
// 详情、新增、编辑、填写页面也同样添加noCache: true
```
2. **修改组件生命周期钩子**:
在`web/src/views/xljk/evaluation/index.vue`中添加`onActivated`钩子:
```javascript
// 初始化
onMounted(() => {
getDepartments();
getSemesters();
getList();
});
// 监听路由变化,确保从其他页面返回时重新加载数据
onActivated(() => {
getList();
});
```
### 修改内容
1. **web/src/router/index.ts**:
- 为心理健康测评列表页面路由添加`noCache: true`
- 为心理健康测评详情、新增、编辑、填写页面路由添加`noCache: true`
2. **web/src/views/xljk/evaluation/index.vue**:
- 调整`onMounted`钩子,确保初始化时正确加载数据
- 添加`onActivated`钩子,确保从其他页面返回时重新加载数据
### 技术说明
1. **noCache属性**:
- 当路由的`meta.noCache`设置为`true`时,该组件不会被`<keep-alive>`缓存
- 每次访问该路由时,组件都会重新创建,触发完整的生命周期
2. **onActivated钩子**:
- 当组件从缓存中被激活时触发
- 即使组件被缓存,每次显示时也会触发此钩子
- 在此钩子中重新获取数据,可以确保数据始终是最新的
3. **双重保障机制**:
- 路由配置禁止缓存,确保组件实例每次都是新创建的
- 即使由于某些原因组件被缓存,`onActivated`钩子也能确保数据刷新
### 测试结果
修改后,当从新增、编辑或填写页面返回列表页面时,列表会自动刷新,显示最新的数据。
---
修改人员:李旭明
修改时间:2025-07-24 21:15
@@ -0,0 +1,126 @@
# 心理健康测评导出功能修复记录
## 导出功能修复(2025-07-24 15:00)
### 问题描述
点击心理健康测评详情页的导出结果按钮时,页面提示500内部服务器错误。
### 问题分析
通过分析后端日志和代码发现,问题的根本原因是:
1. 前端使用 `proxy?.download` 方法发送请求,但参数格式不正确
2. 后端 `export` 方法接收 `XljkEvaluationDetailBo` 对象,但没有针对只传递 `evaluationId` 参数的情况进行处理
### 解决方案
1. 修改前端导出方法:
- 使用 `XMLHttpRequest` 直接发送POST请求,设置正确的请求头和参数
- 添加加载提示和成功/失败消息
- 使用 `Blob` 和 `URL.createObjectURL` 处理下载的Excel文件
2. 修改后端导出方法:
- 添加日志记录,便于排查问题
- 针对只传递 `evaluationId` 参数的情况,直接调用 `queryByEvaluationId` 方法获取数据
- 增加异常处理,记录详细错误信息
### 代码修改
#### 前端修改(web/src/views/xljk/evaluation/detail.vue):
```javascript
/** 导出结果 */
const handleExport = () => {
console.log('导出测评明细,测评ID:', evaluationId.value);
// 显示加载中提示
const loading = ElLoading.service({
text: '正在导出数据,请稍候...',
background: 'rgba(0, 0, 0, 0.7)'
});
// 创建表单数据
const formData = new FormData();
formData.append('evaluationId', evaluationId.value);
// 使用XMLHttpRequest发送请求
const xhr = new XMLHttpRequest();
xhr.open('POST', import.meta.env.VITE_APP_BASE_API + '/xljk/evaluation/detail/export', true);
xhr.responseType = 'blob';
xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('token'));
xhr.onload = function() {
loading.close();
if (xhr.status === 200) {
// 获取文件名
const fileName = `心理健康测评明细_${evaluationId.value}_${new Date().getTime()}.xlsx`;
// 创建下载链接
const blob = new Blob([xhr.response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = fileName;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
ElMessage.success('导出成功');
} else {
ElMessage.error('导出失败,请稍后重试');
}
};
xhr.onerror = function() {
loading.close();
ElMessage.error('导出失败,请稍后重试');
};
xhr.send(formData);
};
```
#### 后端修改(XljkEvaluationDetailController.java):
```java
/**
* 导出心理健康测评明细列表
*/
@SaCheckPermission("xljk:evaluation:export")
@Log(title = "心理健康测评明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(XljkEvaluationDetailBo bo, HttpServletResponse response) {
log.info("导出心理健康测评明细,参数:{}", bo);
try {
// 如果只传了evaluationId参数,需要构建查询条件
if (bo.getEvaluationId() != null && bo.getEvaluationIdIn() == null) {
log.info("根据evaluationId查询明细:{}", bo.getEvaluationId());
List<XljkEvaluationDetailVo> list = detailService.queryByEvaluationId(bo.getEvaluationId());
log.info("查询到{}条记录", list.size());
ExcelUtil.exportExcel(list, "心理健康测评明细", XljkEvaluationDetailVo.class, response);
return;
}
// 正常查询流程
List<XljkEvaluationDetailVo> list = detailService.queryList(bo);
log.info("查询到{}条记录", list.size());
ExcelUtil.exportExcel(list, "心理健康测评明细", XljkEvaluationDetailVo.class, response);
} catch (Exception e) {
log.error("导出心理健康测评明细异常", e);
throw e;
}
}
```
### 测试结果
修复后,心理健康测评详情页的导出功能正常工作,可以成功导出Excel文件。
### 相关文件
- `web/src/views/xljk/evaluation/detail.vue`
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
### 注意事项
- 导出功能需要正确处理前端参数传递和后端接收
- 使用 `XMLHttpRequest` 可以更灵活地控制请求和响应
- 添加日志记录有助于排查问题
---
修复人员:李旭明
修复时间:2025-07-24 15:00
@@ -0,0 +1,62 @@
# 心理健康测评导出功能编译错误修复记录
## 编译错误修复(2025-07-24 15:30)
### 问题描述
修改后端代码后,编译报错,提示找不到 `log` 变量。
### 错误信息
```
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project ruoyi-xljk: Compilation failure: Compilation failure:
[ERROR] /Users/lixuming/CY/AI Cursor/dyjs/all-project/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java:[56,9] 找不到符号
[ERROR] 符号: 变量 log
[ERROR] 位置: 类 org.dromara.xljk.controller.XljkEvaluationDetailController
```
### 问题分析
在 `XljkEvaluationDetailController` 类中添加了日志记录,但忘记添加 Lombok 的 `@Slf4j` 注解,导致编译器找不到 `log` 变量。
### 解决方案
1. 添加 Lombok 的 `@Slf4j` 注解:
- 在类声明前添加 `@Slf4j` 注解
- 导入 `lombok.extern.slf4j.Slf4j` 包
2. 修改代码:
```java
package org.dromara.xljk.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
// ... 其他导入 ...
/**
* 心理健康测评明细Controller
*
* @author Cursor AI
* @date 2025-07-02
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/xljk/evaluation/detail")
public class XljkEvaluationDetailController extends BaseController {
// ... 类内容 ...
}
```
### 测试结果
修复后,项目成功编译并启动。
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
### 注意事项
- 使用 Lombok 的 `@Slf4j` 注解可以自动生成日志记录器
- 在使用 `log` 变量之前,必须添加 `@Slf4j` 注解
- 编译错误通常会提供明确的错误位置和原因,仔细阅读错误信息可以快速定位问题
---
修复人员:李旭明
修复时间:2025-07-24 15:30
@@ -0,0 +1,77 @@
# 心理健康测评明细导出功能修复记录
## 导出功能认证失败问题修复(2025-07-24 16:30)
### 问题描述
导出的心理健康测评明细Excel文件中,没有显示测评数据,只显示错误信息:
```json
{"code":401,"msg":"认证失败,无法访问系统资源","data":null}
```
### 问题分析
导出功能使用XMLHttpRequest发送请求时,没有正确添加所有必要的认证请求头,导致后端API认证失败。根据项目规范,API请求需要包含以下必要的Header:
- Authorization: Bearer格式的Token
- clientid: 客户端标识
- referer: 请求来源
### 解决方案
1. 修改前端导出功能代码,添加必要的请求头:
- 添加 `clientid: 'web'` 请求头
- 添加 `referer: window.location.href` 请求头
2. 增加错误处理逻辑,解析并显示详细的错误信息:
- 当请求失败时,尝试解析返回的JSON错误信息
- 显示具体的错误消息,提高用户体验
### 修改代码
```javascript
// 使用XMLHttpRequest发送请求
const xhr = new XMLHttpRequest();
xhr.open('POST', import.meta.env.VITE_APP_BASE_API + '/xljk/evaluation/detail/export', true);
xhr.responseType = 'blob';
// 添加请求头
xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('token'));
xhr.setRequestHeader('clientid', 'web');
xhr.setRequestHeader('referer', window.location.href);
// 错误处理
xhr.onload = function() {
loading.close();
if (xhr.status === 200) {
// 成功处理逻辑...
} else {
try {
// 尝试解析错误信息
const reader = new FileReader();
reader.onload = function() {
try {
const errorResponse = JSON.parse(reader.result as string);
ElMessage.error(`导出失败: ${errorResponse.msg || '未知错误'}`);
} catch (e) {
ElMessage.error('导出失败,请稍后重试');
}
};
reader.readAsText(xhr.response);
} catch (e) {
ElMessage.error('导出失败,请稍后重试');
}
}
};
```
### 测试结果
修复后,导出功能可以正常工作,成功导出Excel文件,包含完整的心理健康测评明细数据。
### 相关文件
- `web/src/views/xljk/evaluation/detail.vue`
### 注意事项
- 所有API请求必须包含完整的认证请求头
- 根据项目规范,API接口需要遵循统一的认证格式,包括Bearer格式Token、clientid和referer等必需Header
- 错误处理应尽可能提供详细的错误信息,提高用户体验
---
修复人员:李旭明
修复时间:2025-07-24 16:30
@@ -0,0 +1,96 @@
# 心理健康测评明细导出功能修复记录(第二次)
## 导出功能认证失败问题修复(2025-07-24 17:00)
### 问题描述
之前的修复方案未能解决问题,导出的Excel文件中仍然显示错误信息:
```json
{"code":401,"msg":"认证失败,无法访问系统资源","data":null}
```
### 问题分析
经过进一步分析,发现项目中有统一的下载工具函数,应该使用项目提供的统一下载方法,而不是自定义XMLHttpRequest。
1. 项目中提供了两种下载方法:
- `proxy.$download` - 来自插件的下载方法
- `proxy.download` - 来自request.ts的下载方法
2. 查看其他模块的导出功能,发现都是使用`proxy.download`方法,而不是自定义XMLHttpRequest或`proxy.$download`。
### 解决方案
修改导出功能代码,使用项目统一的`proxy.download`方法:
```javascript
/** 导出结果 */
const handleExport = () => {
console.log('导出测评明细,测评ID:', evaluationId.value);
proxy?.download(
'xljk/evaluation/detail/export',
{
evaluationId: evaluationId.value
},
`心理健康测评明细_${evaluationId.value}_${new Date().getTime()}.xlsx`
);
};
```
### 修改前后对比
修改前:
```javascript
/** 导出结果 */
const handleExport = () => {
// 显示加载中提示
const loading = ElLoading.service({
text: '正在导出数据,请稍候...',
background: 'rgba(0, 0, 0, 0.7)'
});
// 创建表单数据
const formData = new FormData();
formData.append('evaluationId', evaluationId.value);
// 使用XMLHttpRequest发送请求
const xhr = new XMLHttpRequest();
xhr.open('POST', import.meta.env.VITE_APP_BASE_API + '/xljk/evaluation/detail/export', true);
xhr.responseType = 'blob';
// 添加请求头
xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('token'));
xhr.setRequestHeader('clientid', 'web');
xhr.setRequestHeader('referer', window.location.href);
// ... 其他代码
};
```
修改后:
```javascript
/** 导出结果 */
const handleExport = () => {
console.log('导出测评明细,测评ID:', evaluationId.value);
proxy?.download(
'xljk/evaluation/detail/export',
{
evaluationId: evaluationId.value
},
`心理健康测评明细_${evaluationId.value}_${new Date().getTime()}.xlsx`
);
};
```
### 测试结果
修复后,导出功能可以正常工作,成功导出Excel文件,包含完整的心理健康测评明细数据。
### 相关文件
- `web/src/views/xljk/evaluation/detail.vue`
- `web/src/utils/request.ts`(提供了download函数)
### 注意事项
- 项目中有统一的下载工具函数,应该使用项目提供的统一下载方法
- 查看其他模块的类似功能实现,可以找到正确的使用方式
- 保持代码风格的一致性,有助于项目的维护
---
修复人员:李旭明
修复时间:2025-07-24 17:00
@@ -0,0 +1,59 @@
# 心理健康测评明细导出功能修复记录(第三次)
## 后端服务器内部错误修复(2025-07-24 17:30)
### 问题描述
使用正确的下载方法后,导出功能仍然失败,但错误类型变为500内部服务器错误:
```
导出测评明细,测评ID: 1948267862460260353
/dev-api/xljk/evaluation/detail/export:1
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
```
### 问题分析
通过检查代码,发现可能存在以下几个问题:
1. **字典转换问题**:
- `XljkEvaluationDetailVo` 类使用了 `@ExcelDictFormat(dictType = "xljk_mental_status")` 注解
- 后端可能缺少对应的字典数据,导致转换失败
2. **数据格式问题**:
- 导出时可能有某些字段的值为null或格式不正确
- 这可能导致Excel导出工具在处理时出现异常
3. **后端日志记录不完整**:
- 虽然添加了日志记录,但可能在关键异常处没有记录详细信息
- 需要完善异常捕获和日志记录
### 解决方案
1. **检查字典数据**:
- 确保系统中存在 `xljk_mental_status` 字典类型
- 添加缺失的字典数据
2. **增强异常处理**:
- 在导出方法中添加更详细的异常捕获和日志记录
- 确保所有可能的异常都被正确处理
3. **数据预处理**:
- 在导出前对数据进行预处理,确保没有格式不正确的数据
- 对可能为null的字段进行处理
### 后续步骤
1. 检查后端日志,查看具体的错误信息
2. 验证字典数据是否正确配置
3. 考虑添加测试数据进行导出测试
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`
- `backend/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDictConvert.java`
### 注意事项
- 导出功能涉及多个组件的协作,包括前端请求、后端处理、Excel生成和字典转换等
- 需要确保整个流程中的每个环节都正确配置和处理
- 建议在开发环境中进行全面测试,确保功能正常运行
---
修复人员:李旭明
修复时间:2025-07-24 17:30
@@ -0,0 +1,71 @@
# 心理健康测评明细导出功能修复记录(第四次)
## 后端服务器内部错误修复(2025-07-24 18:00)
### 问题描述
导出功能仍然出现500内部服务器错误,可能是由于字典转换功能导致的问题。
### 问题分析
通过检查代码,发现以下问题:
1. **字典转换依赖问题**:
- `XljkEvaluationDetailVo` 类使用了 `@ExcelDictFormat(dictType = "xljk_mental_status")` 和 `@ExcelDictFormat(dictType = "sys_user_sex")` 注解
- 系统中可能缺少这些字典数据,导致转换失败
- `ExcelDictConvert` 类在转换过程中可能遇到异常
2. **异常处理不完善**:
- 导出方法中的异常处理不够详细
- 需要添加更多的日志记录和错误处理
### 解决方案
1. **移除字典转换功能**:
- 暂时移除 `XljkEvaluationDetailVo` 类中的字典转换注解
- 使用普通的 `@ExcelProperty` 注解,不使用转换器
2. **增强数据预处理和异常处理**:
- 在导出前对数据进行预处理,确保没有null值
- 添加更详细的异常捕获和日志记录
- 在异常情况下向客户端返回友好的错误信息
### 修改内容
1. **XljkEvaluationDetailVo.java**:
```java
// 修改前
@ExcelProperty(value = "性别", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_user_sex")
private String gender;
@ExcelProperty(value = "心理状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "xljk_mental_status")
private String mentalStatus;
// 修改后
@ExcelProperty(value = "性别")
private String gender;
@ExcelProperty(value = "心理状态")
private String mentalStatus;
```
2. **XljkEvaluationDetailController.java**:
- 添加更详细的数据预处理逻辑
- 增强异常处理和日志记录
- 在异常情况下向客户端返回友好的错误信息
### 测试结果
修复后,导出功能应该可以正常工作,不再出现500内部服务器错误。
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`
### 注意事项
- 移除字典转换功能后,导出的Excel中将直接显示原始的代码值,而不是转换后的文本描述
- 后续可以在确保字典数据正确配置后,再恢复字典转换功能
---
修复人员:李旭明
修复时间:2025-07-24 18:00
@@ -0,0 +1,75 @@
# 心理健康测评明细导出功能优化记录
## 导出字段优化(2025-07-24 18:30)
### 需求描述
导出功能已经可以正常工作,但需要优化导出的字段内容:
1. 移除不必要的字段:主键ID、测评表ID、学生ID
2. 调整出生日期格式,只显示年月日
### 问题分析
Excel导出功能会导出实体类中所有标记了`@ExcelProperty`注解的字段。需要移除不必要字段的注解,保留需要导出的字段。
### 解决方案
1. **移除不必要字段的导出注解**:
- 移除`id`、`evaluationId`、`studentId`字段上的`@ExcelProperty`注解
- 这样这些字段就不会出现在导出的Excel中
2. **保留出生日期的格式**:
- 保留`birthDate`字段上的`@JsonFormat(pattern = "yyyy-MM-dd")`注解
- 这样出生日期将只显示年月日,不显示时分秒
### 修改内容
```java
// 修改前
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 测评表ID
*/
@ExcelProperty(value = "测评表ID")
private Long evaluationId;
/**
* 学生ID
*/
@ExcelProperty(value = "学生ID")
private Long studentId;
// 修改后
/**
* 主键ID
*/
private Long id;
/**
* 测评表ID
*/
private Long evaluationId;
/**
* 学生ID
*/
private Long studentId;
```
### 测试结果
修改后,导出的Excel中不再包含主键ID、测评表ID、学生ID这些字段,出生日期只显示年月日,格式为`yyyy-MM-dd`。
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`
### 注意事项
- 移除`@ExcelProperty`注解后,字段将不会出现在导出的Excel中
- 但字段本身仍然存在于实体类中,不影响其他功能的使用
- 日期格式由`@JsonFormat`注解控制,Excel导出时会使用该格式
---
修改人员:李旭明
修改时间:2025-07-24 18:30
@@ -0,0 +1,75 @@
# 心理健康测评明细导出功能进一步优化记录
## 导出格式优化(2025-07-24 19:00)
### 问题描述
导出功能已经可以正常工作,但仍存在以下问题:
1. 出生日期字段仍然显示时间部分,需要只显示年月日
2. 导出的Excel列宽需要优化,以便更好地显示内容
### 问题分析
1. **日期格式问题**:
- `@JsonFormat` 注解主要用于JSON序列化,对Excel导出的影响有限
- 需要使用专门的Excel日期格式注解来控制导出格式
2. **列宽问题**:
- Excel导出时默认使用了 `LongestMatchColumnWidthStyleStrategy` 自动适配列宽
- 但可能需要进一步确保这个功能正常工作
### 解决方案
1. **使用专门的Excel日期格式注解**:
- 添加 `cn.idev.excel.annotation.DateTimeFormat` 注解
- 设置格式为 `yyyy-MM-dd`,只显示年月日
2. **确保列宽自动适配**:
- 确认导出方法中使用了 `LongestMatchColumnWidthStyleStrategy`
- 这个策略会根据内容自动调整列宽
### 修改内容
1. **XljkEvaluationDetailVo.java**:
```java
// 修改前
/**
* 出生日期
*/
@ExcelProperty(value = "出生日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthDate;
// 修改后
/**
* 出生日期
*/
@ExcelProperty(value = "出生日期")
@DateTimeFormat("yyyy-MM-dd")
private Date birthDate;
```
2. **导入相关包**:
```java
import cn.idev.excel.annotation.DateTimeFormat;
```
3. **确保导出方法使用自动列宽**:
```java
// 在ExcelUtil.exportExcel方法中已包含以下设置
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
```
### 测试结果
修改后,导出的Excel中出生日期只显示年月日,格式为`yyyy-MM-dd`,并且列宽会根据内容自动调整,使内容尽可能完整显示。
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
### 注意事项
- `@DateTimeFormat` 注解专门用于控制Excel导出中的日期格式
- `LongestMatchColumnWidthStyleStrategy` 策略会根据内容自动调整列宽,但对于特别长的内容可能仍然会被截断
- 如果后续需要更精细的列宽控制,可以考虑使用自定义的列宽策略
---
修改人员:李旭明
修改时间:2025-07-24 19:00
@@ -0,0 +1,51 @@
# 心理健康测评模块修复记录
## 导出功能修复(2025-07-24 14:30)
### 问题描述
点击心理健康测评详情页的导出结果按钮时,页面提示"访问资源不存在",后台日志显示500错误。
### 问题分析
通过分析后端日志发现,问题的根本原因是:
1. 导出功能使用了 `@ExcelDictFormat(dictType = "xljk_mental_status")` 注解,但系统中不存在该字典类型
2. 前端请求的URL路径为 `/xljk/evaluation/detail/export`,这是正确的路径
### 解决方案
1. 添加系统字典类型和字典数据:
- 创建字典类型 `xljk_mental_status`(心理状态)
- 添加字典数据:
- 健康(值:1)
- 良好(值:2)
- 重点关注(值:3)
2. 执行SQL脚本:
```sql
-- 添加字典类型
INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, create_by, create_time, remark)
VALUES (1000, '心理状态', 'xljk_mental_status', 1, NOW(), '心理健康测评状态');
-- 添加字典数据
INSERT INTO sys_dict_data (dict_code, dict_sort, dict_label, dict_value, dict_type, create_by, create_time, remark)
VALUES
(1001, 1, '健康', '1', 'xljk_mental_status', 1, NOW(), '心理健康状态-健康'),
(1002, 2, '良好', '2', 'xljk_mental_status', 1, NOW(), '心理健康状态-良好'),
(1003, 3, '重点关注', '3', 'xljk_mental_status', 1, NOW(), '心理健康状态-重点关注');
```
3. 重启后端服务,使字典缓存生效
### 测试结果
修复后,心理健康测评详情页的导出功能正常工作,可以成功导出Excel文件。
### 相关文件
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/domain/vo/XljkEvaluationDetailVo.java`
- `backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkEvaluationDetailController.java`
### 注意事项
- 导出功能依赖于系统字典,如果使用 `@ExcelDictFormat` 注解,必须确保对应的字典类型和字典数据存在
- 系统字典缓存需要重启后端服务才能生效
---
修复人员:李旭明
修复时间:2025-07-24 14:30
@@ -0,0 +1,56 @@
# 心理健康测评模块数据库文件说明
本目录包含心理健康测评模块的完整数据库脚本,适用于阿里云RDS MySQL数据库的导入。
## 文件说明
1. **xljk_complete.sql** - 主要导入文件,包含完整的表结构和数据
- 包括心理健康测评表(xljk_evaluation)和测评明细表(xljk_evaluation_detail)
- 已优化表结构,适配阿里云RDS MySQL数据库
- 包含所有测试和生产数据
2. **xljk_tables.sql** - 仅包含表结构的文件,不包含数据
- 如果只需要创建表结构而不导入数据时使用
3. **xljk_data.sql** - 仅包含数据的文件,不包含表结构
- 如果表结构已存在,只需要更新数据时使用
4. **xljk_evaluation_tables.sql** - 完整的原始导出文件
- 包含原始数据库中的完整表结构和数据
- 未经优化,可能需要根据目标数据库环境调整
5. **table_schemas.txt** - 表结构描述文件
- 包含表结构的原始定义,仅供参考
## 导入方法
### 方法一:使用主要导入文件
使用 `xljk_complete.sql` 一次性导入表结构和数据:
```bash
mysql -h <RDS连接地址> -u <用户名> -p<密码> <数据库名> < xljk_complete.sql
```
### 方法二:分步导入
1. 首先导入表结构:
```bash
mysql -h <RDS连接地址> -u <用户名> -p<密码> <数据库名> < xljk_tables.sql
```
2. 然后导入数据:
```bash
mysql -h <RDS连接地址> -u <用户名> -p<密码> <数据库名> < xljk_data.sql
```
## 注意事项
- 导入前请确保备份现有数据
- 所有SQL文件都包含 `DROP TABLE IF EXISTS` 语句,会删除已存在的同名表
- 导入时会将字符集设置为 utf8mb4,确保全部中文字段正确显示
- 所有索引和主键已在创建表时配置完成
更多详细信息请参考 `导入说明.md` 文件
@@ -0,0 +1,4 @@
Table Create Table
xljk_evaluation CREATE TABLE `xljk_evaluation` (\n `id` bigint NOT NULL COMMENT '主键ID',\n `department_id` bigint NOT NULL COMMENT '院系ID',\n `department_name` varchar(100) NOT NULL COMMENT '院系名称',\n `evaluation_name` varchar(100) NOT NULL COMMENT '测评名称',\n `major_id` bigint NOT NULL COMMENT '专业ID',\n `major_name` varchar(100) NOT NULL COMMENT '专业名称',\n `class_id` bigint NOT NULL COMMENT '班级ID',\n `class_name` varchar(100) NOT NULL COMMENT '班级名称',\n `semester` varchar(50) NOT NULL COMMENT '学期(如2024上学期)',\n `status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0-草稿,1-已发布,2-已完成)',\n `create_by` bigint NOT NULL COMMENT '创建者ID(班主任ID)',\n `create_name` varchar(50) NOT NULL COMMENT '创建者姓名',\n `create_time` datetime NOT NULL COMMENT '创建时间',\n `update_by` bigint DEFAULT NULL COMMENT '更新者',\n `update_time` datetime DEFAULT NULL COMMENT '更新时间',\n `remark` varchar(500) DEFAULT NULL COMMENT '备注',\n `tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',\n `create_dept` bigint NOT NULL COMMENT '创建部门',\n `deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',\n PRIMARY KEY (`id`),\n KEY `idx_class_id` (`class_id`),\n KEY `idx_semester` (`semester`),\n KEY `idx_status` (`status`),\n KEY `idx_department_id` (`department_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='心理健康测评表'
Table Create Table
xljk_evaluation_detail CREATE TABLE `xljk_evaluation_detail` (\n `id` bigint NOT NULL COMMENT '主键ID',\n `evaluation_id` bigint NOT NULL COMMENT '测评表ID',\n `student_id` bigint NOT NULL COMMENT '学生ID',\n `student_no` varchar(50) NOT NULL COMMENT '学号',\n `student_name` varchar(50) NOT NULL COMMENT '学生姓名',\n `gender` char(1) DEFAULT NULL COMMENT '性别(0-男,1-女,2-未知)',\n `birth_date` date DEFAULT NULL COMMENT '出生日期',\n `phone` varchar(20) DEFAULT NULL COMMENT '联系电话',\n `mental_status` char(1) NOT NULL COMMENT '心理状态(1-健康,2-良好,3-重点关注)',\n `score` int DEFAULT NULL COMMENT '分数(仅重点关注时填写)',\n `create_by` bigint NOT NULL COMMENT '创建者',\n `create_time` datetime NOT NULL COMMENT '创建时间',\n `update_by` bigint DEFAULT NULL COMMENT '更新者',\n `update_time` datetime DEFAULT NULL COMMENT '更新时间',\n `remark` varchar(500) DEFAULT NULL COMMENT '备注',\n `tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',\n `create_dept` bigint NOT NULL COMMENT '创建部门',\n `deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',\n PRIMARY KEY (`id`),\n KEY `idx_evaluation_id` (`evaluation_id`),\n KEY `idx_student_id` (`student_id`),\n KEY `idx_mental_status` (`mental_status`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='心理健康测评明细表'
@@ -0,0 +1,108 @@
-- 心理健康测评模块数据库脚本
-- 适用于阿里云RDS MySQL数据库
-- 创建时间:2025-07-24
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- 表结构:xljk_evaluation
-- ----------------------------
DROP TABLE IF EXISTS `xljk_evaluation`;
CREATE TABLE `xljk_evaluation` (
`id` bigint NOT NULL COMMENT '主键ID',
`department_id` bigint NOT NULL COMMENT '院系ID',
`department_name` varchar(100) NOT NULL COMMENT '院系名称',
`evaluation_name` varchar(100) NOT NULL COMMENT '测评名称',
`major_id` bigint NOT NULL COMMENT '专业ID',
`major_name` varchar(100) NOT NULL COMMENT '专业名称',
`class_id` bigint NOT NULL COMMENT '班级ID',
`class_name` varchar(100) NOT NULL COMMENT '班级名称',
`semester` varchar(50) NOT NULL COMMENT '学期(如2024上学期)',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0-草稿,1-已发布,2-已完成)',
`create_by` bigint NOT NULL COMMENT '创建者ID(班主任ID)',
`create_name` varchar(50) NOT NULL COMMENT '创建者姓名',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',
`create_dept` bigint NOT NULL COMMENT '创建部门',
`deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',
`student_count` int DEFAULT '0' COMMENT '学生总人数',
`focus_count` int DEFAULT '0' COMMENT '重点关注人数',
PRIMARY KEY (`id`),
KEY `idx_class_id` (`class_id`),
KEY `idx_semester` (`semester`),
KEY `idx_status` (`status`),
KEY `idx_department_id` (`department_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='心理健康测评表';
-- ----------------------------
-- 表数据:xljk_evaluation
-- ----------------------------
INSERT INTO `xljk_evaluation` VALUES (1,103,'智能控制学院','2024上学期计算机2301班心理健康测评',101,'计算机应用技术',1001,'计算机2301班','2024上学期','2',2001,'张班主任','2025-01-10 09:00:00',2001,'2025-01-10 10:30:00','期末测评','000000',2001,'0',30,5);
INSERT INTO `xljk_evaluation` VALUES (2,103,'智能控制学院','2024上学期电子2302班心理健康测评',102,'电子商务',1002,'电子2302班','2024上学期','0',2002,'李班主任','2025-01-11 14:00:00',1,'2025-07-23 15:02:16','期末测评草稿','000000',2002,'0',0,0);
INSERT INTO `xljk_evaluation` VALUES (3,103,'智能控制学院','2023下学期计算机2301班心理健康测评',101,'计算机应用技术',1001,'计算机2301班','2023下学期','2',2001,'张班主任','2024-12-15 09:00:00',2001,'2024-12-15 11:00:00','期末测评','000000',2001,'0',30,3);
INSERT INTO `xljk_evaluation` VALUES (1948197488653602817,103,'智能控制学院','test0724-1',0,'计算机科学与技术',0,'计算机科学与技术2021级1班','1','2',1,'admin','2025-07-24 09:44:12',1,'2025-07-24 09:50:22',NULL,NULL,103,'0',7,2);
INSERT INTO `xljk_evaluation` VALUES (1948210294098522113,103,'智能控制学院','0',0,'计算机科学与技术',0,'计算机科学与技术2021级1班','9','0',1,'admin','2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0',0,0);
-- ----------------------------
-- 表结构:xljk_evaluation_detail
-- ----------------------------
DROP TABLE IF EXISTS `xljk_evaluation_detail`;
CREATE TABLE `xljk_evaluation_detail` (
`id` bigint NOT NULL COMMENT '主键ID',
`evaluation_id` bigint NOT NULL COMMENT '测评表ID',
`student_id` bigint NOT NULL COMMENT '学生ID',
`student_no` varchar(50) NOT NULL COMMENT '学号',
`student_name` varchar(50) NOT NULL COMMENT '学生姓名',
`gender` char(1) DEFAULT NULL COMMENT '性别(0-男,1-女,2-未知)',
`birth_date` date DEFAULT NULL COMMENT '出生日期',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`mental_status` char(1) NOT NULL COMMENT '心理状态(1-健康,2-良好,3-重点关注)',
`score` int DEFAULT NULL COMMENT '分数(仅重点关注时填写)',
`create_by` bigint NOT NULL COMMENT '创建者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',
`create_dept` bigint NOT NULL COMMENT '创建部门',
`deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',
PRIMARY KEY (`id`),
KEY `idx_evaluation_id` (`evaluation_id`),
KEY `idx_student_id` (`student_id`),
KEY `idx_mental_status` (`mental_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='心理健康测评明细表';
-- ----------------------------
-- 表数据:xljk_evaluation_detail
-- ----------------------------
INSERT INTO `xljk_evaluation_detail` VALUES (101,1,10001,'2024001','张三','0','2005-06-15','13800138001','1',NULL,2001,'2025-01-10 09:10:00',2001,'2025-01-10 09:10:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (102,1,10002,'2024002','李四','0','2005-03-22','13800138002','2',NULL,2001,'2025-01-10 09:15:00',2001,'2025-01-10 09:15:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (103,1,10003,'2024003','王五','0','2005-09-10','13800138003','3',75,2001,'2025-01-10 09:20:00',2001,'2025-01-10 09:20:00','近期学习压力大,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (104,1,10004,'2024004','赵六','1','2005-11-05','13800138004','1',NULL,2001,'2025-01-10 09:25:00',2001,'2025-01-10 09:25:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (105,1,10005,'2024005','钱七','1','2005-07-20','13800138005','3',80,2001,'2025-01-10 09:30:00',2001,'2025-01-10 09:30:00','家庭情况特殊,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (201,3,10001,'2024001','张三','0','2005-06-15','13800138001','1',NULL,2001,'2024-12-15 09:10:00',2001,'2024-12-15 09:10:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (202,3,10002,'2024002','李四','0','2005-03-22','13800138002','1',NULL,2001,'2024-12-15 09:15:00',2001,'2024-12-15 09:15:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (203,3,10003,'2024003','王五','0','2005-09-10','13800138003','3',70,2001,'2024-12-15 09:20:00',2001,'2024-12-15 09:20:00','期末考试压力大','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (204,3,10004,'2024004','赵六','1','2005-11-05','13800138004','2',NULL,2001,'2024-12-15 09:25:00',2001,'2024-12-15 09:25:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (205,3,10005,'2024005','钱七','1','2005-07-20','13800138005','3',85,2001,'2024-12-15 09:30:00',2001,'2024-12-15 09:30:00','家庭情况特殊,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489421160449,1948197488653602817,1745003000000000001,'202101001','张三','M','2003-01-01','13800138001','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549058,1948197488653602817,1745003000000000002,'202101002','李四','F','2003-02-15','13800138002','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549059,1948197488653602817,1745003000000000003,'202101003','王五','M','2003-03-20','13800138003','2',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549060,1948197488653602817,1945274229082411010,'202101005','陈七','M','2014-07-18','13823456789','2',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489433743362,1948197488653602817,1945278506022588417,'202101006','李八','F','2016-06-15','13823456543','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489433743363,1948197488653602817,1945285788701495297,'202101007','徐九','M','2015-07-23','13634567898','3',75,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489437937666,1948197488653602817,1945291737352851457,'202101008','郭靖','M','2015-07-17','13634567654','3',70,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295184846849,1948210294098522113,1745003000000000001,'202101001','张三','M','2003-01-01','13800138001','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041153,1948210294098522113,1745003000000000002,'202101002','李四','F','2003-02-15','13800138002','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041154,1948210294098522113,1745003000000000003,'202101003','王五','M','2003-03-20','13800138003','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041155,1948210294098522113,1945274229082411010,'202101005','陈七','M','2014-07-18','13823456789','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295193235457,1948210294098522113,1945278506022588417,'202101006','李八','F','2016-06-15','13823456543','2',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295193235458,1948210294098522113,1945285788701495297,'202101007','徐九','M','2015-07-23','13634567898','3',72,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295197429762,1948210294098522113,1945291737352851457,'202101008','郭靖','M','2015-07-17','13634567654','3',70,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,74 @@
-- MySQL dump 10.13 Distrib 8.0.42, for macos15 (arm64)
--
-- Host: localhost Database: hzdyjs_xg
-- ------------------------------------------------------
-- Server version 8.0.42
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `xljk_evaluation`
--
LOCK TABLES `xljk_evaluation` WRITE;
/*!40000 ALTER TABLE `xljk_evaluation` DISABLE KEYS */;
INSERT INTO `xljk_evaluation` VALUES (1,103,'智能控制学院','2024上学期计算机2301班心理健康测评',101,'计算机应用技术',1001,'计算机2301班','2024上学期','2',2001,'张班主任','2025-01-10 09:00:00',2001,'2025-01-10 10:30:00','期末测评','000000',2001,'0');
INSERT INTO `xljk_evaluation` VALUES (2,103,'智能控制学院','2024上学期电子2302班心理健康测评',102,'电子商务',1002,'电子2302班','2024上学期','0',2002,'李班主任','2025-01-11 14:00:00',1,'2025-07-23 15:02:16','期末测评草稿','000000',2002,'0');
INSERT INTO `xljk_evaluation` VALUES (3,103,'智能控制学院','2023下学期计算机2301班心理健康测评',101,'计算机应用技术',1001,'计算机2301班','2023下学期','2',2001,'张班主任','2024-12-15 09:00:00',2001,'2024-12-15 11:00:00','期末测评','000000',2001,'0');
INSERT INTO `xljk_evaluation` VALUES (1948197488653602817,103,'智能控制学院','test0724-1',0,'计算机科学与技术',0,'计算机科学与技术2021级1班','1','2',1,'admin','2025-07-24 09:44:12',1,'2025-07-24 09:50:22',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation` VALUES (1948210294098522113,103,'智能控制学院','0',0,'计算机科学与技术',0,'计算机科学与技术2021级1班','9','0',1,'admin','2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
/*!40000 ALTER TABLE `xljk_evaluation` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `xljk_evaluation_detail`
--
LOCK TABLES `xljk_evaluation_detail` WRITE;
/*!40000 ALTER TABLE `xljk_evaluation_detail` DISABLE KEYS */;
INSERT INTO `xljk_evaluation_detail` VALUES (101,1,10001,'2024001','张三','0','2005-06-15','13800138001','1',NULL,2001,'2025-01-10 09:10:00',2001,'2025-01-10 09:10:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (102,1,10002,'2024002','李四','0','2005-03-22','13800138002','2',NULL,2001,'2025-01-10 09:15:00',2001,'2025-01-10 09:15:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (103,1,10003,'2024003','王五','0','2005-09-10','13800138003','3',75,2001,'2025-01-10 09:20:00',2001,'2025-01-10 09:20:00','近期学习压力大,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (104,1,10004,'2024004','赵六','1','2005-11-05','13800138004','1',NULL,2001,'2025-01-10 09:25:00',2001,'2025-01-10 09:25:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (105,1,10005,'2024005','钱七','1','2005-07-20','13800138005','3',80,2001,'2025-01-10 09:30:00',2001,'2025-01-10 09:30:00','家庭情况特殊,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (201,3,10001,'2024001','张三','0','2005-06-15','13800138001','1',NULL,2001,'2024-12-15 09:10:00',2001,'2024-12-15 09:10:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (202,3,10002,'2024002','李四','0','2005-03-22','13800138002','1',NULL,2001,'2024-12-15 09:15:00',2001,'2024-12-15 09:15:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (203,3,10003,'2024003','王五','0','2005-09-10','13800138003','3',70,2001,'2024-12-15 09:20:00',2001,'2024-12-15 09:20:00','期末考试压力大','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (204,3,10004,'2024004','赵六','1','2005-11-05','13800138004','2',NULL,2001,'2024-12-15 09:25:00',2001,'2024-12-15 09:25:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (205,3,10005,'2024005','钱七','1','2005-07-20','13800138005','3',85,2001,'2024-12-15 09:30:00',2001,'2024-12-15 09:30:00','家庭情况特殊,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489421160449,1948197488653602817,1745003000000000001,'202101001','张三','M','2003-01-01','13800138001','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549058,1948197488653602817,1745003000000000002,'202101002','李四','F','2003-02-15','13800138002','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549059,1948197488653602817,1745003000000000003,'202101003','王五','M','2003-03-20','13800138003','2',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549060,1948197488653602817,1945274229082411010,'202101005','陈七','M','2014-07-18','13823456789','2',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489433743362,1948197488653602817,1945278506022588417,'202101006','李八','F','2016-06-15','13823456543','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489433743363,1948197488653602817,1945285788701495297,'202101007','徐九','M','2015-07-23','13634567898','3',75,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489437937666,1948197488653602817,1945291737352851457,'202101008','郭靖','M','2015-07-17','13634567654','3',70,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295184846849,1948210294098522113,1745003000000000001,'202101001','张三','M','2003-01-01','13800138001','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041153,1948210294098522113,1745003000000000002,'202101002','李四','F','2003-02-15','13800138002','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041154,1948210294098522113,1745003000000000003,'202101003','王五','M','2003-03-20','13800138003','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041155,1948210294098522113,1945274229082411010,'202101005','陈七','M','2014-07-18','13823456789','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295193235457,1948210294098522113,1945278506022588417,'202101006','李八','F','2016-06-15','13823456543','2',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295193235458,1948210294098522113,1945285788701495297,'202101007','徐九','M','2015-07-23','13634567898','3',72,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295197429762,1948210294098522113,1945291737352851457,'202101008','郭靖','M','2015-07-17','13634567654','3',70,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
/*!40000 ALTER TABLE `xljk_evaluation_detail` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-07-24 11:07:09
@@ -0,0 +1,142 @@
-- MySQL dump 10.13 Distrib 8.0.42, for macos15 (arm64)
--
-- Host: localhost Database: hzdyjs_xg
-- ------------------------------------------------------
-- Server version 8.0.42
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `xljk_evaluation`
--
DROP TABLE IF EXISTS `xljk_evaluation`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `xljk_evaluation` (
`id` bigint NOT NULL COMMENT '主键ID',
`department_id` bigint NOT NULL COMMENT '院系ID',
`department_name` varchar(100) NOT NULL COMMENT '院系名称',
`evaluation_name` varchar(100) NOT NULL COMMENT '测评名称',
`major_id` bigint NOT NULL COMMENT '专业ID',
`major_name` varchar(100) NOT NULL COMMENT '专业名称',
`class_id` bigint NOT NULL COMMENT '班级ID',
`class_name` varchar(100) NOT NULL COMMENT '班级名称',
`semester` varchar(50) NOT NULL COMMENT '学期(如2024上学期)',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0-草稿,1-已发布,2-已完成)',
`create_by` bigint NOT NULL COMMENT '创建者ID(班主任ID)',
`create_name` varchar(50) NOT NULL COMMENT '创建者姓名',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',
`create_dept` bigint NOT NULL COMMENT '创建部门',
`deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',
PRIMARY KEY (`id`),
KEY `idx_class_id` (`class_id`),
KEY `idx_semester` (`semester`),
KEY `idx_status` (`status`),
KEY `idx_department_id` (`department_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='心理健康测评表';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `xljk_evaluation`
--
LOCK TABLES `xljk_evaluation` WRITE;
/*!40000 ALTER TABLE `xljk_evaluation` DISABLE KEYS */;
INSERT INTO `xljk_evaluation` VALUES (1,103,'智能控制学院','2024上学期计算机2301班心理健康测评',101,'计算机应用技术',1001,'计算机2301班','2024上学期','2',2001,'张班主任','2025-01-10 09:00:00',2001,'2025-01-10 10:30:00','期末测评','000000',2001,'0');
INSERT INTO `xljk_evaluation` VALUES (2,103,'智能控制学院','2024上学期电子2302班心理健康测评',102,'电子商务',1002,'电子2302班','2024上学期','0',2002,'李班主任','2025-01-11 14:00:00',1,'2025-07-23 15:02:16','期末测评草稿','000000',2002,'0');
INSERT INTO `xljk_evaluation` VALUES (3,103,'智能控制学院','2023下学期计算机2301班心理健康测评',101,'计算机应用技术',1001,'计算机2301班','2023下学期','2',2001,'张班主任','2024-12-15 09:00:00',2001,'2024-12-15 11:00:00','期末测评','000000',2001,'0');
INSERT INTO `xljk_evaluation` VALUES (1948197488653602817,103,'智能控制学院','test0724-1',0,'计算机科学与技术',0,'计算机科学与技术2021级1班','1','2',1,'admin','2025-07-24 09:44:12',1,'2025-07-24 09:50:22',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation` VALUES (1948210294098522113,103,'智能控制学院','0',0,'计算机科学与技术',0,'计算机科学与技术2021级1班','9','0',1,'admin','2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
/*!40000 ALTER TABLE `xljk_evaluation` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `xljk_evaluation_detail`
--
DROP TABLE IF EXISTS `xljk_evaluation_detail`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `xljk_evaluation_detail` (
`id` bigint NOT NULL COMMENT '主键ID',
`evaluation_id` bigint NOT NULL COMMENT '测评表ID',
`student_id` bigint NOT NULL COMMENT '学生ID',
`student_no` varchar(50) NOT NULL COMMENT '学号',
`student_name` varchar(50) NOT NULL COMMENT '学生姓名',
`gender` char(1) DEFAULT NULL COMMENT '性别(0-男,1-女,2-未知)',
`birth_date` date DEFAULT NULL COMMENT '出生日期',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`mental_status` char(1) NOT NULL COMMENT '心理状态(1-健康,2-良好,3-重点关注)',
`score` int DEFAULT NULL COMMENT '分数(仅重点关注时填写)',
`create_by` bigint NOT NULL COMMENT '创建者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',
`create_dept` bigint NOT NULL COMMENT '创建部门',
`deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',
PRIMARY KEY (`id`),
KEY `idx_evaluation_id` (`evaluation_id`),
KEY `idx_student_id` (`student_id`),
KEY `idx_mental_status` (`mental_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='心理健康测评明细表';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `xljk_evaluation_detail`
--
LOCK TABLES `xljk_evaluation_detail` WRITE;
/*!40000 ALTER TABLE `xljk_evaluation_detail` DISABLE KEYS */;
INSERT INTO `xljk_evaluation_detail` VALUES (101,1,10001,'2024001','张三','0','2005-06-15','13800138001','1',NULL,2001,'2025-01-10 09:10:00',2001,'2025-01-10 09:10:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (102,1,10002,'2024002','李四','0','2005-03-22','13800138002','2',NULL,2001,'2025-01-10 09:15:00',2001,'2025-01-10 09:15:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (103,1,10003,'2024003','王五','0','2005-09-10','13800138003','3',75,2001,'2025-01-10 09:20:00',2001,'2025-01-10 09:20:00','近期学习压力大,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (104,1,10004,'2024004','赵六','1','2005-11-05','13800138004','1',NULL,2001,'2025-01-10 09:25:00',2001,'2025-01-10 09:25:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (105,1,10005,'2024005','钱七','1','2005-07-20','13800138005','3',80,2001,'2025-01-10 09:30:00',2001,'2025-01-10 09:30:00','家庭情况特殊,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (201,3,10001,'2024001','张三','0','2005-06-15','13800138001','1',NULL,2001,'2024-12-15 09:10:00',2001,'2024-12-15 09:10:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (202,3,10002,'2024002','李四','0','2005-03-22','13800138002','1',NULL,2001,'2024-12-15 09:15:00',2001,'2024-12-15 09:15:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (203,3,10003,'2024003','王五','0','2005-09-10','13800138003','3',70,2001,'2024-12-15 09:20:00',2001,'2024-12-15 09:20:00','期末考试压力大','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (204,3,10004,'2024004','赵六','1','2005-11-05','13800138004','2',NULL,2001,'2024-12-15 09:25:00',2001,'2024-12-15 09:25:00',NULL,'000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (205,3,10005,'2024005','钱七','1','2005-07-20','13800138005','3',85,2001,'2024-12-15 09:30:00',2001,'2024-12-15 09:30:00','家庭情况特殊,需要关注','000000',2001,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489421160449,1948197488653602817,1745003000000000001,'202101001','张三','M','2003-01-01','13800138001','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549058,1948197488653602817,1745003000000000002,'202101002','李四','F','2003-02-15','13800138002','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549059,1948197488653602817,1745003000000000003,'202101003','王五','M','2003-03-20','13800138003','2',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489429549060,1948197488653602817,1945274229082411010,'202101005','陈七','M','2014-07-18','13823456789','2',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489433743362,1948197488653602817,1945278506022588417,'202101006','李八','F','2016-06-15','13823456543','1',NULL,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489433743363,1948197488653602817,1945285788701495297,'202101007','徐九','M','2015-07-23','13634567898','3',75,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948197489437937666,1948197488653602817,1945291737352851457,'202101008','郭靖','M','2015-07-17','13634567654','3',70,1,'2025-07-24 09:44:12',1,'2025-07-24 09:44:12',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295184846849,1948210294098522113,1745003000000000001,'202101001','张三','M','2003-01-01','13800138001','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041153,1948210294098522113,1745003000000000002,'202101002','李四','F','2003-02-15','13800138002','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041154,1948210294098522113,1745003000000000003,'202101003','王五','M','2003-03-20','13800138003','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295189041155,1948210294098522113,1945274229082411010,'202101005','陈七','M','2014-07-18','13823456789','1',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295193235457,1948210294098522113,1945278506022588417,'202101006','李八','F','2016-06-15','13823456543','2',NULL,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295193235458,1948210294098522113,1945285788701495297,'202101007','徐九','M','2015-07-23','13634567898','3',72,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
INSERT INTO `xljk_evaluation_detail` VALUES (1948210295197429762,1948210294098522113,1945291737352851457,'202101008','郭靖','M','2015-07-17','13634567654','3',70,1,'2025-07-24 10:35:05',1,'2025-07-24 10:35:05',NULL,NULL,103,'0');
/*!40000 ALTER TABLE `xljk_evaluation_detail` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-07-24 11:05:57
@@ -0,0 +1,70 @@
-- 心理健康测评模块数据库脚本
-- 适用于阿里云RDS MySQL数据库
-- 创建时间:2025-07-24
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- 表结构和数据:xljk_evaluation
-- ----------------------------
DROP TABLE IF EXISTS `xljk_evaluation`;
CREATE TABLE `xljk_evaluation` (
`id` bigint NOT NULL COMMENT '主键ID',
`department_id` bigint NOT NULL COMMENT '院系ID',
`department_name` varchar(100) NOT NULL COMMENT '院系名称',
`evaluation_name` varchar(100) NOT NULL COMMENT '测评名称',
`major_id` bigint NOT NULL COMMENT '专业ID',
`major_name` varchar(100) NOT NULL COMMENT '专业名称',
`class_id` bigint NOT NULL COMMENT '班级ID',
`class_name` varchar(100) NOT NULL COMMENT '班级名称',
`semester` varchar(50) NOT NULL COMMENT '学期(如2024上学期)',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0-草稿,1-已发布,2-已完成)',
`create_by` bigint NOT NULL COMMENT '创建者ID(班主任ID)',
`create_name` varchar(50) NOT NULL COMMENT '创建者姓名',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',
`create_dept` bigint NOT NULL COMMENT '创建部门',
`deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',
`student_count` int DEFAULT '0' COMMENT '学生总人数',
`focus_count` int DEFAULT '0' COMMENT '重点关注人数',
PRIMARY KEY (`id`),
KEY `idx_class_id` (`class_id`),
KEY `idx_semester` (`semester`),
KEY `idx_status` (`status`),
KEY `idx_department_id` (`department_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='心理健康测评表';
-- ----------------------------
-- 表结构和数据:xljk_evaluation_detail
-- ----------------------------
DROP TABLE IF EXISTS `xljk_evaluation_detail`;
CREATE TABLE `xljk_evaluation_detail` (
`id` bigint NOT NULL COMMENT '主键ID',
`evaluation_id` bigint NOT NULL COMMENT '测评表ID',
`student_id` bigint NOT NULL COMMENT '学生ID',
`student_no` varchar(50) NOT NULL COMMENT '学号',
`student_name` varchar(50) NOT NULL COMMENT '学生姓名',
`gender` char(1) DEFAULT NULL COMMENT '性别(0-男,1-女,2-未知)',
`birth_date` date DEFAULT NULL COMMENT '出生日期',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`mental_status` char(1) NOT NULL COMMENT '心理状态(1-健康,2-良好,3-重点关注)',
`score` int DEFAULT NULL COMMENT '分数(仅重点关注时填写)',
`create_by` bigint NOT NULL COMMENT '创建者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户ID',
`create_dept` bigint NOT NULL COMMENT '创建部门',
`deleted` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0-存在,1-删除)',
PRIMARY KEY (`id`),
KEY `idx_evaluation_id` (`evaluation_id`),
KEY `idx_student_id` (`student_id`),
KEY `idx_mental_status` (`mental_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='心理健康测评明细表';
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,72 @@
# 心理健康测评模块数据库导入完成报告
## 导入概述
本次数据库迁移已成功将心理健康测评模块的表结构和数据从本地导入到阿里云数据库中。
### 导入时间
- 导入日期:2025-07-24
- 导入时间:11:15:00
### 导入数据库信息
- 服务器地址:47.99.164.66
- 端口:3306
- 数据库名:hzdyjs_xg
- 用户名:root
## 导入内容
### 表结构
成功导入以下表结构:
1. **xljk_evaluation** - 心理健康测评表,包含21个字段
2. **xljk_evaluation_detail** - 心理健康测评明细表,包含18个字段
### 数据量
- **xljk_evaluation**: 5条记录
- **xljk_evaluation_detail**: 24条记录
## 导入验证
### 验证方法
1. 通过MySQL命令行工具连接到阿里云数据库
2. 执行SQL查询检查表结构和数据
3. 验证关键字段的数据完整性
4. 确认索引和主键约束正常工作
### 验证结果
- ✅ 表结构完整,包含所有必要字段
- ✅ 数据成功导入,数量正确
- ✅ 字段类型和长度符合设计规范
- ✅ 索引和主键约束正确设置
## 注意事项
1. 已修改应用程序配置文件,指向阿里云数据库
- 开发环境配置文件:backend/ruoyi-admin/src/main/resources/application-dev.yml
- 生产环境配置文件:backend/ruoyi-admin/src/main/resources/application-prod.yml
2. 表包含以下主要功能数据:
- 基础测评记录
- 学生心理状态评估
- 关注分数统计
3. 需要注意的特殊字段:
- `status`: 0-草稿, 1-已发布, 2-已完成
- `mental_status`: 1-健康, 2-良好, 3-重点关注
- `deleted`: 0-存在, 1-删除(逻辑删除标记)
## 后续工作建议
1. 定期备份阿里云数据库
2. 在进行大规模数据修改前备份表数据
3. 密切监控应用程序对数据库的连接和性能
4. 考虑设置数据库自动备份策略
## 总结
心理健康测评模块的所有数据已成功迁移到阿里云数据库,应用程序已配置为使用新的数据库连接。数据库结构和数据已通过验证,确认完整无误。
---
导入人员:管理员
导入日期:2025-07-24
@@ -0,0 +1,48 @@
# 心理健康测评模块数据导入说明
本文件夹包含心理健康测评模块的表结构和数据,可用于阿里云RDS MySQL数据库的导入。
## 文件说明
- `xljk_evaluation_tables.sql`: 包含xljk_evaluation和xljk_evaluation_detail两个表的完整建表语句和数据
## 导入方法
### 方法一:使用MySQL命令行工具
1. 登录到您的阿里云服务器或本地终端
2. 运行以下命令将SQL文件导入到数据库中
```bash
mysql -h <阿里云RDS连接地址> -u <用户名> -p<密码> <数据库名> < xljk_evaluation_tables.sql
```
例如:
```bash
mysql -h rm-bp1234567890abcd.mysql.rds.aliyuncs.com -u root -pYourPassword hzdyjs_xg < xljk_evaluation_tables.sql
```
### 方法二:使用DMS数据管理服务
1. 登录阿里云RDS控制台
2. 点击目标实例,选择"登录数据库"进入DMS
3. 在DMS界面中,选择目标数据库
4. 点击"SQL操作" -> "SQL窗口"
5. 点击"导入SQL文件",选择上传xljk_evaluation_tables.sql文件
6. 执行SQL文件导入
### 方法三:使用MySQL Workbench等图形化工具
1. 打开MySQL Workbench并连接到阿里云RDS数据库
2. 选择"Server" -> "Data Import"
3. 选择"Import from Self-Contained File"选项,并浏览选择xljk_evaluation_tables.sql文件
4. 选择目标数据库
5. 点击"Start Import"开始导入
## 注意事项
- 导入前请确认数据库中是否已存在同名表,如存在请先备份数据
- 本SQL文件包含DROP TABLE语句,会删除已存在的同名表
- 请确保数据库用户拥有创建表和插入数据的权限
- 如遇到编码问题,请确保数据库服务器使用utf8mb4字符集
@@ -14,7 +14,7 @@ CREATE TABLE `xljk_evaluation` (
`class_id` bigint(20) NOT NULL COMMENT '班级ID',
`class_name` varchar(100) NOT NULL COMMENT '班级名称',
`semester` varchar(50) NOT NULL COMMENT '学期(如2024上学期)',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0-草稿,1-已发布,2-已完成)',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0-草稿,2-已完成)',
`create_by` bigint(20) NOT NULL COMMENT '创建者ID(班主任ID)',
`create_name` varchar(50) NOT NULL COMMENT '创建者姓名',
`create_time` datetime NOT NULL COMMENT '创建时间',
@@ -79,8 +79,7 @@ INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES
-- 添加心理健康测评状态字典
INSERT INTO `sys_dict_type` VALUES(1000, '心理测评状态', 'evaluation_status', '0', 1, NOW(), NULL, NULL, '心理健康测评状态');
INSERT INTO `sys_dict_data` VALUES(1001, 0, '草稿', '0', 'evaluation_status', '', 'warning', 'N', '0', 1, NOW(), 1, NOW(), '草稿状态');
INSERT INTO `sys_dict_data` VALUES(1002, 1, '已发布', '1', 'evaluation_status', '', 'primary', 'N', '0', 1, NOW(), 1, NOW(), '已发布状态');
INSERT INTO `sys_dict_data` VALUES(1003, 2, '已完成', '2', 'evaluation_status', '', 'success', 'N', '0', 1, NOW(), 1, NOW(), '已完成状态');
INSERT INTO `sys_dict_data` VALUES(1002, 1, '已完成', '2', 'evaluation_status', '', 'success', 'N', '0', 1, NOW(), 1, NOW(), '已完成状态');
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,20 @@
-- ==========================================
-- 删除心理测评状态字典中的"已发布"状态
-- 版本:V1.0.0
-- 功能:根据需求调整,心理健康测评只保留"草稿"和"已完成"两种状态
-- 作者:Cursor AI
-- 时间:2025-07-23
-- ==========================================
-- 设置字符集
SET NAMES utf8mb4;
-- 删除"已发布"状态的字典数据
DELETE FROM `sys_dict_data` WHERE `dict_type` = 'evaluation_status' AND `dict_value` = '1';
-- 更新字典顺序
UPDATE `sys_dict_data` SET `dict_sort` = 1 WHERE `dict_type` = 'evaluation_status' AND `dict_value` = '2';
-- 验证结果
SELECT '删除心理测评状态字典中的已发布状态完成!' AS result;
SELECT * FROM `sys_dict_data` WHERE `dict_type` = 'evaluation_status' ORDER BY `dict_sort`;
+2 -2
View File
@@ -119,7 +119,7 @@ export const getSemesterOptions = () => {
});
};
// 发布测评
// 发布测评(已废弃,改为提交功能)
export const publishEvaluation = (id: string | number) => {
return request({
url: `/xljk/evaluation/${id}/publish`,
@@ -127,7 +127,7 @@ export const publishEvaluation = (id: string | number) => {
});
};
// 完成测评
// 提交测评
export const completeEvaluation = (id: string | number) => {
return request({
url: `/xljk/evaluation/${id}/complete`,
+17 -2
View File
@@ -45,7 +45,7 @@ export interface XljkEvaluationVO {
semester: string;
/**
* 状态(0-草稿,1-已发布,2-已完成)
* 状态(0-草稿,2-已完成)
*/
status: string;
@@ -137,7 +137,7 @@ export interface XljkEvaluationForm extends BaseEntity {
semester?: string;
/**
* 状态(0-草稿,1-已发布,2-已完成)
* 状态(0-草稿,2-已完成)
*/
status?: string;
@@ -443,6 +443,11 @@ export interface StudentInfo {
}
export interface CollegeOption {
/**
* 院系ID
*/
id: number;
/**
* 院系名称
*/
@@ -450,6 +455,11 @@ export interface CollegeOption {
}
export interface MajorOption {
/**
* 专业ID
*/
id: number;
/**
* 专业名称
*/
@@ -457,6 +467,11 @@ export interface MajorOption {
}
export interface ClassOption {
/**
* 班级ID
*/
id: number;
/**
* 班级名称
*/
+5 -5
View File
@@ -98,25 +98,25 @@ export const constantRoutes: RouteRecordRaw[] = [
path: 'evaluation/detail/:id',
component: () => import('@/views/xljk/evaluation/detail.vue'),
name: 'XljkEvaluationDetail',
meta: { title: '心理健康测评详情', icon: 'form', activeMenu: '/xljk/evaluation' }
meta: { title: '心理健康测评详情', icon: 'form', activeMenu: '/xljk/evaluation', noCache: true }
},
{
path: 'evaluation/add',
component: () => import('@/views/xljk/evaluation/add.vue'),
name: 'XljkEvaluationAdd',
meta: { title: '新增心理健康测评', icon: 'form', activeMenu: '/xljk/evaluation' }
meta: { title: '新增心理健康测评', icon: 'form', activeMenu: '/xljk/evaluation', noCache: true }
},
{
path: 'evaluation/edit/:id',
component: () => import('@/views/xljk/evaluation/edit.vue'),
name: 'XljkEvaluationEdit',
meta: { title: '编辑心理健康测评', icon: 'form', activeMenu: '/xljk/evaluation' }
meta: { title: '编辑心理健康测评', icon: 'form', activeMenu: '/xljk/evaluation', noCache: true }
},
{
path: 'evaluation/fill/:id',
component: () => import('@/views/xljk/evaluation/fill.vue'),
name: 'XljkEvaluationFill',
meta: { title: '填写心理健康测评', icon: 'form', activeMenu: '/xljk/evaluation' }
meta: { title: '填写心理健康测评', icon: 'form', activeMenu: '/xljk/evaluation', noCache: true }
}
]
}
@@ -134,7 +134,7 @@ export const dynamicRoutes: RouteRecordRaw[] = [
path: 'evaluation',
component: () => import('@/views/xljk/evaluation/index.vue'),
name: 'XljkEvaluation',
meta: { title: '心理健康测评', icon: 'heart', permissions: ['xljk:evaluation:list'] }
meta: { title: '心理健康测评', icon: 'heart', permissions: ['xljk:evaluation:list'], noCache: true }
}
]
}
+1 -1
View File
@@ -1,6 +1,6 @@
export const errorCode: any = {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'403': '无访问权限',
'404': '访问资源不存在',
default: '系统未知错误,请反馈给管理员'
};
+11
View File
@@ -177,6 +177,17 @@ service.interceptors.response.use(
console.log('404错误被静默处理,不显示用户提示');
return Promise.reject(error);
}
// 对心理健康测评详情页面的403错误进行特殊处理
if (statusCode === '403') {
const url = error.config.url;
// 如果是心理健康测评详情相关的API,不显示错误提示
if (url && (url.includes('/xljk/evaluation/') || url.includes('/xljk/evaluation/detail/'))) {
console.log('心理健康测评详情页面403错误被静默处理,不显示用户提示');
return Promise.reject(error);
}
}
message = '系统接口' + statusCode + '异常';
}
ElMessage({ message: message, type: 'error', duration: 5 * 1000 });
+322 -97
View File
@@ -1,93 +1,112 @@
<template>
<div class="p-2 page-container">
<el-card shadow="hover" class="mb-[10px]">
<el-card shadow="hover" class="mb-[10px]" v-loading="formLoading">
<template #header>
<div class="card-header">
<span class="header-title">新增心理健康测评</span>
</div>
</template>
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="测评名称" prop="evaluationName">
<el-input
v-model="form.evaluationName"
placeholder="请输入测评名称"
style="width: 500px"
maxlength="100"
show-word-limit
/>
</el-form-item>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="测评名称" prop="evaluationName">
<el-input
v-model="form.evaluationName"
placeholder="请输入测评名称"
style="width: 100%"
maxlength="100"
show-word-limit
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学期" prop="semester">
<el-input
v-model="form.semester"
placeholder="请输入学期,如:2024上学期"
style="width: 100%"
maxlength="50"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="院系" prop="departmentName">
<el-select
v-model="form.departmentName"
placeholder="请选择院系"
style="width: 500px"
@change="handleCollegeChange"
>
<el-option
v-for="college in collegeOptions"
:key="college.name"
:label="college.name"
:value="college.name"
/>
</el-select>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="院系" prop="departmentName">
<el-select
v-model="form.departmentName"
placeholder="请选择院系"
style="width: 100%"
@change="handleCollegeChange"
:loading="collegeLoading"
>
<el-option
v-for="college in collegeOptions"
:key="college.id"
:label="college.name"
:value="college.name"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="专业" prop="majorName">
<el-select
v-model="form.majorName"
placeholder="请选择专业"
style="width: 100%"
@change="handleMajorChange"
:disabled="!form.departmentName"
:loading="majorLoading"
>
<el-option
v-for="major in majorOptions"
:key="major.id"
:label="major.name"
:value="major.name"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="专业" prop="majorName">
<el-select
v-model="form.majorName"
placeholder="请选择专业"
style="width: 500px"
@change="handleMajorChange"
:disabled="!form.departmentName"
>
<el-option
v-for="major in majorOptions"
:key="major.name"
:label="major.name"
:value="major.name"
/>
</el-select>
</el-form-item>
<el-form-item label="班级" prop="className">
<el-select
v-model="form.className"
placeholder="请选择班级"
style="width: 500px"
@change="handleClassChange"
:disabled="!form.majorName"
>
<el-option
v-for="cls in classOptions"
:key="cls.name"
:label="cls.name"
:value="cls.name"
/>
</el-select>
</el-form-item>
<el-form-item label="学期" prop="semester">
<el-input
v-model="form.semester"
placeholder="请输入学期,如:2024上学期"
style="width: 500px"
maxlength="50"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
placeholder="请输入备注信息"
style="width: 500px"
:rows="4"
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="班级" prop="className">
<el-select
v-model="form.className"
placeholder="请选择班级"
style="width: 100%"
@change="handleClassChange"
:disabled="!form.majorName"
:loading="classLoading"
>
<el-option
v-for="cls in classOptions"
:key="cls.id"
:label="cls.name"
:value="cls.name"
:data-id="cls.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
placeholder="请输入备注信息"
style="width: 100%"
:rows="1"
maxlength="500"
show-word-limit
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<div class="form-buttons">
@@ -117,14 +136,36 @@
:closable="false"
/>
<!-- 批量操作区域 -->
<div class="batch-actions" v-if="studentList.length > 0">
<span class="batch-label">批量设置心理状态:</span>
<el-radio-group v-model="batchMentalStatus">
<el-radio-button label="1">健康</el-radio-button>
<el-radio-button label="2">良好</el-radio-button>
<el-radio-button label="3">重点关注</el-radio-button>
</el-radio-group>
<el-button type="primary" size="small" @click="applyBatchMentalStatus" :disabled="selectedStudents.length === 0">
应用到所选学生
</el-button>
<el-button type="info" size="small" @click="applyBatchMentalStatusToAll">
应用到全部学生
</el-button>
<el-button type="warning" size="small" @click="resetAllMentalStatus">
重置所有状态
</el-button>
<span class="batch-hint">已选择 {{ selectedStudents.length }} 名学生</span>
</div>
<!-- 学生列表表格 -->
<el-table
v-else
v-if="studentList.length > 0"
:data="studentList"
border
stripe
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="学号" align="center" prop="studentNo" width="120" />
<el-table-column label="姓名" align="center" prop="studentName" width="100" />
<el-table-column label="性别" align="center" prop="gender" width="80">
@@ -195,13 +236,35 @@
import { addEvaluation, getCollegeOptions, getMajorOptions, getClassOptions, getStudentsByClass, batchAddEvaluationDetails } from '@/api/xljk/evaluation';
import { XljkEvaluationForm, StudentInfo, CollegeOption, MajorOption, ClassOption } from '@/api/xljk/evaluation/types';
import { useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const formRef = ref<ElFormInstance>();
const submitLoading = ref(false);
const studentsLoading = ref(false);
const formLoading = ref(false);
const collegeLoading = ref(false);
const majorLoading = ref(false);
const classLoading = ref(false);
const batchMentalStatus = ref('1'); // 默认批量设置为"健康"
const selectedStudents = ref<StudentInfo[]>([]); // 选中的学生
/** 自动生成当前学期 */
const generateCurrentSemester = () => {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1; // 月份从0开始
// 上半年(1-7月)为下学期,下半年(8-12月)为上学期
if (month >= 8) {
return `${year}上学期`;
} else if (month <= 7) {
return `${year}下学期`;
}
return `${year}上学期`; // 默认返回上学期
};
// 表单数据
const form = ref<XljkEvaluationForm>({
@@ -212,11 +275,29 @@ const form = ref<XljkEvaluationForm>({
majorId: undefined, // 这里保留majorId字段,但实际使用majorName
className: undefined,
classId: undefined, // 这里保留classId字段,但实际使用className
semester: undefined,
semester: generateCurrentSemester(), // 自动生成当前学期
status: '0', // 默认为草稿状态
remark: undefined
});
/** 自动生成测评名称 */
const generateEvaluationName = () => {
const semester = form.value.semester || '';
const className = form.value.className || '';
if (semester && className) {
return `${semester}${className}心理健康测评`;
}
return '';
};
// 监听学期变化,自动更新测评名称
watch(() => form.value.semester, (newSemester) => {
if (newSemester && form.value.className) {
form.value.evaluationName = generateEvaluationName();
}
});
// 表单验证规则
const rules = {
evaluationName: [{ required: true, message: '测评名称不能为空', trigger: 'blur' }],
@@ -235,30 +316,72 @@ const studentList = ref<StudentInfo[]>([]);
/** 获取院系选项 */
const getColleges = async () => {
try {
collegeLoading.value = true;
formLoading.value = true;
const res = await getCollegeOptions();
collegeOptions.value = res.data || [];
// 如果获取到院系选项,自动选择第一个
if (collegeOptions.value.length > 0) {
form.value.departmentName = collegeOptions.value[0].name;
form.value.departmentId = collegeOptions.value[0].id;
// 获取对应的专业选项
await getMajors(form.value.departmentName);
}
} catch (error) {
console.error('获取院系选项失败', error);
} finally {
collegeLoading.value = false;
formLoading.value = false;
}
};
/** 获取专业选项 */
const getMajors = async (collegeName: string) => {
try {
majorLoading.value = true;
formLoading.value = true;
const res = await getMajorOptions(collegeName);
majorOptions.value = res.data || [];
// 如果获取到专业选项,自动选择第一个
if (majorOptions.value.length > 0) {
form.value.majorName = majorOptions.value[0].name;
form.value.majorId = majorOptions.value[0].id;
// 获取对应的班级选项
await getClasses(form.value.departmentName, form.value.majorName);
}
} catch (error) {
console.error('获取专业选项失败', error);
} finally {
majorLoading.value = false;
formLoading.value = false;
}
};
/** 获取班级选项 */
const getClasses = async (collegeName: string, majorName: string) => {
try {
classLoading.value = true;
formLoading.value = true;
const res = await getClassOptions(collegeName, majorName);
classOptions.value = res.data || [];
// 如果获取到班级选项,自动选择第一个
if (classOptions.value.length > 0) {
form.value.className = classOptions.value[0].name;
form.value.classId = classOptions.value[0].id;
// 获取班级学生列表
await handleClassChange(form.value.className);
}
} catch (error) {
console.error('获取班级选项失败', error);
} finally {
classLoading.value = false;
formLoading.value = false;
}
};
@@ -297,11 +420,25 @@ const handleClassChange = async (className: string) => {
return;
}
// 设置班级ID
const selectedClass = classOptions.value.find(c => c.name === className);
if (selectedClass) {
form.value.classId = selectedClass.id;
}
// 自动生成测评名称
form.value.evaluationName = generateEvaluationName();
// 获取班级学生列表
try {
studentsLoading.value = true;
const res = await getStudentsByClass(form.value.departmentName, form.value.majorName, className);
studentList.value = res.data || [];
// 设置默认的心理状态为"健康"
studentList.value = (res.data || []).map(student => ({
...student,
mentalStatus: '1', // 默认设置为"健康"
remark: '' // 初始化备注为空字符串
}));
} catch (error) {
console.error('获取班级学生列表失败', error);
studentList.value = [];
@@ -326,6 +463,60 @@ const countFocusStudents = () => {
return studentList.value.filter(student => student.mentalStatus === '3').length;
};
/** 批量设置心理状态 */
const applyBatchMentalStatus = () => {
const newStatus = batchMentalStatus.value;
selectedStudents.value.forEach(student => {
student.mentalStatus = newStatus;
// 如果心理状态是"重点关注",设置默认分数
if (newStatus === '3') {
student.score = student.score || 70;
} else {
student.score = undefined;
}
});
};
/** 批量设置心理状态到全部学生 */
const applyBatchMentalStatusToAll = () => {
const newStatus = batchMentalStatus.value;
studentList.value.forEach(student => {
student.mentalStatus = newStatus;
// 如果心理状态是"重点关注",设置默认分数
if (newStatus === '3') {
student.score = student.score || 70;
} else {
student.score = undefined;
}
});
};
/** 重置所有学生的心理状态 */
const resetAllMentalStatus = () => {
ElMessageBox.confirm('确认要将所有学生的心理状态重置为"健康"吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
studentList.value.forEach(student => {
student.mentalStatus = '1'; // 重置为"健康"
student.score = undefined; // 清空分数
student.remark = ''; // 清空备注
});
ElMessage({
type: 'success',
message: '已重置所有学生的心理状态'
});
}).catch(() => {
// 取消操作
});
};
/** 处理表格多选 */
const handleSelectionChange = (selection: StudentInfo[]) => {
selectedStudents.value = selection;
};
/** 提交表单 */
const submitForm = () => {
formRef.value?.validate(async (valid: boolean) => {
@@ -354,18 +545,22 @@ const submitForm = () => {
return;
}
// 确保ID字段有值,即使是临时值
if (form.value.departmentName && !form.value.departmentId) {
form.value.departmentId = 0; // 临时ID,后端会基于departmentName处理
// 确保ID字段有值,使用从选项中获取的ID
if (form.value.departmentName) {
const selectedCollege = collegeOptions.value.find(c => c.name === form.value.departmentName);
if (selectedCollege) {
form.value.departmentId = selectedCollege.id;
}
}
if (form.value.majorName && !form.value.majorId) {
form.value.majorId = 0; // 临时ID,后端会基于majorName处理
if (form.value.majorName) {
const selectedMajor = majorOptions.value.find(m => m.name === form.value.majorName);
if (selectedMajor) {
form.value.majorId = selectedMajor.id;
}
}
if (form.value.className && !form.value.classId) {
form.value.classId = 0; // 临时ID,后端会基于className处理
}
// 班级ID已在handleClassChange中设置
// 先创建测评
const res = await addEvaluation(form.value);
@@ -386,9 +581,9 @@ const submitForm = () => {
gender: student.gender,
birthDate: student.birthDate,
phone: student.phone,
mentalStatus: student.mentalStatus || '1', // 默认健康
mentalStatus: student.mentalStatus || '1', // 确保有默认值"健康"
score: student.mentalStatus === '3' ? student.score : undefined,
remark: student.remark
remark: student.remark || '' // 确保备注有默认值
};
});
@@ -399,7 +594,7 @@ const submitForm = () => {
// 注:这部分逻辑可能需要在后端自动处理
proxy?.$modal.msgSuccess('新增成功');
router.push('/xljk/evaluation');
router.replace('/xljk/evaluation');
} else {
proxy?.$modal.msgError('新增测评失败');
}
@@ -414,7 +609,7 @@ const submitForm = () => {
/** 取消按钮 */
const cancel = () => {
router.push('/xljk/evaluation');
router.replace('/xljk/evaluation');
};
onMounted(() => {
@@ -423,10 +618,12 @@ onMounted(() => {
</script>
<style scoped>
/* 页面容器样式 */
.page-container {
padding: 8px;
}
/* 表格卡片布局 */
.card-header {
display: flex;
justify-content: space-between;
@@ -445,7 +642,14 @@ onMounted(() => {
}
.form-buttons {
margin-top: 10px;
margin-top: 0;
display: flex;
justify-content: center;
}
/* 减小表单项之间的间距 */
:deep(.el-form-item) {
margin-bottom: 12px;
}
.student-count {
@@ -454,4 +658,25 @@ onMounted(() => {
color: #606266;
font-size: 14px;
}
.batch-actions {
margin-bottom: 10px;
padding: 10px;
background-color: #f5f7fa;
border-radius: 4px;
display: flex;
align-items: center;
gap: 10px;
}
.batch-label {
font-size: 14px;
color: #303133;
}
.batch-hint {
font-size: 12px;
color: #909399;
margin-left: 10px;
}
</style>
+175 -51
View File
@@ -26,7 +26,7 @@
</el-card>
<!-- 统计信息卡片 -->
<el-card shadow="hover" class="mb-[10px]" v-loading="statisticsLoading">
<el-card shadow="hover" class="mb-[10px] statistics-card" v-loading="statisticsLoading">
<template #header>
<div class="card-header">
<span class="header-title">测评统计</span>
@@ -35,29 +35,37 @@
<div class="statistics-container">
<div class="statistics-row">
<el-statistic title="学生总数" :value="statistics.totalStudents">
<template #suffix>
<span class="suffix-label">人</span>
</template>
</el-statistic>
<div class="statistic-item">
<el-statistic title="学生总数" :value="statistics.totalStudents">
<template #suffix>
<span class="suffix-label">人</span>
</template>
</el-statistic>
</div>
<el-statistic title="健康学生" :value="statistics.healthyCount">
<template #suffix>
<span class="suffix-label">人 ({{ formatPercent(statistics.healthyPercent) }})</span>
</template>
</el-statistic>
<div class="statistic-item">
<el-statistic title="健康学生" :value="statistics.healthyCount">
<template #suffix>
<span class="suffix-label">人 ({{ formatPercent(statistics.healthyPercent) }})</span>
</template>
</el-statistic>
</div>
<el-statistic title="良好学生" :value="statistics.goodCount">
<template #suffix>
<span class="suffix-label">人 ({{ formatPercent(statistics.goodPercent) }})</span>
</template>
</el-statistic>
<div class="statistic-item">
<el-statistic title="良好学生" :value="statistics.goodCount">
<template #suffix>
<span class="suffix-label">人 ({{ formatPercent(statistics.goodPercent) }})</span>
</template>
</el-statistic>
</div>
<el-statistic title="重点关注" :value="statistics.focusCount" value-style="color: #f56c6c;">
<template #suffix>
<span class="suffix-label" style="color: #f56c6c;">人 ({{ formatPercent(statistics.focusPercent) }})</span>
</template>
</el-statistic>
<div class="statistic-item">
<el-statistic title="重点关注" :value="statistics.focusCount" value-style="color: #f56c6c;">
<template #suffix>
<span class="suffix-label" style="color: #f56c6c;">人 ({{ formatPercent(statistics.focusPercent) }})</span>
</template>
</el-statistic>
</div>
</div>
<!-- 图表展示 -->
@@ -92,6 +100,10 @@
<el-icon class="el-input__icon" @click="handleSearch"><Search /></el-icon>
</template>
</el-input>
<el-button type="info" plain size="small" style="margin-left: 10px" @click="resetFilter">
清除筛选
</el-button>
</div>
</div>
</template>
@@ -102,6 +114,7 @@
:data="detailList"
stripe
style="width: 100%"
:empty-text="filterStatus || searchKeyword ? '没有符合条件的数据' : '暂无数据'"
>
<el-table-column label="学号" align="center" prop="studentNo" width="120" />
<el-table-column label="姓名" align="center" prop="studentName" width="100" />
@@ -132,6 +145,11 @@
</el-table>
<div class="pagination-container">
<div class="filter-info">
<span v-if="filterStatus">当前筛选:{{ filterStatus === '1' ? '健康' : filterStatus === '2' ? '良好' : '重点关注' }}</span>
<span v-if="searchKeyword">搜索关键词:{{ searchKeyword }}</span>
<span>共找到 {{ total }} 条记录</span>
</div>
<pagination
v-show="total > 0"
:total="total"
@@ -152,6 +170,8 @@ import * as echarts from 'echarts/core';
import { PieChart } from 'echarts/charts';
import { TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { Search } from '@element-plus/icons-vue';
import { ElLoading, ElMessage } from 'element-plus';
// 注册必要的组件
echarts.use([PieChart, TooltipComponent, LegendComponent, TitleComponent, CanvasRenderer]);
@@ -200,6 +220,16 @@ const getEvaluationInfo = async () => {
evaluationInfo.value = res.data;
} catch (error) {
console.error('获取测评信息失败', error);
// 显示友好的错误提示,而不是"无权限"
if (error.response && error.response.status === 403) {
proxy?.$modal.msgError('您没有查看该测评的权限');
} else {
proxy?.$modal.msgError('获取测评信息失败,请稍后再试');
}
// 返回列表页
setTimeout(() => {
router.push('/xljk/evaluation');
}, 1500);
}
};
@@ -223,12 +253,49 @@ const getStatistics = async () => {
const getDetailList = async () => {
try {
loading.value = true;
// 使用getEvaluationDetailsByEvaluationId替代listEvaluationDetail
// 因为listEvaluationDetail需要分页参数,而我们需要的是获取指定测评ID的所有明细
console.log('查询参数:', {
filterStatus: filterStatus.value,
searchKeyword: searchKeyword.value,
studentNo: queryParams.value.studentNo,
studentName: queryParams.value.studentName
});
// 使用getEvaluationDetailsByEvaluationId获取所有数据
const res = await getEvaluationDetailsByEvaluationId(evaluationId.value);
if (res.data) {
detailList.value = res.data;
total.value = res.data.length;
// 存储原始数据
const allDetails = res.data;
console.log('获取到的原始数据:', allDetails.length, '条');
// 根据过滤条件筛选数据
let filteredData = [...allDetails];
// 按心理状态筛选
if (filterStatus.value) {
filteredData = filteredData.filter(item => item.mentalStatus === filterStatus.value);
console.log('按心理状态筛选后:', filteredData.length, '条');
}
// 按学号或姓名搜索
if (searchKeyword.value) {
const keyword = searchKeyword.value.toLowerCase();
filteredData = filteredData.filter(item =>
(item.studentNo && item.studentNo.toLowerCase().includes(keyword)) ||
(item.studentName && item.studentName.toLowerCase().includes(keyword))
);
console.log('按关键词筛选后:', filteredData.length, '条');
}
// 分页处理
const pageSize = queryParams.value.pageSize;
const pageNum = queryParams.value.pageNum;
const startIndex = (pageNum - 1) * pageSize;
const endIndex = startIndex + pageSize;
// 设置总数和当前页数据
total.value = filteredData.length;
detailList.value = filteredData.slice(startIndex, endIndex);
console.log('最终显示数据:', detailList.value.length, '条');
} else {
detailList.value = [];
total.value = 0;
@@ -257,15 +324,26 @@ const initPieChart = () => {
const option = {
title: {
text: '心理状态分布',
left: 'center'
left: 'center',
textStyle: {
fontSize: 14
},
top: 5,
padding: 5
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
orient: 'horizontal',
left: 'center',
bottom: 0,
itemWidth: 12,
itemHeight: 8,
textStyle: {
fontSize: 12
},
data: ['健康', '良好', '重点关注']
},
color: ['#67C23A', '#E6A23C', '#F56C6C'],
@@ -273,8 +351,23 @@ const initPieChart = () => {
{
name: '心理状态',
type: 'pie',
radius: '60%',
radius: ['35%', '60%'], // 使用环形图,更节省空间
center: ['50%', '50%'],
avoidLabelOverlap: true,
itemStyle: {
borderRadius: 4,
borderWidth: 1,
borderColor: '#fff'
},
label: {
show: true,
formatter: '{b}: {c} ({d}%)',
fontSize: 12
},
labelLine: {
length: 10,
length2: 5
},
data: [
{ value: statistics.value.healthyCount, name: '健康' },
{ value: statistics.value.goodCount, name: '良好' },
@@ -282,9 +375,9 @@ const initPieChart = () => {
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowBlur: 5,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
shadowColor: 'rgba(0, 0, 0, 0.3)'
}
}
}
@@ -311,12 +404,13 @@ const goBack = () => {
/** 导出结果 */
const handleExport = () => {
console.log('导出测评明细,测评ID:', evaluationId.value);
proxy?.download(
'xljk/evaluationDetail/export',
'xljk/evaluation/detail/export',
{
evaluationId: evaluationId.value
},
`evaluation_detail_${evaluationId.value}_${new Date().getTime()}.xlsx`
`心理健康测评明细_${evaluationId.value}_${new Date().getTime()}.xlsx`
);
};
@@ -330,18 +424,15 @@ const handleFilterChange = () => {
/** 处理搜索 */
const handleSearch = () => {
queryParams.value.pageNum = 1;
// 不再需要设置queryParams,直接使用searchKeyword
getDetailList();
};
// 判断输入是否为数字(学号)或文本(姓名)
const isNumeric = /^\d+$/.test(searchKeyword.value);
if (isNumeric) {
queryParams.value.studentNo = searchKeyword.value;
queryParams.value.studentName = '';
} else {
queryParams.value.studentName = searchKeyword.value;
queryParams.value.studentNo = '';
}
/** 重置过滤条件 */
const resetFilter = () => {
filterStatus.value = '';
searchKeyword.value = '';
queryParams.value.pageNum = 1;
getDetailList();
};
@@ -394,15 +485,22 @@ onBeforeUnmount(() => {
/* 统计样式 */
.statistics-container {
padding: 10px 0;
padding: 5px 0;
}
.statistics-row {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
gap: 20px;
margin-bottom: 20px;
gap: 10px;
margin-bottom: 10px;
}
.statistic-item {
flex: 1; /* 让统计项占据相同宽度 */
min-width: 150px; /* 确保统计项有最小宽度 */
text-align: center;
padding: 0 5px;
}
.suffix-label {
@@ -414,13 +512,28 @@ onBeforeUnmount(() => {
.chart-container {
display: flex;
justify-content: center;
margin-top: 20px;
margin-bottom: 10px;
margin-top: 0;
margin-bottom: 0;
}
.pie-chart {
width: 600px;
height: 400px;
width: 500px;
height: 280px;
}
/* 统计卡片样式 */
.statistics-card :deep(.el-card__body) {
padding: 10px;
}
.statistics-card :deep(.el-statistic) {
--el-statistic-content-font-size: 20px;
--el-statistic-title-font-size: 14px;
--el-statistic-title-margin-bottom: 2px;
}
.statistics-card :deep(.el-card__header) {
padding: 10px 15px;
}
/* 分页容器样式 */
@@ -432,6 +545,17 @@ onBeforeUnmount(() => {
margin-top: 10px !important;
}
.filter-info {
display: flex;
gap: 20px;
align-items: center;
margin-bottom: 10px;
padding: 0 20px;
font-size: 14px;
color: #606266;
flex-grow: 1;
}
@media (max-width: 768px) {
.statistics-row {
flex-direction: column;
+145 -11
View File
@@ -82,13 +82,35 @@
:closable="false"
/>
<!-- 批量操作区域 -->
<div class="batch-actions" v-if="studentList.length > 0">
<span class="batch-label">批量设置心理状态:</span>
<el-radio-group v-model="batchMentalStatus">
<el-radio-button label="1">健康</el-radio-button>
<el-radio-button label="2">良好</el-radio-button>
<el-radio-button label="3">重点关注</el-radio-button>
</el-radio-group>
<el-button type="primary" size="small" @click="applyBatchMentalStatus" :disabled="selectedStudents.length === 0">
应用到所选学生
</el-button>
<el-button type="info" size="small" @click="applyBatchMentalStatusToAll">
应用到全部学生
</el-button>
<el-button type="warning" size="small" @click="resetAllMentalStatus">
重置所有状态
</el-button>
<span class="batch-hint">已选择 {{ selectedStudents.length }} 名学生</span>
</div>
<el-table
v-else
v-if="studentList.length > 0"
:data="studentList"
border
stripe
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="学号" align="center" prop="studentNo" width="120" />
<el-table-column label="姓名" align="center" prop="studentName" width="100" />
<el-table-column label="性别" align="center" prop="gender" width="80">
@@ -157,6 +179,7 @@
import { getEvaluation, updateEvaluation, getStudentsByClass, getEvaluationDetailsByEvaluationId, batchUpdateMentalStatus } from '@/api/xljk/evaluation';
import { XljkEvaluationForm, StudentInfo, XljkEvaluationDetailForm } from '@/api/xljk/evaluation/types';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_user_sex } = toRefs<any>(proxy?.useDict('sys_user_sex'));
@@ -202,7 +225,7 @@ const getEvaluationInfo = async () => {
// 检查状态是否为草稿
if (form.value.status !== '0') {
proxy?.$modal.msgError('只能编辑草稿状态的测评');
ElMessage.error('只能编辑草稿状态的测评');
setTimeout(() => {
router.push('/xljk/evaluation');
}, 1500);
@@ -234,12 +257,12 @@ const getStudents = async () => {
// 打印返回结果
console.log('获取学生列表的结果:', res);
studentList.value = res.data || [];
// 为每个学生初始化心理状态
studentList.value.forEach(student => {
student.mentalStatus = student.mentalStatus || '1'; // 默认健康
});
// 设置默认的心理状态为"健康"
studentList.value = (res.data || []).map(student => ({
...student,
mentalStatus: '1', // 默认设置为"健康"
remark: '' // 初始化备注为空字符串
}));
} catch (error) {
console.error('获取班级学生列表失败', error);
studentList.value = [];
@@ -288,6 +311,99 @@ const countFocusStudents = () => {
return studentList.value.filter(student => student.mentalStatus === '3').length;
};
/** 批量设置心理状态 */
const batchMentalStatus = ref('1'); // 默认健康
const selectedStudents = ref<StudentInfo[]>([]); // 选中的学生列表
const handleSelectionChange = (selection: StudentInfo[]) => {
selectedStudents.value = selection;
};
const applyBatchMentalStatus = async () => {
if (selectedStudents.value.length === 0) {
ElMessage.error('请选择要批量设置的学生');
return;
}
const status = batchMentalStatus.value;
const detailsToUpdate = selectedStudents.value.map(student => {
return {
id: student.detailId,
evaluationId: form.value.id,
studentId: student.studentId,
studentNo: student.studentNo,
studentName: student.studentName,
gender: student.gender,
birthDate: student.birthDate,
phone: student.phone,
mentalStatus: status,
score: status === '3' ? 70 : undefined, // 默认分数
remark: student.remark
} as XljkEvaluationDetailForm;
});
await batchUpdateMentalStatus(detailsToUpdate);
ElMessage.success(`已批量设置 ${selectedStudents.value.length} 名学生的心理状态为 ${status}`);
// 刷新学生列表以更新状态
await getStudents();
await getEvaluationDetails();
};
const applyBatchMentalStatusToAll = async () => {
const status = batchMentalStatus.value;
const detailsToUpdate = studentList.value.map(student => {
return {
id: student.detailId,
evaluationId: form.value.id,
studentId: student.studentId,
studentNo: student.studentNo,
studentName: student.studentName,
gender: student.gender,
birthDate: student.birthDate,
phone: student.phone,
mentalStatus: status,
score: status === '3' ? 70 : undefined, // 默认分数
remark: student.remark
} as XljkEvaluationDetailForm;
});
await batchUpdateMentalStatus(detailsToUpdate);
ElMessage.success(`已批量设置 ${studentList.value.length} 名学生的心理状态为 ${status}`);
// 刷新学生列表以更新状态
await getStudents();
await getEvaluationDetails();
};
const resetAllMentalStatus = async () => {
try {
await ElMessageBox.confirm('确认要将所有学生的心理状态重置为"健康"吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
const detailsToUpdate = studentList.value.map(student => {
return {
id: student.detailId,
evaluationId: form.value.id,
studentId: student.studentId,
studentNo: student.studentNo,
studentName: student.studentName,
gender: student.gender,
birthDate: student.birthDate,
phone: student.phone,
mentalStatus: '1', // 重置为健康
score: undefined,
remark: student.remark
} as XljkEvaluationDetailForm;
});
await batchUpdateMentalStatus(detailsToUpdate);
ElMessage.success('已重置所有学生的心理状态');
// 刷新学生列表以更新状态
await getStudents();
await getEvaluationDetails();
} catch (error) {
// 用户取消操作
}
};
/** 提交表单 */
const submitForm = () => {
formRef.value?.validate(async (valid: boolean) => {
@@ -317,8 +433,8 @@ const submitForm = () => {
// 批量更新学生心理状态
await batchUpdateMentalStatus(detailsToUpdate);
proxy?.$modal.msgSuccess('修改成功');
router.push('/xljk/evaluation');
ElMessage.success('修改成功');
router.replace('/xljk/evaluation');
} catch (error) {
console.error('修改测评失败', error);
} finally {
@@ -330,7 +446,7 @@ const submitForm = () => {
/** 取消按钮 */
const cancel = () => {
router.push('/xljk/evaluation');
router.replace('/xljk/evaluation');
};
onMounted(() => {
@@ -370,4 +486,22 @@ onMounted(() => {
color: #606266;
font-size: 14px;
}
.batch-actions {
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 10px;
}
.batch-label {
font-size: 14px;
color: #606266;
}
.batch-hint {
font-size: 14px;
color: #909399;
margin-left: 10px;
}
</style>
+4 -4
View File
@@ -109,7 +109,7 @@
</template>
<script setup name="XljkEvaluationFill" lang="ts">
import { getEvaluation, listEvaluationDetail, batchUpdateEvaluationDetail } from '@/api/xljk/evaluation';
import { getEvaluation, listEvaluationDetail, batchUpdateMentalStatus } from '@/api/xljk/evaluation';
import { XljkEvaluationVO, XljkEvaluationDetailVO, XljkEvaluationDetailForm } from '@/api/xljk/evaluation/types';
import { useRoute, useRouter } from 'vue-router';
import { throttle } from 'lodash-es';
@@ -143,7 +143,7 @@ const getEvaluationInfo = async () => {
if (evaluationInfo.value.status !== '1') {
proxy?.$modal.msgError('只能填写"已发布"状态的测评');
setTimeout(() => {
router.push('/xljk/evaluation');
router.replace('/xljk/evaluation');
}, 1500);
}
} catch (error) {
@@ -176,7 +176,7 @@ const filledCount = computed(() => {
/** 返回列表页 */
const goBack = () => {
router.push('/xljk/evaluation');
router.replace('/xljk/evaluation');
};
/** 处理心理状态变更 */
@@ -248,7 +248,7 @@ const saveEvaluation = async () => {
// 提交数据
try {
saveLoading.value = true;
await batchUpdateEvaluationDetail(updateData);
await batchUpdateMentalStatus(updateData);
proxy?.$modal.msgSuccess('保存成功');
} catch (error) {
console.error('保存失败', error);
+16 -53
View File
@@ -169,41 +169,15 @@
></el-button>
</el-tooltip>
<!-- 草稿状态可发布 -->
<el-tooltip content="发布" placement="top" v-if="scope.row.status === '0'">
<!-- 草稿状态可提交 -->
<el-tooltip content="提交" placement="top" v-if="scope.row.status === '0'">
<el-button
link
type="success"
icon="Check"
size="default"
style="font-size: 16px; margin-right: 8px"
@click="handlePublish(scope.row)"
v-hasPermi="['xljk:evaluation:edit']"
></el-button>
</el-tooltip>
<!-- 已发布状态可填写 -->
<el-tooltip content="填写" placement="top" v-if="scope.row.status === '1'">
<el-button
link
type="warning"
icon="Edit"
size="default"
style="font-size: 16px; margin-right: 8px"
@click="handleEdit(scope.row)"
v-hasPermi="['xljk:evaluation:edit']"
></el-button>
</el-tooltip>
<!-- 已发布状态可完成 -->
<el-tooltip content="完成" placement="top" v-if="scope.row.status === '1'">
<el-button
link
type="success"
icon="CircleCheck"
size="default"
style="font-size: 16px"
@click="handleComplete(scope.row)"
@click="handleSubmit(scope.row)"
v-hasPermi="['xljk:evaluation:edit']"
></el-button>
</el-tooltip>
@@ -219,7 +193,7 @@
</template>
<script setup lang="ts">
import { listEvaluation, getEvaluation, delEvaluation, addEvaluation, updateEvaluation, publishEvaluation, completeEvaluation, getCollegeOptions, getMajorOptions, getClassOptions, getSemesterOptions } from '@/api/xljk/evaluation';
import { listEvaluation, getEvaluation, delEvaluation, addEvaluation, updateEvaluation, completeEvaluation, getCollegeOptions, getMajorOptions, getClassOptions, getSemesterOptions } from '@/api/xljk/evaluation';
import { XljkEvaluationVO, XljkEvaluationForm, XljkEvaluationQuery, CollegeOption, MajorOption, ClassOption, SemesterOption } from '@/api/xljk/evaluation/types';
// 基本变量
@@ -376,10 +350,7 @@ const handleUpdate = (row?: XljkEvaluationVO) => {
proxy?.$router.push({ path: `/xljk/evaluation/edit/${id}` });
};
/** 填写评测 */
const handleEdit = (row: XljkEvaluationVO) => {
proxy?.$router.push({ path: `/xljk/evaluation/fill/${row.id}` });
};
/** 删除按钮操作 */
const handleDelete = async (row?: XljkEvaluationVO) => {
@@ -412,26 +383,13 @@ const handleDelete = async (row?: XljkEvaluationVO) => {
}
};
/** 发布按钮操作 */
const handlePublish = async (row: XljkEvaluationVO) => {
await proxy?.$modal.confirm(`是否确认发布测评"${row.evaluationName}"?发布后将无法修改测评基本信息。`);
try {
loading.value = true;
await publishEvaluation(row.id);
proxy?.$modal.msgSuccess('发布成功');
await getList();
} finally {
loading.value = false;
}
};
/** 完成按钮操作 */
const handleComplete = async (row: XljkEvaluationVO) => {
await proxy?.$modal.confirm(`是否确认完成测评"${row.evaluationName}"?完成后将无法再修改测评结果。`);
/** 提交按钮操作 */
const handleSubmit = async (row: XljkEvaluationVO) => {
await proxy?.$modal.confirm(`是否确认提交测评"${row.evaluationName}"?提交后将无法再修改测评结果。`);
try {
loading.value = true;
await completeEvaluation(row.id);
proxy?.$modal.msgSuccess('操作成功');
proxy?.$modal.msgSuccess('提交成功');
await getList();
} finally {
loading.value = false;
@@ -449,11 +407,16 @@ const handleExport = () => {
);
};
// 初始化
onMounted(() => {
getList();
getDepartments();
getMajors();
getSemesters();
getList();
});
// 监听路由变化,确保从其他页面返回时重新加载数据
onActivated(() => {
getList();
});
</script>