diff --git a/backend/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java b/backend/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java index 8c690e34..ebbd0d02 100644 --- a/backend/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java +++ b/backend/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java @@ -13,7 +13,11 @@ import org.dromara.common.core.utils.sql.SqlUtil; import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * 分页查询实体类 @@ -46,6 +50,16 @@ public class PageQuery implements Serializable { */ private String isAsc; + /** + * 默认排序列 + */ + private String defaultOrderByColumn = "create_time"; + + /** + * 默认排序方向 + */ + private String defaultIsAsc = "desc"; + /** * 当前记录起始索引 默认值 */ @@ -66,10 +80,14 @@ public class PageQuery implements Serializable { pageNum = DEFAULT_PAGE_NUM; } Page page = new Page<>(pageNum, pageSize); - List orderItems = buildOrderItem(); + List orderItems = buildOrderItem(orderByColumn, isAsc); if (CollUtil.isNotEmpty(orderItems)) { page.addOrder(orderItems); } + List defaultOrderItems = buildDefaultOrderItem(orderItems); + if (CollUtil.isNotEmpty(defaultOrderItems)) { + page.addOrder(defaultOrderItems); + } return page; } @@ -79,18 +97,21 @@ public class PageQuery implements Serializable { * 支持的用法如下: * {isAsc:"asc",orderByColumn:"id"} order by id asc * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc - * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc - * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc + * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time + * desc + * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time + * desc */ - private List buildOrderItem() { + private List buildOrderItem(String orderByColumn, String isAsc) { if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) { - return null; + return Collections.emptyList(); } String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); orderBy = StringUtils.toUnderScoreCase(orderBy); // 兼容前端排序类型 - isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"}); + isAsc = StringUtils.replaceEach(isAsc, new String[] { "ascending", "descending" }, + new String[] { "asc", "desc" }); String[] orderByArr = orderBy.split(StringUtils.SEPARATOR); String[] isAscArr = isAsc.split(StringUtils.SEPARATOR); @@ -114,6 +135,29 @@ public class PageQuery implements Serializable { return list; } + private List buildDefaultOrderItem(List existingOrders) { + if (StringUtils.isBlank(defaultOrderByColumn) || StringUtils.isBlank(defaultIsAsc)) { + return Collections.emptyList(); + } + List defaultItems = buildOrderItem(defaultOrderByColumn, defaultIsAsc); + if (CollUtil.isEmpty(defaultItems)) { + return defaultItems; + } + Set existing = CollUtil.isNotEmpty(existingOrders) + ? existingOrders.stream() + .map(item -> StringUtils.blankToDefault(item.getColumn(), StringUtils.EMPTY).trim() + .toLowerCase()) + .collect(Collectors.toCollection(HashSet::new)) + : Collections.emptySet(); + return defaultItems.stream() + .filter(item -> { + String column = StringUtils.blankToDefault(item.getColumn(), StringUtils.EMPTY).trim() + .toLowerCase(); + return !existing.contains(column); + }) + .collect(Collectors.toList()); + } + @JsonIgnore public Integer getFirstNum() { return (pageNum - 1) * pageSize; @@ -130,4 +174,20 @@ public class PageQuery implements Serializable { this.pageNum = pageNum; } + public PageQuery withDefaultOrder(String column, String asc) { + this.defaultOrderByColumn = column; + this.defaultIsAsc = asc; + return this; + } + + public PageQuery withDefaultOrder(String column) { + return withDefaultOrder(column, "desc"); + } + + public PageQuery disableDefaultOrder() { + this.defaultOrderByColumn = null; + this.defaultIsAsc = null; + return this; + } + } diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwApprovalRecordMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwApprovalRecordMapper.xml index 43b4f9b6..7f254c75 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwApprovalRecordMapper.xml +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwApprovalRecordMapper.xml @@ -275,7 +275,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND u.status = '0' AND u.del_flag = '0' AND r.status = '0' - ORDER BY u.user_name + ORDER BY u.user_name ASC, u.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwProjectAuditorMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwProjectAuditorMapper.xml index fb8efb03..410732be 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwProjectAuditorMapper.xml +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwProjectAuditorMapper.xml @@ -129,7 +129,7 @@ #{userId} - order by u.dept_id, u.user_name + order by u.user_name asc, u.dept_id diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml index 61641ed6..1302c5ce 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml @@ -32,7 +32,7 @@ FROM cw_project_evaluation_indicator WHERE evaluation_id = #{evaluationId} AND deleted = 0 - ORDER BY indicator_category, sort_order + ORDER BY indicator_category, sort_order, create_time DESC @@ -42,7 +42,7 @@ WHERE evaluation_id = #{evaluationId} AND indicator_category = #{indicatorCategory} AND deleted = 0 - ORDER BY sort_order + ORDER BY sort_order, create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml index 0eb93018..66964ed2 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml @@ -43,7 +43,7 @@ FROM cw_project_monthly_monitoring WHERE evaluation_id = #{evaluationId} AND deleted = 0 - ORDER BY monitoring_year, monitoring_month + ORDER BY monitoring_year, monitoring_month, create_time DESC @@ -53,7 +53,7 @@ WHERE evaluation_id = #{evaluationId} AND monitoring_year = #{monitoringYear} AND deleted = 0 - ORDER BY monitoring_month + ORDER BY monitoring_month, create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml index 7ccb808a..6e255ac5 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml @@ -147,7 +147,7 @@ FROM cw_project_performance_self_evaluation WHERE evaluation_status = 'submitted' AND deleted = 0 - ORDER BY submit_time ASC + ORDER BY submit_time ASC, create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatQuestionServiceImpl.java b/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatQuestionServiceImpl.java index 92d211fb..d8963bc4 100644 --- a/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatQuestionServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatQuestionServiceImpl.java @@ -75,6 +75,7 @@ public class HqSatQuestionServiceImpl implements IHqSatQuestionService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); // 处理排序参数 + boolean sortedByCreateTime = false; if (params != null && params.containsKey("orderByColumn") && params.containsKey("isAsc")) { String orderByColumn = (String) params.get("orderByColumn"); String isAsc = (String) params.get("isAsc"); @@ -85,6 +86,7 @@ public class HqSatQuestionServiceImpl implements IHqSatQuestionService { } else { lqw.orderByAsc(HqSatQuestion::getCreateTime); } + sortedByCreateTime = true; } else if ("updateTime".equals(orderByColumn)) { if ("desc".equals(isAsc)) { lqw.orderByDesc(HqSatQuestion::getUpdateTime); @@ -100,10 +102,15 @@ public class HqSatQuestionServiceImpl implements IHqSatQuestionService { } else { // 默认按创建时间倒序 lqw.orderByDesc(HqSatQuestion::getCreateTime); + sortedByCreateTime = true; } } else { // 默认按创建时间倒序 lqw.orderByDesc(HqSatQuestion::getCreateTime); + sortedByCreateTime = true; + } + if (!sortedByCreateTime) { + lqw.orderByDesc(HqSatQuestion::getCreateTime); } // 添加ID查询条件 diff --git a/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatSurveyServiceImpl.java b/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatSurveyServiceImpl.java index e1c020e5..92e86169 100644 --- a/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatSurveyServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatSurveyServiceImpl.java @@ -1097,7 +1097,7 @@ public class HqSatSurveyServiceImpl implements IHqSatSurveyService { } sql.append("GROUP BY u.user_id, rec.id "); - sql.append("ORDER BY CASE WHEN rec.submit_time IS NOT NULL THEN 0 ELSE 1 END, rec.submit_time DESC, u.user_id "); + sql.append("ORDER BY CASE WHEN rec.submit_time IS NOT NULL THEN 0 ELSE 1 END, rec.submit_time DESC, u.user_name ASC, u.user_id "); // 查询总数 StringBuilder countSql = new StringBuilder(); diff --git a/backend/ruoyi-modules/ruoyi-hq/src/main/resources/mapper/HqPmRepairOrderMapper.xml b/backend/ruoyi-modules/ruoyi-hq/src/main/resources/mapper/HqPmRepairOrderMapper.xml index 7952986e..32cc54a9 100644 --- a/backend/ruoyi-modules/ruoyi-hq/src/main/resources/mapper/HqPmRepairOrderMapper.xml +++ b/backend/ruoyi-modules/ruoyi-hq/src/main/resources/mapper/HqPmRepairOrderMapper.xml @@ -18,7 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" WHERE r.role_key = 'maintenance_worker' AND u.status = '0' AND u.del_flag = '0' - ORDER BY u.user_id + ORDER BY u.user_name ASC, u.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/service/impl/JcbtScholarshipApplicationServiceImpl.java b/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/service/impl/JcbtScholarshipApplicationServiceImpl.java index fbf380e7..3fb9411d 100644 --- a/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/service/impl/JcbtScholarshipApplicationServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/service/impl/JcbtScholarshipApplicationServiceImpl.java @@ -527,7 +527,7 @@ public class JcbtScholarshipApplicationServiceImpl implements IJcbtScholarshipAp WHERE cm.class_teacher_id = ? AND cm.deleted = 0 AND cm.class_status = '1' - ORDER BY cm.grade DESC, cm.class_name ASC + ORDER BY cm.grade DESC, cm.class_name ASC, cm.create_time DESC """; // 执行查询 @@ -713,7 +713,7 @@ public class JcbtScholarshipApplicationServiceImpl implements IJcbtScholarshipAp AND sm.deleted = 0 AND sm.student_status = '1' AND (cm.deleted IS NULL OR cm.deleted = 0) - ORDER BY sm.student_no ASC + ORDER BY sm.student_no DESC, sm.create_time DESC """; List> studentList = jdbcTemplate.queryForList(sql, classId); diff --git a/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtPovertyApplicationMapper.xml b/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtPovertyApplicationMapper.xml index 65d576d3..4ec1a65f 100644 --- a/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtPovertyApplicationMapper.xml +++ b/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtPovertyApplicationMapper.xml @@ -246,7 +246,7 @@ and s.deleted = 0 and s.student_status = '1' and (c.deleted is null or c.deleted = 0) - order by s.student_no asc + order by s.student_no desc diff --git a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsApplicationMapper.xml b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsApplicationMapper.xml index 5fdbe3a0..1fdf4fdc 100644 --- a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsApplicationMapper.xml +++ b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsApplicationMapper.xml @@ -47,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.contact_phone like concat('%', #{contactPhone}, '%') and a.contact_email like concat('%', #{contactEmail}, '%') + order by a.create_time desc where a.job_id = #{jobId} and a.applicant_id = #{applicantId} + order by a.create_time desc diff --git a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationAttachmentMapper.xml b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationAttachmentMapper.xml index 5ecdc60b..d8e9508b 100644 --- a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationAttachmentMapper.xml +++ b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationAttachmentMapper.xml @@ -37,7 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where application_id = #{applicationId} and deleted = '0' - order by upload_time desc + order by upload_time desc, create_time desc diff --git a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationMapper.xml b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationMapper.xml index 7770ed92..9563709c 100644 --- a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationMapper.xml +++ b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasApplicationMapper.xml @@ -582,7 +582,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND r.status = '0' AND u.deleted = '0' AND u.status = '0' - ORDER BY u.user_id + ORDER BY u.user_name ASC, u.create_time DESC @@ -597,7 +597,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND m.status = '0' AND r.del_flag = '0' AND r.status = '0' - ORDER BY m.perms + ORDER BY m.perms, m.create_time DESC @@ -615,7 +615,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND u.dept_id = #{deptId} - ORDER BY a.apply_time DESC + ORDER BY a.apply_time DESC, a.create_time DESC \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsTrainingApprovalMapper.xml b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsTrainingApprovalMapper.xml index 561335ed..1a6ecfab 100644 --- a/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsTrainingApprovalMapper.xml +++ b/backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsTrainingApprovalMapper.xml @@ -197,7 +197,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND app.user_id = #{applicantId} - ORDER BY a.approval_time DESC + ORDER BY a.approval_time DESC, a.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/StglMyMapper.xml b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/StglMyMapper.xml index 9715a314..14a403ad 100644 --- a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/StglMyMapper.xml +++ b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/StglMyMapper.xml @@ -38,7 +38,7 @@ AND m.deleted = 0 AND c.deleted = 0 - ORDER BY m.join_time DESC + ORDER BY m.join_time DESC, c.create_time DESC @@ -77,7 +77,7 @@ AND vt.tenant_id = #{tenantId} AND m.tenant_id = #{tenantId} - ORDER BY m.join_time DESC + ORDER BY m.join_time DESC, vt.create_time DESC @@ -252,7 +252,7 @@ - ORDER BY COALESCE(direct_ar.registration_time, team_ar.registration_time) DESC + ORDER BY COALESCE(direct_ar.registration_time, team_ar.registration_time) DESC, a.create_time DESC @@ -351,7 +351,7 @@ AND target_name LIKE CONCAT('%', #{name}, '%') - ORDER BY registration_time DESC + ORDER BY registration_time DESC, create_time DESC @@ -478,7 +478,7 @@ AND target_name LIKE CONCAT('%', #{name}, '%') - ORDER BY registration_time DESC + ORDER BY registration_time DESC, create_time DESC \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglActivityMapper.xml b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglActivityMapper.xml index 03af3451..58b5eb1f 100644 --- a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglActivityMapper.xml +++ b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglActivityMapper.xml @@ -388,7 +388,7 @@ 1 AS relatedType FROM stgl_club WHERE deleted = 0 AND status = 0 - ORDER BY club_name + ORDER BY club_name, create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglAuditorMapper.xml b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglAuditorMapper.xml index e5cb2b93..c3057eb2 100644 --- a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglAuditorMapper.xml +++ b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglAuditorMapper.xml @@ -126,7 +126,7 @@ #{userId} - order by u.dept_id, u.user_name + order by u.user_name asc, u.dept_id \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglClassMapper.xml b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglClassMapper.xml index 4e353556..2ad5d4a0 100644 --- a/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglClassMapper.xml +++ b/backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglClassMapper.xml @@ -40,7 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND tcr.deleted = 0 AND tcr.teacher_type = 'class_teacher' AND (tcr.end_date IS NULL OR tcr.end_date > NOW()) - ORDER BY c.grade DESC, c.class_name ASC + ORDER BY c.grade DESC, c.class_name ASC, c.create_time DESC @@ -270,7 +270,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND s.student_no LIKE CONCAT('%', #{studentNo}, '%') - ORDER BY s.student_no ASC + ORDER BY s.student_no DESC, s.create_time DESC LIMIT #{pageSize} OFFSET #{offset} @@ -442,7 +442,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) ) AND a.tenant_id = '000000' - ORDER BY a.start_time DESC + ORDER BY a.start_time DESC, a.create_time DESC \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTeacherMapper.java b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTeacherMapper.java index c11d375c..1594469a 100644 --- a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTeacherMapper.java +++ b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTeacherMapper.java @@ -46,7 +46,7 @@ public interface SysTeacherMapper extends BaseMapperPlus WHERE u.del_flag = '0' AND u.account_type = '1' ${ew.customSqlSegment} - ORDER BY u.create_time DESC + ORDER BY u.user_name ASC, u.create_time DESC """) Page selectPageTeacherList(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper wrapper); @@ -74,7 +74,7 @@ public interface SysTeacherMapper extends BaseMapperPlus WHERE u.del_flag = '0' AND u.account_type = '1' ${ew.customSqlSegment} - ORDER BY u.create_time DESC + ORDER BY u.user_name ASC, u.create_time DESC """) List selectTeacherList(@Param(Constants.WRAPPER) Wrapper wrapper); @@ -105,14 +105,14 @@ public interface SysTeacherMapper extends BaseMapperPlus OR u.user_name LIKE CONCAT('%', #{name}, '%') OR u.phonenumber LIKE CONCAT('%', #{name}, '%')) AND u.status = '0' - ORDER BY u.create_time DESC + ORDER BY u.user_name ASC, u.create_time DESC LIMIT #{limit} """) List searchTeachersByName(@Param("name") String name, @Param("limit") Integer limit); /** * 根据部门ID获取教师列表(带数据权限控制) - * + * * 说明:添加数据权限注解后,只会返回用户有权限访问的部门的教师 * * @param deptId 部门ID @@ -139,13 +139,13 @@ public interface SysTeacherMapper extends BaseMapperPlus AND u.account_type = '1' AND u.dept_id = #{deptId} AND u.status = '0' - ORDER BY u.create_time DESC + ORDER BY u.user_name ASC, u.create_time DESC """) List selectTeachersByDeptId(@Param("deptId") Long deptId); /** * 获取部门树形结构(只包含有教师且用户有权限访问的部门) - * + * * 说明:添加数据权限注解后,只会返回用户有权限访问的部门 * 这样可以避免在同行人选择器中显示用户无权访问的部门 * @@ -167,7 +167,7 @@ public interface SysTeacherMapper extends BaseMapperPlus AND u.del_flag = '0' AND u.account_type = '1' AND u.status = '0' - ORDER BY d.order_num + ORDER BY d.order_num, d.create_time DESC """) List selectDeptTreeWithTeachers(); @@ -191,8 +191,8 @@ public interface SysTeacherMapper extends BaseMapperPlus #{deptId} - ORDER BY order_num + ORDER BY order_num, create_time DESC """) List selectDeptsByIds(@Param("deptIds") List deptIds); -} \ No newline at end of file +} diff --git a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java index aa4024c3..8e5e95be 100644 --- a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java +++ b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java @@ -121,7 +121,8 @@ public interface SysUserMapper extends BaseMapperPlus { AND sm.perms = #{permission} AND (#{tenantId} IS NULL OR #{tenantId} = '' OR su.tenant_id = #{tenantId}) ORDER BY - su.user_id + su.user_name ASC, + su.create_time DESC """) List selectUserListByPermission(@Param("permission") String permission, @Param("tenantId") String tenantId); diff --git a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java index 0a2e485f..9b107ed0 100644 --- a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java @@ -57,6 +57,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { @Override public TableDataInfo selectPageRoleList(SysRoleBo role, PageQuery pageQuery) { + pageQuery.withDefaultOrder("r.create_time"); Page page = baseMapper.selectPageRoleList(pageQuery.build(), this.buildQueryWrapper(role)); return TableDataInfo.build(page); } diff --git a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index f03931a6..487d1fbc 100644 --- a/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -64,12 +64,14 @@ public class SysUserServiceImpl implements ISysUserService, UserService { @Override public TableDataInfo selectPageUserList(SysUserBo user, PageQuery pageQuery) { + pageQuery.withDefaultOrder("u.user_name"); Page page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user)); return TableDataInfo.build(page); } @Override public TableDataInfo selectPageUserListByOr(SysUserBo user, PageQuery pageQuery) { + pageQuery.withDefaultOrder("u.user_name"); Page page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapperByOr(user)); return TableDataInfo.build(page); } @@ -169,7 +171,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { } // 排序 - wrapper.orderByAsc("u.user_id"); + wrapper.orderByAsc("u.user_name"); return wrapper; } @@ -203,7 +205,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { List ids = StreamUtils.toList(deptList, SysDept::getDeptId); ids.add(user.getDeptId()); w.in("u.dept_id", ids); - }).orderByAsc("u.user_id"); + }).orderByAsc("u.user_name"); if (StringUtils.isNotBlank(user.getExcludeUserIds())) { wrapper.notIn("u.user_id", StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong)); } @@ -224,7 +226,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) - .orderByAsc("u.user_id"); + .orderByAsc("u.user_name"); + pageQuery.withDefaultOrder("u.user_name"); Page page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper); return TableDataInfo.build(page); } @@ -244,7 +247,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) - .orderByAsc("u.user_id"); + .orderByAsc("u.user_name"); + pageQuery.withDefaultOrder("u.user_name"); Page page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper); return TableDataInfo.build(page); } @@ -300,7 +304,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getPhonenumber) .eq(SysUser::getStatus, SystemConstants.NORMAL) .eq(ObjectUtil.isNotNull(deptId), SysUser::getDeptId, deptId) - .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds)); + .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds) + .orderByAsc(SysUser::getUserName)); } /** @@ -719,7 +724,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { public List selectUserListByDept(Long deptId) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(SysUser::getDeptId, deptId); - lqw.orderByAsc(SysUser::getUserId); + lqw.orderByAsc(SysUser::getUserName); return baseMapper.selectVoList(lqw); } diff --git a/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml index 9057a0e2..5309a7d6 100644 --- a/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -16,6 +16,14 @@ * from sys_dept ${ew.getCustomSqlSegment} + + + , create_time desc + + + order by create_time desc + + diff --git a/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index 9dd3f2e1..6f0d6132 100644 --- a/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/backend/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -14,6 +14,14 @@ left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_role r on rm.role_id = r.role_id ${ew.getCustomSqlSegment} + + + , m.create_time desc + + + order by m.create_time desc + + ${ew.getCustomSqlSegment} + + + , r.create_time desc + + + order by r.create_time desc + + diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedMapper.java index 382c3b6b..f85c59ca 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedMapper.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedMapper.java @@ -69,7 +69,7 @@ public interface XgDormBedMapper extends BaseMapperPlus LEFT JOIN xg_student_msg s ON bs.student_id = s.id AND s.deleted = 0 WHERE b.room_id = #{roomId} AND b.deleted = '0' - ORDER BY b.bed_code + ORDER BY s.student_no DESC, b.bed_code, b.create_time DESC """) List selectBedDetailsByRoomId(@Param("roomId") Long roomId); @@ -125,7 +125,7 @@ public interface XgDormBedMapper extends BaseMapperPlus LEFT JOIN xg_student_msg s ON bs.student_id = s.id AND s.deleted = 0 WHERE r.building_id = #{buildingId} AND b.deleted = '0' - ORDER BY r.room_name, b.bed_code + ORDER BY s.student_no DESC, r.room_name, b.bed_code, b.create_time DESC """) List selectBedDetailsByBuildingId(@Param("buildingId") Long buildingId); @@ -183,7 +183,7 @@ public interface XgDormBedMapper extends BaseMapperPlus WHERE b.room_id = #{roomId} AND bs.college_id = #{collegeId} AND b.deleted = '0' - ORDER BY b.bed_code + ORDER BY s.student_no DESC, b.bed_code, b.create_time DESC """) List selectBedDetailsByRoomIdAndCollegeId(@Param("roomId") Long roomId, @Param("collegeId") Long collegeId); @@ -242,7 +242,7 @@ public interface XgDormBedMapper extends BaseMapperPlus WHERE b.room_id = #{roomId} AND bs.class_id = #{classId} AND b.deleted = '0' - ORDER BY b.bed_code + ORDER BY s.student_no DESC, b.bed_code, b.create_time DESC """) List selectBedDetailsByRoomIdAndClassId(@Param("roomId") Long roomId, @Param("classId") Long classId); diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedStudentMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedStudentMapper.java index cc7d3b58..d938c4fd 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedStudentMapper.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedStudentMapper.java @@ -76,11 +76,13 @@ public interface XgDormBedStudentMapper extends BaseMapperPlus> selectClassOccupiedBedDetails(@Param("classId") Long classId); @@ -137,7 +139,8 @@ public interface XgDormBedStudentMapper extends BaseMapperPlus> selectClassUnoccupiedBedDetails(@Param("classId") Long classId); @@ -184,7 +187,7 @@ public interface XgDormBedStudentMapper extends BaseMapperPlus> selectRoomStudents(@Param("roomId") Long roomId); diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMapper.java index 966c286a..96227475 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMapper.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMapper.java @@ -20,17 +20,40 @@ public interface XgStudentMapper extends BaseMapperPlus> selectTreeNodes(); } \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java index 397d2ef9..51f00ad9 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java @@ -1473,7 +1473,7 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService { .eq(XgStudentMsg::getDeleted, 0L) // 未删除 .eq(XgStudentMsg::getIsBoarder, "1") // 需要住校 .eq(XgStudentMsg::getClassId, targetClassId) // 指定班级 - .orderByAsc(XgStudentMsg::getStudentNo); // 按学号排序 + .orderByDesc(XgStudentMsg::getStudentNo); // 按学号倒序排序 List boardingStudents = xgStudentMsgMapper.selectList(studentQuery); diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java index d76255c5..26527872 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java @@ -99,7 +99,7 @@ public class XgDormManagerServiceImpl implements IXgDormManagerService { params.add("%" + name + "%"); } - sql.append("ORDER BY u.nick_name"); + sql.append("ORDER BY u.user_name ASC, u.nick_name"); try { if (params.isEmpty()) { diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java index c9bbbce2..0d89abc9 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java @@ -203,7 +203,7 @@ public class XgStudentManagerServiceImpl implements IXgStudentManagerService { sql.append(" AND s.phonenumber LIKE ?"); params.add("%" + phone + "%"); } - sql.append(" ORDER BY c.class_status ASC, c.class_name ASC"); + sql.append(" ORDER BY c.class_status ASC, c.class_name ASC, c.create_time DESC"); return jdbcTemplate.query(sql.toString(), params.toArray(), (rs, rowNum) -> { ClassTeacherInfoVo vo = new ClassTeacherInfoVo(); vo.setName(rs.getString("name")); diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java index bed0bb0a..db4b8e32 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java @@ -204,7 +204,7 @@ public class XgStudentManagerSourceServiceImpl implements IXgStudentManagerSourc if (isSchoolManager) { // 全校学生管理员:查询id=101下所有部门数据,所有节点都可点击 String sql = "SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept " + - "WHERE (dept_id = 101 OR ancestors LIKE '%,101' OR ancestors LIKE '%,101,%') AND status = '0' AND del_flag = '0' ORDER BY order_num"; + "WHERE (dept_id = 101 OR ancestors LIKE '%,101' OR ancestors LIKE '%,101,%') AND status = '0' AND del_flag = '0' ORDER BY order_num, create_time DESC"; List> deptMaps = jdbcTemplate.queryForList(sql); // 构建部门树 @@ -310,7 +310,7 @@ public class XgStudentManagerSourceServiceImpl implements IXgStudentManagerSourc // 查询所有部门信息 String inSql = finalDeptIds.stream().map(String::valueOf).collect(Collectors.joining(",")); String sql = "SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept " + - "WHERE dept_id IN (" + inSql + ") AND status = '0' AND del_flag = '0' ORDER BY order_num"; + "WHERE dept_id IN (" + inSql + ") AND status = '0' AND del_flag = '0' ORDER BY order_num, create_time DESC"; List> deptMaps = jdbcTemplate.queryForList(sql); // 构建部门树 diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java index 03671ae7..9ecee881 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java @@ -366,7 +366,7 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService { private LambdaQueryWrapper buildQueryWrapper(XgStudentMsgBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(XgStudentMsg::getId); + lqw.orderByDesc(XgStudentMsg::getStudentNo).orderByDesc(XgStudentMsg::getId); lqw.eq(bo.getDeleted() != null, XgStudentMsg::getDeleted, bo.getDeleted()); lqw.eq(StringUtils.isNotBlank(bo.getStudentNo()), XgStudentMsg::getStudentNo, bo.getStudentNo()); lqw.eq(StringUtils.isNotBlank(bo.getIdCard()), XgStudentMsg::getIdCard, bo.getIdCard()); diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentServiceImpl.java index 2df9c8b8..381b7546 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentServiceImpl.java @@ -67,6 +67,7 @@ public class XgStudentServiceImpl implements IXgStudentService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(name), XgStudentMsg::getName, name); lqw.eq(XgStudentMsg::getStudentStatus, "1"); // 只查询在籍学生 + lqw.orderByDesc(XgStudentMsg::getStudentNo); lqw.last("LIMIT " + (limit != null ? limit : 10)); return baseMapper.selectVoList(lqw); } @@ -149,7 +150,7 @@ public class XgStudentServiceImpl implements IXgStudentService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(XgStudentMsg::getClassId, classId); lqw.eq(XgStudentMsg::getStudentStatus, "1"); // 只查询在籍学生 - lqw.orderByAsc(XgStudentMsg::getStudentNo); // 按学号排序 + lqw.orderByDesc(XgStudentMsg::getStudentNo); // 按学号倒序排序 return baseMapper.selectVoList(lqw); } @@ -209,6 +210,7 @@ public class XgStudentServiceImpl implements IXgStudentService { lqw.eq(StringUtils.isNotBlank(bo.getStudentStatus()), XgStudentMsg::getStudentStatus, bo.getStudentStatus()); lqw.eq(bo.getEnrollmentYear() != null, XgStudentMsg::getEnrollmentYear, bo.getEnrollmentYear()); lqw.eq(bo.getEnrollmentDate() != null, XgStudentMsg::getEnrollmentDate, bo.getEnrollmentDate()); + lqw.orderByDesc(XgStudentMsg::getStudentNo).orderByDesc(XgStudentMsg::getId); return lqw; } } \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormHygieneCheck/XgDormHygieneCheckMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormHygieneCheck/XgDormHygieneCheckMapper.xml index 827ed2ae..2b14d67a 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormHygieneCheck/XgDormHygieneCheckMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormHygieneCheck/XgDormHygieneCheckMapper.xml @@ -115,7 +115,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND dhc.check_date <= #{params.endTime} - ORDER BY dhc.check_date DESC, dhc.id ASC, dhss.student_no ASC + ORDER BY dhss.student_no DESC, dhc.check_date DESC, dhc.id ASC, dhc.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormViolation/XgDormViolationMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormViolation/XgDormViolationMapper.xml index e81ccb55..3aad3223 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormViolation/XgDormViolationMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormViolation/XgDormViolationMapper.xml @@ -76,7 +76,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND (s.student_no LIKE CONCAT('%', #{bo.keyword}, '%') OR s.name LIKE CONCAT('%', #{bo.keyword}, '%')) - ORDER BY s.student_no ASC + ORDER BY s.student_no DESC, s.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/holidayStay/XgHolidayStayMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/holidayStay/XgHolidayStayMapper.xml index 4cf092d0..1f03b3e0 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/holidayStay/XgHolidayStayMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/holidayStay/XgHolidayStayMapper.xml @@ -76,7 +76,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND (s.student_no LIKE CONCAT('%', #{bo.keyword}, '%') OR s.name LIKE CONCAT('%', #{bo.keyword}, '%')) - ORDER BY s.student_no ASC + ORDER BY s.student_no DESC, s.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml index 64ddfac8..6db6b30b 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml @@ -66,7 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - ORDER BY create_time DESC + ORDER BY student_no DESC, create_time DESC @@ -100,7 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - ORDER BY create_time DESC + ORDER BY student_no DESC, create_time DESC @@ -134,7 +134,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND name LIKE CONCAT('%', #{name}, '%') - ORDER BY create_time DESC + ORDER BY student_no DESC, create_time DESC @@ -205,7 +205,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND sm.major_id IS NOT NULL AND sm.class_id IS NOT NULL GROUP BY c.grade, sm.college_id, sm.college_name, sm.major_id, sm.major_name, sm.class_id, sm.class_name - ORDER BY c.grade DESC, sm.college_name, sm.major_name, sm.class_name + ORDER BY c.grade DESC, sm.college_name, sm.major_name, sm.class_name, sm.create_time DESC @@ -255,7 +255,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND sm.major_id IS NOT NULL AND sm.class_id IS NOT NULL GROUP BY c.grade, sm.college_id, sm.college_name, sm.major_id, sm.major_name, sm.class_id, sm.class_name - ORDER BY c.grade DESC, sm.college_name, sm.major_name, sm.class_name + ORDER BY c.grade DESC, sm.college_name, sm.major_name, sm.class_name, sm.create_time DESC @@ -301,7 +301,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND (d.parent_id = #{secondaryCollegeId} OR d.dept_id = #{secondaryCollegeId} OR FIND_IN_SET(#{secondaryCollegeId}, d.ancestors)) AND sm.college_id IS NOT NULL GROUP BY sm.college_id, sm.college_name - ORDER BY sm.college_name + ORDER BY sm.college_name, sm.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsgBatch/XgStudentMsgBatchMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsgBatch/XgStudentMsgBatchMapper.xml index a06b5718..7d3b154a 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsgBatch/XgStudentMsgBatchMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsgBatch/XgStudentMsgBatchMapper.xml @@ -24,14 +24,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" inner join sys_user s2 on xsmb.update_by = s2.user_id WHERE batch_id = #{batchId} and xsmb.id = #{userId} - ORDER BY xsmb.create_time asc + ORDER BY xsmb.create_time DESC @@ -183,7 +183,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND xsmb.info_status = #{infoStatus} - ORDER BY xsmb.create_time DESC + ORDER BY xsmb.student_no DESC, xsmb.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgStudentStatisticsMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgStudentStatisticsMapper.xml index 3585dcf8..9aea303d 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgStudentStatisticsMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgStudentStatisticsMapper.xml @@ -58,7 +58,7 @@ GROUP BY dr.college_id ) teaching_violation_stats ON d.dept_id = teaching_violation_stats.college_id WHERE d.parent_id = 101 AND d.del_flag = '0' - ORDER BY d.order_num ASC, d.dept_name ASC + ORDER BY d.order_num ASC, d.dept_name ASC, d.create_time DESC @@ -118,7 +118,7 @@ GROUP BY dr.college_id ) teaching_violation_stats ON d.dept_id = teaching_violation_stats.college_id WHERE d.parent_id = 101 AND d.del_flag = '0' - ORDER BY d.order_num ASC, d.dept_name ASC + ORDER BY d.order_num ASC, d.dept_name ASC, d.create_time DESC @@ -178,7 +178,7 @@ GROUP BY dr.major_id ) teaching_violation_stats ON d.dept_id = teaching_violation_stats.major_id WHERE d.parent_id = #{bo.collegeId} AND d.dept_category LIKE 'zy-%' AND d.del_flag = '0' - ORDER BY d.order_num ASC, d.dept_name ASC + ORDER BY d.order_num ASC, d.dept_name ASC, d.create_time DESC @@ -242,7 +242,7 @@ GROUP BY dr.major_id ) teaching_violation_stats ON d.dept_id = teaching_violation_stats.major_id WHERE d.parent_id = #{bo.collegeId} AND d.dept_category LIKE 'zy-%' AND d.del_flag = '0' - ORDER BY d.order_num ASC, d.dept_name ASC + ORDER BY d.order_num ASC, d.dept_name ASC, d.create_time DESC @@ -303,7 +303,7 @@ ) as teachingViolationDeduction FROM xg_class_msg c WHERE c.college_id = #{bo.collegeId} AND c.major_id = #{bo.majorId} AND c.deleted = 0 - ORDER BY c.class_name ASC + ORDER BY c.class_name ASC, c.create_time DESC @@ -458,7 +458,7 @@ )) as totalDeduction FROM xg_class_msg c WHERE c.college_id = #{bo.collegeId} AND c.major_id = #{bo.majorId} AND c.deleted = 0 - ORDER BY c.class_name ASC + ORDER BY c.class_name ASC, c.create_time DESC @@ -472,7 +472,7 @@ order_num as sort FROM sys_dept WHERE parent_id = 101 AND del_flag = '0' - ORDER BY order_num ASC, dept_name ASC + ORDER BY order_num ASC, dept_name ASC, create_time DESC @@ -486,7 +486,7 @@ WHERE parent_id = #{collegeId} AND dept_category LIKE 'zy-%' AND del_flag = '0' - ORDER BY order_num ASC, dept_name ASC + ORDER BY order_num ASC, dept_name ASC, create_time DESC @@ -498,7 +498,7 @@ 0 as sort FROM xg_class_msg WHERE major_id = #{majorId} AND deleted = 0 - ORDER BY class_name ASC + ORDER BY class_name ASC, create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml index bbd8553a..821baf75 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml @@ -23,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select user_id, user_name, nick_name, phonenumber, account_type from sys_user where status = '0' and del_flag = '0' - order by create_time desc + order by user_name asc, create_time desc @@ -31,7 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select user_id, user_name, nick_name, phonenumber, account_type from sys_user where status = '0' and del_flag = '0' and account_type = #{accountType} - order by create_time desc + order by user_name asc, create_time desc diff --git a/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkConsultationScheduleController.java b/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkConsultationScheduleController.java index 5d3cc5be..367aa0cc 100644 --- a/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkConsultationScheduleController.java +++ b/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/controller/XljkConsultationScheduleController.java @@ -212,7 +212,7 @@ public class XljkConsultationScheduleController { "JOIN sys_role r ON ur.role_id = r.role_id " + "LEFT JOIN xljk_consulter c ON u.user_id = c.user_id AND c.deleted = 0 " + "WHERE r.role_key = 'xljk_consultant' AND u.del_flag = '0' " + - "ORDER BY u.nick_name"; + "ORDER BY u.user_name ASC, u.nick_name, u.create_time DESC"; List> counselorOptions = jdbcTemplate.queryForList(sql); return R.ok(counselorOptions); diff --git a/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationAppointmentServiceImpl.java b/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationAppointmentServiceImpl.java index 30debfdf..e78ace86 100644 --- a/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationAppointmentServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationAppointmentServiceImpl.java @@ -47,16 +47,16 @@ import java.time.Month; public class XljkConsultationAppointmentServiceImpl implements IXljkConsultationAppointmentService { @Autowired private XljkConsultationAppointmentMapper mapper; - + @Autowired private XljkConsultationScheduleMapper scheduleMapper; - + @Autowired private ISysUserService userService; @Autowired private JdbcTemplate jdbcTemplate; - + @Autowired private DataSource dataSource; @@ -68,29 +68,29 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation log.warn("未找到ID为{}的预约记录", id); return null; } - + log.info("找到预约记录: {}", entity); XljkConsultationAppointmentVo vo = new XljkConsultationAppointmentVo(); BeanUtils.copyProperties(entity, vo); - + // 记录关键字段 - log.info("复制后的VO对象关键字段:status={}, communicationDuration={}, consultationContent长度={}, counselorSuggestion长度={}", + log.info("复制后的VO对象关键字段:status={}, communicationDuration={}, consultationContent长度={}, counselorSuggestion长度={}", vo.getStatus(), vo.getCommunicationDuration(), vo.getConsultationContent() != null ? vo.getConsultationContent().length() : 0, vo.getCounselorSuggestion() != null ? vo.getCounselorSuggestion().length() : 0); - + // 使用与selectList相同的方式查询关联信息 String sql = "SELECT s.name as student_name, s.student_no, s.class_name, s.college_name, s.major_name, " + - "u.nick_name as counselor_name " + - "FROM xg_student_msg s " + - "LEFT JOIN sys_user u ON u.user_id = " + entity.getCounselorId() + " " + - "WHERE s.id = " + entity.getStudentId(); - + "u.nick_name as counselor_name " + + "FROM xg_student_msg s " + + "LEFT JOIN sys_user u ON u.user_id = " + entity.getCounselorId() + " " + + "WHERE s.id = " + entity.getStudentId(); + try { Map result = jdbcTemplate.queryForMap(sql); log.info("关联查询结果: {}", result); - + // 填充关联信息 vo.setStudentName((String) result.get("student_name")); vo.setStudentNo((String) result.get("student_no")); @@ -103,10 +103,11 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation // 如果关联查询失败,尝试分别查询 try { // 查询学生信息 - String studentSql = "SELECT name, student_no, class_name, college_name, major_name FROM xg_student_msg WHERE id = " + entity.getStudentId(); + String studentSql = "SELECT name, student_no, class_name, college_name, major_name FROM xg_student_msg WHERE id = " + + entity.getStudentId(); Map studentInfo = jdbcTemplate.queryForMap(studentSql); log.info("学生信息查询结果: {}", studentInfo); - + vo.setStudentName((String) studentInfo.get("name")); vo.setStudentNo((String) studentInfo.get("student_no")); vo.setClassName((String) studentInfo.get("class_name")); @@ -115,7 +116,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } catch (Exception ex) { log.error("查询学生信息失败", ex); } - + try { // 查询咨询师信息 SysUserVo counselor = userService.selectUserById(entity.getCounselorId()); @@ -127,13 +128,13 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation log.error("查询咨询师信息失败", ex); } } - + // 再次检查关键字段 if (vo.getStatus() != null && vo.getStatus() == 1) { - log.info("已到访状态,检查咨询结果相关字段:communicationDuration={}", + log.info("已到访状态,检查咨询结果相关字段:communicationDuration={}", vo.getCommunicationDuration()); } - + log.info("返回预约记录详情: {}", vo); return vo; } @@ -149,85 +150,86 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation sqlBuilder.append("LEFT JOIN xg_student_msg s ON a.student_id = s.id "); sqlBuilder.append("LEFT JOIN sys_user u ON a.counselor_id = u.user_id "); sqlBuilder.append("WHERE a.deleted = 0 "); - + List params = new ArrayList<>(); - + // 添加查询条件 if (bo.getStudentId() != null) { sqlBuilder.append("AND a.student_id = ? "); params.add(bo.getStudentId()); } - + if (bo.getCounselorId() != null) { sqlBuilder.append("AND a.counselor_id = ? "); params.add(bo.getCounselorId()); } - + if (bo.getStatus() != null) { sqlBuilder.append("AND a.status = ? "); params.add(bo.getStatus()); } - + if (bo.getAppointmentDate() != null) { sqlBuilder.append("AND a.appointment_date = ? "); params.add(bo.getAppointmentDate()); } - + // 添加新增字段查询条件 if (StringUtils.isNotBlank(bo.getStudentName())) { sqlBuilder.append("AND s.name LIKE ? "); params.add("%" + bo.getStudentName() + "%"); } - + if (StringUtils.isNotBlank(bo.getStudentNo())) { sqlBuilder.append("AND s.student_no LIKE ? "); params.add("%" + bo.getStudentNo() + "%"); } - + if (StringUtils.isNotBlank(bo.getCollegeName())) { sqlBuilder.append("AND s.college_name LIKE ? "); params.add("%" + bo.getCollegeName() + "%"); } - + if (StringUtils.isNotBlank(bo.getMajorName())) { sqlBuilder.append("AND s.major_name LIKE ? "); params.add("%" + bo.getMajorName() + "%"); } - + if (StringUtils.isNotBlank(bo.getClassName())) { sqlBuilder.append("AND s.class_name LIKE ? "); params.add("%" + bo.getClassName() + "%"); } - + // 添加排序 - sqlBuilder.append("ORDER BY a.create_time DESC"); - + sqlBuilder.append("ORDER BY s.student_no DESC, a.create_time DESC"); + log.info("执行SQL查询: {}", sqlBuilder.toString()); log.info("参数: {}", params); - + // 执行查询 List> resultList = jdbcTemplate.queryForList(sqlBuilder.toString(), params.toArray()); - + log.info("查询结果数量: {}", resultList.size()); if (!resultList.isEmpty()) { Map firstRow = resultList.get(0); - log.info("第一条记录: student_id={}, student_name={}, student_no={}, class_name={}, college_name={}, major_name={}, counselor_name={}", - firstRow.get("student_id"), - firstRow.get("student_name"), - firstRow.get("student_no"), - firstRow.get("class_name"), - firstRow.get("college_name"), - firstRow.get("major_name"), - firstRow.get("counselor_name")); + log.info( + "第一条记录: student_id={}, student_name={}, student_no={}, class_name={}, college_name={}, major_name={}, counselor_name={}", + firstRow.get("student_id"), + firstRow.get("student_name"), + firstRow.get("student_no"), + firstRow.get("class_name"), + firstRow.get("college_name"), + firstRow.get("major_name"), + firstRow.get("counselor_name")); } - + // 转换为VO对象 return resultList.stream().map(row -> { XljkConsultationAppointmentVo vo = new XljkConsultationAppointmentVo(); - + // 获取学生ID用于计算本学期到访次数 Long studentId = row.get("student_id") != null ? ((Number) row.get("student_id")).longValue() : null; - + // 设置基本字段 vo.setId(((Number) row.get("id")).longValue()); vo.setTenantId((String) row.get("tenant_id")); @@ -236,7 +238,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation vo.setCreateTime(convertToDate(row.get("create_time"))); vo.setUpdateBy(row.get("update_by") != null ? ((Number) row.get("update_by")).longValue() : null); vo.setUpdateTime(convertToDate(row.get("update_time"))); - + // 处理deleted字段,可能是Boolean或Integer类型 Object deletedObj = row.get("deleted"); if (deletedObj instanceof Boolean) { @@ -246,7 +248,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } else { vo.setDeleted(0); // 默认值 } - + vo.setStudentId(row.get("student_id") != null ? ((Number) row.get("student_id")).longValue() : null); vo.setCounselorId(row.get("counselor_id") != null ? ((Number) row.get("counselor_id")).longValue() : null); vo.setScheduleId(row.get("schedule_id") != null ? ((Number) row.get("schedule_id")).longValue() : null); @@ -254,11 +256,11 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation vo.setAppointmentTime((String) row.get("appointment_time")); vo.setAppointmentDetailTime((String) row.get("appointment_detail_time")); vo.setReason((String) row.get("reason")); - + // 记录status字段的值和类型 Object statusObj = row.get("status"); log.info("status字段值: {}, 类型: {}", statusObj, statusObj != null ? statusObj.getClass().getName() : "null"); - + // 将status字段从String类型改为Integer类型 if (statusObj != null) { if (statusObj instanceof String) { @@ -280,14 +282,16 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation log.info("status字段为null,设置默认值0"); vo.setStatus(0); // 默认为待咨询 } - - vo.setCommunicationDuration(row.get("communication_duration") != null ? ((Number) row.get("communication_duration")).intValue() : null); + + vo.setCommunicationDuration( + row.get("communication_duration") != null ? ((Number) row.get("communication_duration")).intValue() + : null); vo.setConsultationContent((String) row.get("consultation_content")); vo.setCounselorSuggestion((String) row.get("counselor_suggestion")); - + // 设置咨询主题字段 vo.setConsultTheme((String) row.get("consult_theme")); - + // 设置心理健康相关字段 Object psychologicalHistoryObj = row.get("psychological_history"); if (psychologicalHistoryObj != null) { @@ -301,11 +305,11 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } } } - + vo.setPsychologicalHistoryDetail((String) row.get("psychological_history_detail")); vo.setBasicSituation((String) row.get("basic_situation")); vo.setMajorLifeEvents((String) row.get("major_life_events")); - + Object needReferralObj = row.get("need_referral"); if (needReferralObj != null) { if (needReferralObj instanceof Number) { @@ -318,7 +322,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } } } - + // 设置关联字段 vo.setStudentName((String) row.get("student_name")); vo.setStudentNo((String) row.get("student_no")); @@ -326,22 +330,23 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation vo.setCounselorName((String) row.get("counselor_name")); vo.setCollegeName((String) row.get("college_name")); vo.setMajorName((String) row.get("major_name")); - + // 计算本学期到访次数 if (studentId != null) { vo.setSemesterVisitCount(calculateSemesterVisitCount(studentId)); } else { vo.setSemesterVisitCount(0); } - + return vo; }).collect(Collectors.toList()); } - + /** * 计算学生本学期到访次数 * 上学期:3月1日-8月31日 * 下学期:9月1日-2月29日 + * * @param studentId 学生ID * @return 本学期到访次数 */ @@ -350,7 +355,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation // 获取当前日期 LocalDate now = LocalDate.now(); String startDate, endDate; - + // 判断当前处于哪个学期 if (now.getMonthValue() >= 3 && now.getMonthValue() <= 8) { // 上学期:3月1日-8月31日 @@ -373,16 +378,16 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation LocalDate lastDayOfFeb = currentFeb.withDayOfMonth(currentFeb.lengthOfMonth()); endDate = lastDayOfFeb.toString(); } - + // 查询该学生在当前学期内状态为已到访(status=1)的记录数 String sql = "SELECT COUNT(*) FROM xljk_consultation_appointment " + - "WHERE student_id = ? AND status = 1 AND deleted = 0 " + - "AND appointment_date >= ? AND appointment_date <= ?"; - + "WHERE student_id = ? AND status = 1 AND deleted = 0 " + + "AND appointment_date >= ? AND appointment_date <= ?"; + Integer count = jdbcTemplate.queryForObject(sql, Integer.class, studentId, startDate, endDate); - + log.debug("学生ID: {}, 学期时间段: {} - {}, 到访次数: {}", studentId, startDate, endDate, count); - + return count != null ? count : 0; } catch (Exception e) { log.error("计算学生本学期到访次数失败,学生ID: {}", studentId, e); @@ -408,29 +413,30 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation public boolean deleteById(Long id) { return mapper.deleteById(id) > 0; } - + @Override public List> getAvailableTimeSlots(Date startDate, Date endDate) { // 查询指定日期范围内的可用时段 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(XljkConsultationSchedule::getScheduleDate, startDate) - .le(XljkConsultationSchedule::getScheduleDate, endDate) - .eq(XljkConsultationSchedule::getStatus, "0"); // 0表示正常可用 - + .le(XljkConsultationSchedule::getScheduleDate, endDate) + .eq(XljkConsultationSchedule::getStatus, "0"); // 0表示正常可用 + List schedules = scheduleMapper.selectList(queryWrapper); - + // 查询已预约的时段 LambdaQueryWrapper appointmentQueryWrapper = new LambdaQueryWrapper<>(); appointmentQueryWrapper.ge(XljkConsultationAppointment::getAppointmentDate, startDate) - .le(XljkConsultationAppointment::getAppointmentDate, endDate) - .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1", "4")); // 待咨询、已完成或待审核的 - + .le(XljkConsultationAppointment::getAppointmentDate, endDate) + .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1", "4")); // 待咨询、已完成或待审核的 + List appointments = mapper.selectList(appointmentQueryWrapper); - + // 构建已预约时段的映射,用于快速查找 Map> bookedDetailSlots = new HashMap<>(); for (XljkConsultationAppointment appointment : appointments) { - String key = new SimpleDateFormat("yyyy-MM-dd").format(appointment.getAppointmentDate()) + "_" + appointment.getScheduleId(); + String key = new SimpleDateFormat("yyyy-MM-dd").format(appointment.getAppointmentDate()) + "_" + + appointment.getScheduleId(); if (!bookedDetailSlots.containsKey(key)) { bookedDetailSlots.put(key, new ArrayList<>()); } @@ -438,26 +444,27 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation bookedDetailSlots.get(key).add(appointment.getAppointmentDetailTime()); } } - + // 构建可用时段列表 List> availableSlots = new ArrayList<>(); Date now = new Date(); // 获取当前时间 - + for (XljkConsultationSchedule schedule : schedules) { String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(schedule.getScheduleDate()); String key = dateStr + "_" + schedule.getId(); - + // 检查该时段的可用详细时段(用于时间判断,但总容量固定为1) - List detailSlots = TimeSlotUtils.generateTimeSlots(schedule.getStartTime(), schedule.getEndTime()); + List detailSlots = TimeSlotUtils.generateTimeSlots(schedule.getStartTime(), + schedule.getEndTime()); int totalDetailSlots = detailSlots.size(); // 保留用于时间过期判断 int totalSlots = 1; // 每个时段只能预约1个人 int bookedCount = 0; boolean isExpired = false; - + // 检查是否已过期 - 更精确的判断逻辑 try { // 使用已生成的详细时间段进行过期判断 - + // 检查是否还有未过期的详细时间段 boolean hasValidSlots = false; for (TimeSlotDetailVo detailSlot : detailSlots) { @@ -465,7 +472,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation String[] timeParts = detailSlot.getStartTime().split(":"); int hour = Integer.parseInt(timeParts[0]); int minute = Integer.parseInt(timeParts[1]); - + // 设置该详细时间段的开始时间 Calendar detailSlotCalendar = Calendar.getInstance(); detailSlotCalendar.setTime(schedule.getScheduleDate()); @@ -473,31 +480,31 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation detailSlotCalendar.set(Calendar.MINUTE, minute); detailSlotCalendar.set(Calendar.SECOND, 0); detailSlotCalendar.set(Calendar.MILLISECOND, 0); - + Date detailSlotStartTime = detailSlotCalendar.getTime(); - + // 如果该详细时间段未过期,则整个时段还有可用时间 if (detailSlotStartTime.after(now)) { hasValidSlots = true; break; } } - + // 如果没有任何未过期的详细时间段,则标记为已过期 isExpired = !hasValidSlots; - + } catch (Exception e) { // 如果解析时间失败,默认标记为未过期 isExpired = false; } - + // 检查已预约数量(按整个时段计算,不再按详细时段计算) if (bookedDetailSlots.containsKey(key)) { List bookedTimes = bookedDetailSlots.get(key); // 只要有任何预约,就算已预约1个(因为每个时段只能预约1个人) bookedCount = bookedTimes.isEmpty() ? 0 : 1; } - + // 创建时段信息 Map slot = new HashMap<>(); slot.put("scheduleId", schedule.getId()); @@ -509,7 +516,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation slot.put("allBooked", bookedCount >= totalSlots); // 是否全部约满 slot.put("availableCount", totalSlots - bookedCount); // 可用数量 slot.put("isExpired", isExpired); // 是否已过期 - + // 查询咨询师姓名 if (schedule.getCounselorId() != null) { try { @@ -527,20 +534,20 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } else { slot.put("counselorName", null); } - + availableSlots.add(slot); } - + return availableSlots; } - - @Override + + @Override public List getAvailableDetailSlots(Date date, String timeSlot) { // 1. 查询该日期该时段的排班信息 LambdaQueryWrapper scheduleQueryWrapper = new LambdaQueryWrapper<>(); scheduleQueryWrapper.eq(XljkConsultationSchedule::getScheduleDate, date) - .eq(XljkConsultationSchedule::getTimeSlot, timeSlot) - .eq(XljkConsultationSchedule::getStatus, "0"); // 0表示正常可用 + .eq(XljkConsultationSchedule::getTimeSlot, timeSlot) + .eq(XljkConsultationSchedule::getStatus, "0"); // 0表示正常可用 // 修改:使用selectList()而不是selectOne(),因为可能有多条记录 List schedules = scheduleMapper.selectList(scheduleQueryWrapper); @@ -553,9 +560,10 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation // 2. 合并所有排班的时段,生成完整的30分钟时段列表 List allTimeSlots = new ArrayList<>(); Set uniqueTimeSlots = new LinkedHashSet<>(); // 用于去重,保持顺序 - + for (XljkConsultationSchedule schedule : schedules) { - List timeSlots = TimeSlotUtils.generateTimeSlots(schedule.getStartTime(), schedule.getEndTime()); + List timeSlots = TimeSlotUtils.generateTimeSlots(schedule.getStartTime(), + schedule.getEndTime()); for (TimeSlotDetailVo slot : timeSlots) { String slotKey = slot.getStartTime() + "-" + slot.getEndTime(); if (uniqueTimeSlots.add(slotKey)) { @@ -563,29 +571,29 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } } } - + // 3. 查询已预约的时段(查询所有相关排班的预约) List scheduleIds = schedules.stream().map(XljkConsultationSchedule::getId).collect(Collectors.toList()); LambdaQueryWrapper appointmentQueryWrapper = new LambdaQueryWrapper<>(); appointmentQueryWrapper.eq(XljkConsultationAppointment::getAppointmentDate, date) - .in(XljkConsultationAppointment::getScheduleId, scheduleIds) // 按排班ID列表过滤 - .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1", "4")); // 待咨询、已完成或待审核的 - + .in(XljkConsultationAppointment::getScheduleId, scheduleIds) // 按排班ID列表过滤 + .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1", "4")); // 待咨询、已完成或待审核的 + List appointments = mapper.selectList(appointmentQueryWrapper); - + // 4. 标记已预约和已过期的时段 Set bookedDetailTimes = appointments.stream() - .map(XljkConsultationAppointment::getAppointmentDetailTime) - .collect(Collectors.toSet()); - + .map(XljkConsultationAppointment::getAppointmentDetailTime) + .collect(Collectors.toSet()); + // 获取当前时间 Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); - + for (TimeSlotDetailVo slot : allTimeSlots) { String detailTime = slot.getStartTime() + "-" + slot.getEndTime(); - + // 检查是否已预约 if (bookedDetailTimes.contains(detailTime)) { slot.setIsBooked(true); @@ -597,7 +605,7 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation String[] timeParts = slot.getStartTime().split(":"); int hour = Integer.parseInt(timeParts[0]); int minute = Integer.parseInt(timeParts[1]); - + // 设置该时间段的开始时间 Calendar slotCalendar = Calendar.getInstance(); slotCalendar.setTime(date); @@ -605,9 +613,9 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation slotCalendar.set(Calendar.MINUTE, minute); slotCalendar.set(Calendar.SECOND, 0); slotCalendar.set(Calendar.MILLISECOND, 0); - + Date slotStartTime = slotCalendar.getTime(); - + // 如果时间段开始时间早于当前时间,则标记为已过期 if (slotStartTime.before(now)) { slot.setIsExpired(true); @@ -623,26 +631,26 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation } } } - + return allTimeSlots; } - + @Override @Transactional public boolean submitAppointment(XljkConsultationAppointmentBo bo) { // 检查该时段是否已被预约 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(XljkConsultationAppointment::getScheduleId, bo.getScheduleId()) - .eq(XljkConsultationAppointment::getAppointmentDate, bo.getAppointmentDate()) - .eq(XljkConsultationAppointment::getAppointmentDetailTime, bo.getAppointmentDetailTime()) - .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1")); // 待咨询或已完成的 - + .eq(XljkConsultationAppointment::getAppointmentDate, bo.getAppointmentDate()) + .eq(XljkConsultationAppointment::getAppointmentDetailTime, bo.getAppointmentDetailTime()) + .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1")); // 待咨询或已完成的 + long count = mapper.selectCount(queryWrapper); if (count > 0) { // 该时段已被预约 return false; } - + // 检查学生ID是否有效,并获取正确的学生ID Long studentId = bo.getStudentId(); if (studentId != null) { @@ -650,12 +658,12 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation // 根据学生ID查询学生信息 String sql = "SELECT id FROM xg_student_msg WHERE id = ?"; List> result = jdbcTemplate.queryForList(sql, studentId); - + // 如果没有找到学生信息,尝试通过学号查询 if (result.isEmpty() && bo.getStudentNo() != null && !bo.getStudentNo().isEmpty()) { sql = "SELECT id FROM xg_student_msg WHERE student_no = ?"; result = jdbcTemplate.queryForList(sql, bo.getStudentNo()); - + if (!result.isEmpty()) { // 使用查询到的正确学生ID studentId = ((Number) result.get(0).get("id")).longValue(); @@ -666,10 +674,10 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation log.error("验证学生ID时出错: {}", e.getMessage()); } } - + // 检查学生是否有"三次不到"记录 // TODO: 实现"三次不到"规则检查逻辑 - + // 提交预约 XljkConsultationAppointment entity = new XljkConsultationAppointment(); BeanUtils.copyProperties(bo, entity); @@ -678,27 +686,27 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation entity.setCreateTime(new Date()); // 设置创建时间 return mapper.insert(entity) > 0; } - + @Override public List getMyAppointments(Long studentId) { log.info("获取学生预约记录,studentId: {}", studentId); - + // 使用原生SQL查询以绕过MyBatis缓存,确保获取最新数据 String sql = "SELECT a.*, u.nick_name AS counselor_name " + - "FROM xljk_consultation_appointment a " + - "LEFT JOIN sys_user u ON a.counselor_id = u.user_id " + - "WHERE a.student_id = ? AND a.deleted = 0 " + - "ORDER BY a.create_time DESC, a.id DESC"; - + "FROM xljk_consultation_appointment a " + + "LEFT JOIN sys_user u ON a.counselor_id = u.user_id " + + "WHERE a.student_id = ? AND a.deleted = 0 " + + "ORDER BY a.student_no DESC, a.id DESC, a.create_time DESC"; + List result = new ArrayList<>(); - + try { List> rows = jdbcTemplate.queryForList(sql, studentId); log.info("查询到预约记录数: {}", rows.size()); - + for (Map row : rows) { XljkConsultationAppointmentVo vo = new XljkConsultationAppointmentVo(); - + // 设置主要字段 vo.setId(((Number) row.get("id")).longValue()); vo.setStudentId(((Number) row.get("student_id")).longValue()); @@ -708,91 +716,91 @@ public class XljkConsultationAppointmentServiceImpl implements IXljkConsultation vo.setAppointmentDetailTime((String) row.get("appointment_detail_time")); vo.setReason((String) row.get("reason")); // 处理状态字段,确保类型正确 -Object statusObj = row.get("status"); -if (statusObj != null) { - if (statusObj instanceof Number) { - vo.setStatus(((Number) statusObj).intValue()); - } else if (statusObj instanceof String) { - try { - vo.setStatus(Integer.parseInt((String) statusObj)); - } catch (NumberFormatException e) { - log.warn("状态值转换失败: {}", statusObj); - vo.setStatus(0); // 默认待咨询 - } - } else { - log.warn("未知状态类型: {}", statusObj.getClass().getName()); - vo.setStatus(0); // 默认待咨询 - } -} else { - vo.setStatus(0); // 默认待咨询状态 -} + Object statusObj = row.get("status"); + if (statusObj != null) { + if (statusObj instanceof Number) { + vo.setStatus(((Number) statusObj).intValue()); + } else if (statusObj instanceof String) { + try { + vo.setStatus(Integer.parseInt((String) statusObj)); + } catch (NumberFormatException e) { + log.warn("状态值转换失败: {}", statusObj); + vo.setStatus(0); // 默认待咨询 + } + } else { + log.warn("未知状态类型: {}", statusObj.getClass().getName()); + vo.setStatus(0); // 默认待咨询 + } + } else { + vo.setStatus(0); // 默认待咨询状态 + } vo.setCounselorName((String) row.get("counselor_name")); - + // 可选字段 if (row.get("counselor_id") != null) { vo.setCounselorId(((Number) row.get("counselor_id")).longValue()); } - + if (row.get("schedule_id") != null) { vo.setScheduleId(((Number) row.get("schedule_id")).longValue()); } - + if (row.get("communication_duration") != null) { vo.setCommunicationDuration(((Number) row.get("communication_duration")).intValue()); } - + vo.setConsultationContent((String) row.get("consultation_content")); vo.setCounselorSuggestion((String) row.get("counselor_suggestion")); - + // 其他通用字段 if (row.get("create_by") != null) { vo.setCreateBy(((Number) row.get("create_by")).longValue()); } - + if (row.get("create_time") != null) { vo.setCreateTime(convertToDate(row.get("create_time"))); } - + if (row.get("update_by") != null) { vo.setUpdateBy(((Number) row.get("update_by")).longValue()); } - + if (row.get("update_time") != null) { vo.setUpdateTime(convertToDate(row.get("update_time"))); } - + result.add(vo); } - + // 打印日志,显示每条记录的状态,便于调试 for (XljkConsultationAppointmentVo vo : result) { - log.info("预约记录 ID: {}, 状态: {}, 日期: {}", - vo.getId(), vo.getStatus(), vo.getAppointmentDate()); + log.info("预约记录 ID: {}, 状态: {}, 日期: {}", + vo.getId(), vo.getStatus(), vo.getAppointmentDate()); } - + } catch (Exception e) { log.error("获取学生预约记录异常", e); } - + return result; } - + @Override @Transactional - public boolean recordConsultation(Long id, Integer communicationDuration, - String consultationContent, String counselorSuggestion, String status, - Integer psychologicalHistory, String psychologicalHistoryDetail, - String basicSituation, String majorLifeEvents, Integer needReferral) { + public boolean recordConsultation(Long id, Integer communicationDuration, + String consultationContent, String counselorSuggestion, String status, + Integer psychologicalHistory, String psychologicalHistoryDetail, + String basicSituation, String majorLifeEvents, Integer needReferral) { log.info("记录咨询结果,ID: {}, 状态: {}, 心理病史: {}, 转介: {}", id, status, psychologicalHistory, needReferral); - + XljkConsultationAppointment entity = mapper.selectById(id); if (entity == null) { log.warn("未找到ID为{}的预约记录", id); return false; } - + log.info("找到预约记录: {}", entity); - + // 将status转换为Integer类型进行比较,但保存时仍使用原始String类型 Integer statusInt; try { @@ -802,28 +810,28 @@ if (statusObj != null) { statusInt = 1; // 默认已到访 status = "1"; // 确保status也更新为"1" } - + entity.setStatus(status); // 使用原始String类型的status - + // 只有在已到访状态(1)时,才设置咨询结果相关字段 if (statusInt == 1) { entity.setCommunicationDuration(communicationDuration != null ? communicationDuration : 30); entity.setConsultationContent(consultationContent); entity.setCounselorSuggestion(counselorSuggestion); - + // 设置心理病史相关字段 entity.setPsychologicalHistory(psychologicalHistory); entity.setPsychologicalHistoryDetail(psychologicalHistoryDetail); entity.setBasicSituation(basicSituation); entity.setMajorLifeEvents(majorLifeEvents); entity.setNeedReferral(needReferral); - - log.info("设置咨询结果相关字段:沟通时长={}, 咨询内容长度={}, 咨询师建议长度={}", - communicationDuration, + + log.info("设置咨询结果相关字段:沟通时长={}, 咨询内容长度={}, 咨询师建议长度={}", + communicationDuration, consultationContent != null ? consultationContent.length() : 0, counselorSuggestion != null ? counselorSuggestion.length() : 0); - - log.info("设置心理病史相关字段:心理病史={}, 心理病史详情长度={}, 基本情况长度={}, 重大生活事件长度={}, 转介={}", + + log.info("设置心理病史相关字段:心理病史={}, 心理病史详情长度={}, 基本情况长度={}, 重大生活事件长度={}, 转介={}", psychologicalHistory, psychologicalHistoryDetail != null ? psychologicalHistoryDetail.length() : 0, basicSituation != null ? basicSituation.length() : 0, @@ -835,22 +843,24 @@ if (statusObj != null) { entity.setCommunicationDuration(0); entity.setConsultationContent(""); entity.setCounselorSuggestion(""); - + // 清空心理病史相关字段 entity.setPsychologicalHistory(null); entity.setPsychologicalHistoryDetail(""); entity.setBasicSituation(""); entity.setMajorLifeEvents(""); entity.setNeedReferral(null); - + // 如果是未到访状态(3),创建未到访记录 if (statusInt == 3) { log.info("记录未到访,创建未到访记录"); try { // 注入XljkConsultationNoShowService - IXljkConsultationNoShowService noShowService = SpringUtils.getBean(IXljkConsultationNoShowService.class); + IXljkConsultationNoShowService noShowService = SpringUtils + .getBean(IXljkConsultationNoShowService.class); if (noShowService != null) { - noShowService.createNoShowRecord(entity.getStudentId(), entity.getId(), entity.getAppointmentDate()); + noShowService.createNoShowRecord(entity.getStudentId(), entity.getId(), + entity.getAppointmentDate()); } else { log.error("无法获取XljkConsultationNoShowService实例"); } @@ -860,10 +870,10 @@ if (statusObj != null) { } } } - + int result = mapper.updateById(entity); log.info("更新结果: {}", result > 0 ? "成功" : "失败"); - + return result > 0; } @@ -883,18 +893,18 @@ if (statusObj != null) { List params = new ArrayList<>(); // 超级管理员或心理健康管理员可以查看所有院系 - boolean isAdmin = LoginHelper.isSuperAdmin() || - LoginHelper.getLoginUser().getRoles().stream() - .anyMatch(role -> "xljk_admin".equals(role.getRoleKey())); - + boolean isAdmin = LoginHelper.isSuperAdmin() || + LoginHelper.getLoginUser().getRoles().stream() + .anyMatch(role -> "xljk_admin".equals(role.getRoleKey())); + if (isAdmin) { sql = "SELECT DISTINCT college_id as id, college_name as name FROM xg_class_msg " + - "WHERE college_name IS NOT NULL AND deleted = 0 ORDER BY college_name"; + "WHERE college_name IS NOT NULL AND deleted = 0 ORDER BY college_name, create_time DESC"; params = new ArrayList<>(); log.info("管理员查询所有院系"); } else { sql = "SELECT DISTINCT college_id as id, college_name as name FROM xg_class_msg " + - "WHERE counselor_id = ? AND college_name IS NOT NULL AND deleted = 0 ORDER BY college_name"; + "WHERE counselor_id = ? AND college_name IS NOT NULL AND deleted = 0 ORDER BY college_name, create_time DESC"; params.add(userId); log.info("普通用户查询院系,userId={}", userId); } @@ -903,7 +913,7 @@ if (statusObj != null) { // 使用JdbcTemplate执行查询 List> queryResult = jdbcTemplate.queryForList(sql, params.toArray()); log.info("院系查询结果: {}", queryResult); - + if (queryResult != null && !queryResult.isEmpty()) { return queryResult; } else { @@ -912,36 +922,36 @@ if (statusObj != null) { } catch (Exception e) { log.error("查询院系数据异常", e); } - + // 如果没有查询到数据,尝试使用更简单的查询 sql = "SELECT DISTINCT college_id as id, college_name as name FROM xg_class_msg " + - "WHERE college_name IS NOT NULL ORDER BY college_name"; - + "WHERE college_name IS NOT NULL ORDER BY college_name, create_time DESC"; + try { List> fallbackResult = jdbcTemplate.queryForList(sql); log.info("备用查询院系结果: {}", fallbackResult); - + if (fallbackResult != null && !fallbackResult.isEmpty()) { return fallbackResult; } } catch (Exception e) { log.error("备用查询院系数据异常", e); } - + // 如果仍然没有数据,添加测试数据(仅作为最后的备选方案) if (result.isEmpty()) { log.warn("未从数据库获取到院系数据,添加测试数据"); - + Map option1 = new HashMap<>(); option1.put("id", 1L); option1.put("name", "信息工程学院"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 2L); option2.put("name", "机械工程学院"); result.add(option2); - + Map option3 = new HashMap<>(); option3.put("id", 3L); option3.put("name", "人文学院"); @@ -950,7 +960,7 @@ if (statusObj != null) { } catch (Exception e) { log.error("获取院系选项异常", e); } - + return result; } @@ -970,32 +980,32 @@ if (statusObj != null) { List params = new ArrayList<>(); // 超级管理员或心理健康管理员可以查看所有专业 - boolean isAdmin = LoginHelper.isSuperAdmin() || - LoginHelper.getLoginUser().getRoles().stream() - .anyMatch(role -> "xljk_admin".equals(role.getRoleKey())); - + boolean isAdmin = LoginHelper.isSuperAdmin() || + LoginHelper.getLoginUser().getRoles().stream() + .anyMatch(role -> "xljk_admin".equals(role.getRoleKey())); + if (isAdmin) { sql = "SELECT DISTINCT major_id as id, major_name as name FROM xg_class_msg " + - "WHERE major_name IS NOT NULL AND deleted = 0"; - + "WHERE major_name IS NOT NULL AND deleted = 0"; + if (StringUtils.isNotEmpty(collegeName)) { sql += " AND college_name = ?"; params.add(collegeName); } - - sql += " ORDER BY major_name"; + + sql += " ORDER BY major_name, create_time DESC"; log.info("管理员查询专业,collegeName={}", collegeName); } else { sql = "SELECT DISTINCT major_id as id, major_name as name FROM xg_class_msg " + - "WHERE counselor_id = ? AND major_name IS NOT NULL AND deleted = 0"; + "WHERE counselor_id = ? AND major_name IS NOT NULL AND deleted = 0"; params.add(userId); - + if (StringUtils.isNotEmpty(collegeName)) { sql += " AND college_name = ?"; params.add(collegeName); } - - sql += " ORDER BY major_name"; + + sql += " ORDER BY major_name, create_time DESC"; log.info("普通用户查询专业,userId={}, collegeName={}", userId, collegeName); } @@ -1003,7 +1013,7 @@ if (statusObj != null) { // 使用JdbcTemplate执行查询 List> queryResult = jdbcTemplate.queryForList(sql, params.toArray()); log.info("专业查询结果: {}", queryResult); - + if (queryResult != null && !queryResult.isEmpty()) { return queryResult; } else { @@ -1012,45 +1022,45 @@ if (statusObj != null) { } catch (Exception e) { log.error("查询专业数据异常", e); } - + // 如果没有查询到数据,尝试使用更简单的查询 sql = "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 += " AND college_name = ?"; params.add(collegeName); } - - sql += " ORDER BY major_name"; - + + sql += " ORDER BY major_name, create_time DESC"; + try { List> fallbackResult = jdbcTemplate.queryForList(sql, params.toArray()); log.info("备用查询专业结果: {}", fallbackResult); - + if (fallbackResult != null && !fallbackResult.isEmpty()) { return fallbackResult; } } catch (Exception e) { log.error("备用查询专业数据异常", e); } - + // 如果仍然没有数据,添加测试数据(仅作为最后的备选方案) if (result.isEmpty()) { log.warn("未从数据库获取到专业数据,添加测试数据,collegeName={}", collegeName); - + // 根据院系名称返回对应的专业 if ("信息工程学院".equals(collegeName)) { Map option1 = new HashMap<>(); option1.put("id", 1L); option1.put("name", "计算机科学与技术"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 2L); option2.put("name", "软件工程"); result.add(option2); - + Map option3 = new HashMap<>(); option3.put("id", 3L); option3.put("name", "网络工程"); @@ -1060,7 +1070,7 @@ if (statusObj != null) { option1.put("id", 4L); option1.put("name", "机械设计制造及其自动化"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 5L); option2.put("name", "材料成型及控制工程"); @@ -1070,7 +1080,7 @@ if (statusObj != null) { option1.put("id", 6L); option1.put("name", "汉语言文学"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 7L); option2.put("name", "英语"); @@ -1081,32 +1091,32 @@ if (statusObj != null) { option1.put("id", 1L); option1.put("name", "计算机科学与技术"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 2L); option2.put("name", "软件工程"); result.add(option2); - + Map option3 = new HashMap<>(); option3.put("id", 3L); option3.put("name", "网络工程"); result.add(option3); - + Map option4 = new HashMap<>(); option4.put("id", 4L); option4.put("name", "机械设计制造及其自动化"); result.add(option4); - + Map option5 = new HashMap<>(); option5.put("id", 5L); option5.put("name", "材料成型及控制工程"); result.add(option5); - + Map option6 = new HashMap<>(); option6.put("id", 6L); option6.put("name", "汉语言文学"); result.add(option6); - + Map option7 = new HashMap<>(); option7.put("id", 7L); option7.put("name", "英语"); @@ -1116,7 +1126,7 @@ if (statusObj != null) { } catch (Exception e) { log.error("获取专业选项异常", e); } - + return result; } @@ -1136,40 +1146,40 @@ if (statusObj != null) { List params = new ArrayList<>(); // 超级管理员或心理健康管理员可以查看所有班级 - boolean isAdmin = LoginHelper.isSuperAdmin() || - LoginHelper.getLoginUser().getRoles().stream() - .anyMatch(role -> "xljk_admin".equals(role.getRoleKey())); - + boolean isAdmin = LoginHelper.isSuperAdmin() || + LoginHelper.getLoginUser().getRoles().stream() + .anyMatch(role -> "xljk_admin".equals(role.getRoleKey())); + if (isAdmin) { sql = "SELECT id, class_name as name FROM xg_class_msg WHERE class_name IS NOT NULL AND deleted = 0"; - + if (StringUtils.isNotEmpty(collegeName)) { sql += " AND college_name = ?"; params.add(collegeName); } - + if (StringUtils.isNotEmpty(majorName)) { sql += " AND major_name = ?"; params.add(majorName); } - - sql += " ORDER BY class_name"; + + sql += " ORDER BY class_name, create_time DESC"; log.info("管理员查询班级,collegeName={}, majorName={}", collegeName, majorName); } else { sql = "SELECT id, class_name as name FROM xg_class_msg WHERE counselor_id = ? AND class_name IS NOT NULL AND deleted = 0"; params.add(userId); - + if (StringUtils.isNotEmpty(collegeName)) { sql += " AND college_name = ?"; params.add(collegeName); } - + if (StringUtils.isNotEmpty(majorName)) { sql += " AND major_name = ?"; params.add(majorName); } - - sql += " ORDER BY class_name"; + + sql += " ORDER BY class_name, create_time DESC"; log.info("普通用户查询班级,userId={}, collegeName={}, majorName={}", userId, collegeName, majorName); } @@ -1177,7 +1187,7 @@ if (statusObj != null) { // 使用JdbcTemplate执行查询 List> queryResult = jdbcTemplate.queryForList(sql, params.toArray()); log.info("班级查询结果: {}", queryResult); - + if (queryResult != null && !queryResult.isEmpty()) { return queryResult; } else { @@ -1186,38 +1196,38 @@ if (statusObj != null) { } catch (Exception e) { log.error("查询班级数据异常", e); } - + // 如果没有查询到数据,尝试使用更简单的查询 sql = "SELECT id, class_name as name FROM xg_class_msg WHERE class_name IS NOT NULL"; params.clear(); - + if (StringUtils.isNotEmpty(collegeName)) { sql += " AND college_name = ?"; params.add(collegeName); } - + if (StringUtils.isNotEmpty(majorName)) { sql += " AND major_name = ?"; params.add(majorName); } - - sql += " ORDER BY class_name"; - + + sql += " ORDER BY class_name, create_time DESC"; + try { List> fallbackResult = jdbcTemplate.queryForList(sql, params.toArray()); log.info("备用查询班级结果: {}", fallbackResult); - + if (fallbackResult != null && !fallbackResult.isEmpty()) { return fallbackResult; } } catch (Exception e) { log.error("备用查询班级数据异常", e); } - + // 如果仍然没有数据,添加测试数据(仅作为最后的备选方案) if (result.isEmpty()) { log.warn("未从数据库获取到班级数据,添加测试数据,collegeName={}, majorName={}", collegeName, majorName); - + // 根据院系和专业名称返回对应的班级 if ("信息工程学院".equals(collegeName)) { if ("计算机科学与技术".equals(majorName)) { @@ -1225,7 +1235,7 @@ if (statusObj != null) { option1.put("id", 1L); option1.put("name", "计算机2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 2L); option2.put("name", "计算机2302班"); @@ -1235,7 +1245,7 @@ if (statusObj != null) { option1.put("id", 3L); option1.put("name", "软件2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 4L); option2.put("name", "软件2302班"); @@ -1251,22 +1261,22 @@ if (statusObj != null) { option1.put("id", 1L); option1.put("name", "计算机2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 2L); option2.put("name", "计算机2302班"); result.add(option2); - + Map option3 = new HashMap<>(); option3.put("id", 3L); option3.put("name", "软件2301班"); result.add(option3); - + Map option4 = new HashMap<>(); option4.put("id", 4L); option4.put("name", "软件2302班"); result.add(option4); - + Map option5 = new HashMap<>(); option5.put("id", 5L); option5.put("name", "网络2301班"); @@ -1278,7 +1288,7 @@ if (statusObj != null) { option1.put("id", 6L); option1.put("name", "机械2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 7L); option2.put("name", "机械2302班"); @@ -1294,12 +1304,12 @@ if (statusObj != null) { option1.put("id", 6L); option1.put("name", "机械2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 7L); option2.put("name", "机械2302班"); result.add(option2); - + Map option3 = new HashMap<>(); option3.put("id", 8L); option3.put("name", "材料2301班"); @@ -1322,7 +1332,7 @@ if (statusObj != null) { option1.put("id", 9L); option1.put("name", "汉语2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 10L); option2.put("name", "英语2301班"); @@ -1334,47 +1344,47 @@ if (statusObj != null) { option1.put("id", 1L); option1.put("name", "计算机2301班"); result.add(option1); - + Map option2 = new HashMap<>(); option2.put("id", 2L); option2.put("name", "计算机2302班"); result.add(option2); - + Map option3 = new HashMap<>(); option3.put("id", 3L); option3.put("name", "软件2301班"); result.add(option3); - + Map option4 = new HashMap<>(); option4.put("id", 4L); option4.put("name", "软件2302班"); result.add(option4); - + Map option5 = new HashMap<>(); option5.put("id", 5L); option5.put("name", "网络2301班"); result.add(option5); - + Map option6 = new HashMap<>(); option6.put("id", 6L); option6.put("name", "机械2301班"); result.add(option6); - + Map option7 = new HashMap<>(); option7.put("id", 7L); option7.put("name", "机械2302班"); result.add(option7); - + Map option8 = new HashMap<>(); option8.put("id", 8L); option8.put("name", "材料2301班"); result.add(option8); - + Map option9 = new HashMap<>(); option9.put("id", 9L); option9.put("name", "汉语2301班"); result.add(option9); - + Map option10 = new HashMap<>(); option10.put("id", 10L); option10.put("name", "英语2301班"); @@ -1384,13 +1394,13 @@ if (statusObj != null) { } catch (Exception e) { log.error("获取班级选项异常", e); } - + return result; } /** * 将各种日期类型转换为java.util.Date - * + * * @param dateObj 日期对象,可能是LocalDateTime、LocalDate、Date或其他类型 * @return java.util.Date对象,如果转换失败则返回null */ @@ -1398,7 +1408,7 @@ if (statusObj != null) { if (dateObj == null) { return null; } - + try { if (dateObj instanceof Date) { return (Date) dateObj; @@ -1423,13 +1433,14 @@ if (statusObj != null) { } @Override - public TableDataInfo selectPageList(XljkConsultationAppointmentBo bo, PageQuery pageQuery) { + public TableDataInfo selectPageList(XljkConsultationAppointmentBo bo, + PageQuery pageQuery) { log.info("分页查询预约记录列表,页码: {}, 每页数量: {}", pageQuery.getPageNum(), pageQuery.getPageSize()); - + // 将变量定义移到try块外,确保catch块可以访问 StringBuilder sqlBuilder = new StringBuilder(); List params = new ArrayList<>(); - + try { // 构建查询条件 sqlBuilder.append("SELECT a.id, a.tenant_id, a.student_id, a.counselor_id, a.schedule_id, "); @@ -1451,53 +1462,53 @@ if (statusObj != null) { sqlBuilder.append("AND s.name LIKE ? "); params.add("%" + bo.getStudentName() + "%"); } - + if (bo.getStudentNo() != null && !bo.getStudentNo().isEmpty()) { sqlBuilder.append("AND s.student_no LIKE ? "); params.add("%" + bo.getStudentNo() + "%"); } - + if (bo.getCollegeName() != null && !bo.getCollegeName().isEmpty()) { sqlBuilder.append("AND s.college_name = ? "); params.add(bo.getCollegeName()); } - + if (bo.getMajorName() != null && !bo.getMajorName().isEmpty()) { sqlBuilder.append("AND s.major_name = ? "); params.add(bo.getMajorName()); } - + if (bo.getClassName() != null && !bo.getClassName().isEmpty()) { sqlBuilder.append("AND s.class_name = ? "); params.add(bo.getClassName()); } - + if (bo.getStatus() != null && !bo.getStatus().isEmpty()) { sqlBuilder.append("AND a.status = ? "); params.add(bo.getStatus()); } - - // 处理日期范围 - if (bo.getParams() != null) { - Map paramsMap = bo.getParams(); - if (paramsMap.get("beginAppointmentDate") != null) { - sqlBuilder.append("AND a.appointment_date >= ? "); - params.add(paramsMap.get("beginAppointmentDate")); + + // 处理日期范围 + if (bo.getParams() != null) { + Map paramsMap = bo.getParams(); + if (paramsMap.get("beginAppointmentDate") != null) { + sqlBuilder.append("AND a.appointment_date >= ? "); + params.add(paramsMap.get("beginAppointmentDate")); + } + + if (paramsMap.get("endAppointmentDate") != null) { + sqlBuilder.append("AND a.appointment_date <= ? "); + params.add(paramsMap.get("endAppointmentDate")); + } } - - if (paramsMap.get("endAppointmentDate") != null) { - sqlBuilder.append("AND a.appointment_date <= ? "); - params.add(paramsMap.get("endAppointmentDate")); - } - } - + // 添加排序 - sqlBuilder.append("ORDER BY a.create_time DESC, a.id DESC "); - + sqlBuilder.append("ORDER BY s.student_no DESC, a.id DESC, a.create_time DESC "); + // 计算总数 String countSql = "SELECT COUNT(*) FROM (" + sqlBuilder.toString() + ") t"; Long total = jdbcTemplate.queryForObject(countSql, params.toArray(), Long.class); - + if (total == null || total == 0) { TableDataInfo emptyResult = new TableDataInfo<>(); emptyResult.setRows(new ArrayList<>()); @@ -1506,23 +1517,23 @@ if (statusObj != null) { emptyResult.setMsg("查询成功"); return emptyResult; } - + // 添加分页 sqlBuilder.append("LIMIT ?, ?"); int offset = (pageQuery.getPageNum() - 1) * pageQuery.getPageSize(); params.add(offset); params.add(pageQuery.getPageSize()); - + log.info("执行SQL: {}", sqlBuilder.toString()); - + // 执行查询 List> resultMaps = jdbcTemplate.queryForList(sqlBuilder.toString(), params.toArray()); - + // 转换结果 List result = new ArrayList<>(); for (Map row : resultMaps) { XljkConsultationAppointmentVo vo = new XljkConsultationAppointmentVo(); - + // 设置主要字段 vo.setId(((Number) row.get("id")).longValue()); vo.setStudentId(((Number) row.get("student_id")).longValue()); @@ -1535,7 +1546,7 @@ if (statusObj != null) { vo.setAppointmentTime((String) row.get("appointment_time")); vo.setAppointmentDetailTime((String) row.get("appointment_detail_time")); vo.setReason((String) row.get("reason")); - + // 处理状态字段,确保类型正确 Object statusObj = row.get("status"); if (statusObj != null) { @@ -1555,25 +1566,25 @@ if (statusObj != null) { } else { vo.setStatus(0); // 默认待咨询状态 } - + vo.setCounselorName((String) row.get("counselor_name")); - + // 可选字段 if (row.get("counselor_id") != null) { vo.setCounselorId(((Number) row.get("counselor_id")).longValue()); } - + if (row.get("schedule_id") != null) { vo.setScheduleId(((Number) row.get("schedule_id")).longValue()); } - + if (row.get("communication_duration") != null) { vo.setCommunicationDuration(((Number) row.get("communication_duration")).intValue()); } - + vo.setConsultationContent((String) row.get("consultation_content")); vo.setCounselorSuggestion((String) row.get("counselor_suggestion")); - + // 新增字段映射 Object psychologicalHistoryObj = row.get("psychological_history"); if (psychologicalHistoryObj != null) { @@ -1587,11 +1598,11 @@ if (statusObj != null) { } } } - + vo.setPsychologicalHistoryDetail((String) row.get("psychological_history_detail")); vo.setBasicSituation((String) row.get("basic_situation")); vo.setMajorLifeEvents((String) row.get("major_life_events")); - + Object needReferralObj = row.get("need_referral"); if (needReferralObj != null) { if (needReferralObj instanceof Number) { @@ -1604,40 +1615,40 @@ if (statusObj != null) { } } } - + // 其他通用字段 if (row.get("create_by") != null) { vo.setCreateBy(((Number) row.get("create_by")).longValue()); } - + if (row.get("create_time") != null) { vo.setCreateTime(convertToDate(row.get("create_time"))); } - + if (row.get("update_by") != null) { vo.setUpdateBy(((Number) row.get("update_by")).longValue()); } - + if (row.get("update_time") != null) { vo.setUpdateTime(convertToDate(row.get("update_time"))); } - + // 计算本学期到访次数 if (vo.getStudentId() != null) { vo.setSemesterVisitCount(calculateSemesterVisitCount(vo.getStudentId())); } else { vo.setSemesterVisitCount(0); } - + result.add(vo); } - + TableDataInfo tableDataInfo = new TableDataInfo<>(); - tableDataInfo.setRows(result); - tableDataInfo.setTotal(total); - tableDataInfo.setCode(200); - tableDataInfo.setMsg("查询成功"); - return tableDataInfo; + tableDataInfo.setRows(result); + tableDataInfo.setTotal(total); + tableDataInfo.setCode(200); + tableDataInfo.setMsg("查询成功"); + return tableDataInfo; } catch (Exception e) { log.error("分页查询预约记录列表异常", e); log.error("SQL: {}", sqlBuilder.toString()); @@ -1650,51 +1661,52 @@ if (statusObj != null) { return emptyResult; } } - + @Override public List getCalendarSchedules(String startDate, String endDate) { try { // 1. 查询指定日期范围内的所有排班数据 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(XljkConsultationSchedule::getScheduleDate, startDate) - .le(XljkConsultationSchedule::getScheduleDate, endDate) - .eq(XljkConsultationSchedule::getStatus, "0") // 0表示正常可用 - .orderByAsc(XljkConsultationSchedule::getScheduleDate) - .orderByAsc(XljkConsultationSchedule::getTimeSlot) - .orderByAsc(XljkConsultationSchedule::getStartTime); + .le(XljkConsultationSchedule::getScheduleDate, endDate) + .eq(XljkConsultationSchedule::getStatus, "0") // 0表示正常可用 + .orderByAsc(XljkConsultationSchedule::getScheduleDate) + .orderByAsc(XljkConsultationSchedule::getTimeSlot) + .orderByAsc(XljkConsultationSchedule::getStartTime); List schedules = scheduleMapper.selectList(queryWrapper); - + if (schedules.isEmpty()) { return new ArrayList<>(); } // 2. 查询该日期范围内的所有预约记录 - List scheduleIds = schedules.stream().map(XljkConsultationSchedule::getId).collect(Collectors.toList()); + List scheduleIds = schedules.stream().map(XljkConsultationSchedule::getId) + .collect(Collectors.toList()); LambdaQueryWrapper appointmentQueryWrapper = new LambdaQueryWrapper<>(); appointmentQueryWrapper.in(XljkConsultationAppointment::getScheduleId, scheduleIds) - .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1", "4")); // 待咨询、已完成或待审核的 - + .in(XljkConsultationAppointment::getStatus, Arrays.asList("0", "1", "4")); // 待咨询、已完成或待审核的 + List appointments = mapper.selectList(appointmentQueryWrapper); - + // 3. 构建排班ID到预约记录的映射 Map> appointmentMap = appointments.stream() - .collect(Collectors.groupingBy(XljkConsultationAppointment::getScheduleId)); + .collect(Collectors.groupingBy(XljkConsultationAppointment::getScheduleId)); // 4. 获取咨询师信息映射 Map counselorMap = getCounselorNameMap(); - + // 5. 获取当前时间 Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); - + // 6. 构建结果列表 List result = new ArrayList<>(); - + for (XljkConsultationSchedule schedule : schedules) { ScheduleWithStatusVo vo = new ScheduleWithStatusVo(); - + // 基本信息 vo.setScheduleId(schedule.getId()); vo.setCounselorId(schedule.getCounselorId()); @@ -1703,131 +1715,136 @@ if (statusObj != null) { vo.setTimeSlot(schedule.getTimeSlot()); vo.setStartTime(schedule.getStartTime()); vo.setEndTime(schedule.getEndTime()); - + // 构建时段显示文本 String timeSlotText = getTimeSlotText(schedule.getTimeSlot()); vo.setTimeDisplay(timeSlotText + " " + schedule.getStartTime() + "-" + schedule.getEndTime()); - + // 计算预约状态 List scheduleAppointments = appointmentMap.get(schedule.getId()); int bookedCount = scheduleAppointments != null ? scheduleAppointments.size() : 0; - + // 每个时段只能预约1个人(无论时段长度) // 生成30分钟时段用于详细时段显示,但总预约数量固定为1 - List timeSlots = TimeSlotUtils.generateTimeSlots(schedule.getStartTime(), schedule.getEndTime()); + List timeSlots = TimeSlotUtils.generateTimeSlots(schedule.getStartTime(), + schedule.getEndTime()); int totalSlots = 1; // 每个时段只能预约1个人 - + vo.setTotalSlots(totalSlots); vo.setAvailableSlots(Math.max(0, totalSlots - bookedCount)); vo.setIsFullyBooked(bookedCount >= totalSlots); - + // 检查是否已过期 boolean isExpired = false; try { Date scheduleDate = schedule.getScheduleDate(); Calendar calendar = Calendar.getInstance(); calendar.setTime(scheduleDate); - + // 设置具体的结束时间 String[] endTimeParts = schedule.getEndTime().split(":"); calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(endTimeParts[0])); calendar.set(Calendar.MINUTE, Integer.parseInt(endTimeParts[1])); calendar.set(Calendar.SECOND, 0); - + Date scheduleEndTime = calendar.getTime(); isExpired = scheduleEndTime.before(now); } catch (Exception e) { log.warn("检查时段过期状态失败: " + schedule.getId(), e); } - + vo.setIsExpired(isExpired); - + // 设置基础字段 vo.setCreateBy(schedule.getCreateBy()); vo.setCreateTime(schedule.getCreateTime()); vo.setUpdateBy(schedule.getUpdateBy()); vo.setUpdateTime(schedule.getUpdateTime()); - + result.add(vo); } - + return result; - + } catch (Exception e) { log.error("获取日历排班数据失败", e); return new ArrayList<>(); } } - + /** * 获取时段类型文本 */ private String getTimeSlotText(String timeSlot) { switch (timeSlot) { - case "0": return "中午"; - case "1": return "下午"; - case "2": return "晚上"; - default: return "未知"; + case "0": + return "中午"; + case "1": + return "下午"; + case "2": + return "晚上"; + default: + return "未知"; } } - + /** * 获取咨询师名称映射 */ private Map getCounselorNameMap() { try { Map counselorMap = new HashMap<>(); - + // 1. 查询所有已创建排班的咨询师ID LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.select(XljkConsultationSchedule::getCounselorId) - .eq(XljkConsultationSchedule::getStatus, "0") // 只查询正常状态的 - .groupBy(XljkConsultationSchedule::getCounselorId); // 去重 - + .eq(XljkConsultationSchedule::getStatus, "0") // 只查询正常状态的 + .groupBy(XljkConsultationSchedule::getCounselorId); // 去重 + List schedules = scheduleMapper.selectList(queryWrapper); if (schedules.isEmpty()) { return counselorMap; } - + // 2. 提取咨询师ID列表 List counselorIds = schedules.stream() - .map(XljkConsultationSchedule::getCounselorId) - .filter(Objects::nonNull) - .distinct() - .collect(Collectors.toList()); - + .map(XljkConsultationSchedule::getCounselorId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (counselorIds.isEmpty()) { return counselorMap; } - + // 3. 批量查询咨询师信息 List counselors = userService.selectUserByIds(counselorIds, null); - + // 4. 构建ID到姓名的映射 counselorMap = counselors.stream() - .filter(user -> user.getUserId() != null) - .collect(Collectors.toMap( - SysUserVo::getUserId, - user -> { - // 优先使用昵称,如果没有昵称则使用用户名 - String name = user.getNickName(); - if (StringUtils.isBlank(name)) { - name = user.getUserName(); - } - if (StringUtils.isBlank(name)) { - name = "未知咨询师"; - } - return name; - }, - (existing, replacement) -> existing // 如果ID重复,保留第一个 - )); - + .filter(user -> user.getUserId() != null) + .collect(Collectors.toMap( + SysUserVo::getUserId, + user -> { + // 优先使用昵称,如果没有昵称则使用用户名 + String name = user.getNickName(); + if (StringUtils.isBlank(name)) { + name = user.getUserName(); + } + if (StringUtils.isBlank(name)) { + name = "未知咨询师"; + } + return name; + }, + (existing, replacement) -> existing // 如果ID重复,保留第一个 + )); + log.info("成功加载咨询师信息映射,共{}个咨询师", counselorMap.size()); return counselorMap; - + } catch (Exception e) { log.error("获取咨询师信息失败", e); return new HashMap<>(); } } -} \ No newline at end of file +} diff --git a/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationNoShowServiceImpl.java b/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationNoShowServiceImpl.java index 52299f1f..bce51b07 100644 --- a/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationNoShowServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xljk/src/main/java/org/dromara/xljk/service/impl/XljkConsultationNoShowServiceImpl.java @@ -48,37 +48,39 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho sqlBuilder.append("LEFT JOIN xljk_consultation_appointment a ON ns.appointment_id = a.id "); sqlBuilder.append("LEFT JOIN sys_user u ON a.counselor_id = u.user_id "); sqlBuilder.append("WHERE ns.id = ? AND ns.deleted = 0"); - + List> resultList = jdbcTemplate.queryForList(sqlBuilder.toString(), id); - - if (resultList.isEmpty()) return null; - + + if (resultList.isEmpty()) + return null; + Map row = resultList.get(0); XljkConsultationNoShowVo vo = new XljkConsultationNoShowVo(); - + // 设置基本字段 vo.setId(((Number) row.get("id")).longValue()); vo.setStudentId(row.get("student_id") != null ? ((Number) row.get("student_id")).longValue() : null); - vo.setAppointmentId(row.get("appointment_id") != null ? ((Number) row.get("appointment_id")).longValue() : null); + vo.setAppointmentId( + row.get("appointment_id") != null ? ((Number) row.get("appointment_id")).longValue() : null); vo.setNoShowDate(convertToDate(row.get("no_show_date"))); vo.setExpireDate(convertToDate(row.get("expire_date"))); vo.setStatus((String) row.get("status")); vo.setCreateTime(convertToDate(row.get("create_time"))); vo.setUpdateTime(convertToDate(row.get("update_time"))); - + // 设置学生相关信息 vo.setStudentName((String) row.get("student_name")); vo.setStudentNo((String) row.get("student_no")); vo.setClassName((String) row.get("class_name")); vo.setCollegeName((String) row.get("college_name")); vo.setMajorName((String) row.get("major_name")); - + // 设置预约相关信息 - vo.setCounselorName((String) row.get("counselor_name")); // 从counselor表获取咨询师姓名 + vo.setCounselorName((String) row.get("counselor_name")); // 从counselor表获取咨询师姓名 vo.setAppointmentDate(convertToDate(row.get("appointment_date"))); vo.setAppointmentDetailTime((String) row.get("appointment_detail_time")); vo.setReason((String) row.get("reason")); - + return vo; } @@ -91,30 +93,30 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho sqlBuilder.append("FROM xljk_consultation_no_show ns "); sqlBuilder.append("LEFT JOIN xg_student_msg s ON ns.student_id = s.id "); sqlBuilder.append("WHERE ns.deleted = 0 "); - + List params = new ArrayList<>(); - + // 添加查询条件 if (bo.getStudentId() != null) { sqlBuilder.append("AND ns.student_id = ? "); params.add(bo.getStudentId()); } - + if (StringUtils.isNotBlank(bo.getStudentName())) { sqlBuilder.append("AND s.name LIKE ? "); params.add("%" + bo.getStudentName() + "%"); } - + if (StringUtils.isNotBlank(bo.getStudentNo())) { sqlBuilder.append("AND s.student_no LIKE ? "); params.add("%" + bo.getStudentNo() + "%"); } - + if (StringUtils.isNotBlank(bo.getStatus())) { sqlBuilder.append("AND ns.status = ? "); params.add(bo.getStatus()); } - + // 处理日期范围 if (bo.getParams() != null) { Object startDateObj = bo.getParams().get("startDate"); @@ -123,7 +125,7 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho params.add(startDateObj.toString()); log.info("添加开始日期查询条件: {}", startDateObj); } - + Object endDateObj = bo.getParams().get("endDate"); if (endDateObj != null && StringUtils.isNotBlank(endDateObj.toString())) { sqlBuilder.append("AND DATE(ns.no_show_date) <= DATE(?) "); @@ -131,34 +133,35 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho log.info("添加结束日期查询条件: {}", endDateObj); } } - - // 添加排序,首先按未到访日期倒序,其次按创建时间倒序 - sqlBuilder.append("ORDER BY ns.no_show_date DESC, ns.create_time DESC"); - + + // 添加排序,首先按学号降序,其次按未到访日期和创建时间倒序 + sqlBuilder.append("ORDER BY s.student_no DESC, ns.no_show_date DESC, ns.create_time DESC"); + // 执行查询 List> resultList = jdbcTemplate.queryForList(sqlBuilder.toString(), params.toArray()); - + // 转换为VO对象 return resultList.stream().map(row -> { XljkConsultationNoShowVo vo = new XljkConsultationNoShowVo(); - + // 设置基本字段 vo.setId(((Number) row.get("id")).longValue()); vo.setStudentId(row.get("student_id") != null ? ((Number) row.get("student_id")).longValue() : null); - vo.setAppointmentId(row.get("appointment_id") != null ? ((Number) row.get("appointment_id")).longValue() : null); + vo.setAppointmentId( + row.get("appointment_id") != null ? ((Number) row.get("appointment_id")).longValue() : null); vo.setNoShowDate(convertToDate(row.get("no_show_date"))); vo.setExpireDate(convertToDate(row.get("expire_date"))); vo.setStatus((String) row.get("status")); vo.setCreateTime(convertToDate(row.get("create_time"))); vo.setUpdateTime(convertToDate(row.get("update_time"))); - + // 设置关联信息 vo.setStudentName((String) row.get("student_name")); vo.setStudentNo((String) row.get("student_no")); vo.setClassName((String) row.get("class_name")); vo.setCollegeName((String) row.get("college_name")); vo.setMajorName((String) row.get("major_name")); - + return vo; }).collect(Collectors.toList()); } @@ -181,26 +184,26 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho public boolean deleteById(Long id) { return mapper.deleteById(id) > 0; } - + @Override public Map checkLimitation(Long studentId) { Map result = new HashMap<>(); result.put("limited", false); - + try { // 查询是否有生效中的限制 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(XljkConsultationNoShow::getStudentId, studentId) - .eq(XljkConsultationNoShow::getStatus, "0") // 0-生效中 - .eq(XljkConsultationNoShow::getDeleted, 0) - .orderByDesc(XljkConsultationNoShow::getCreateTime); - + .eq(XljkConsultationNoShow::getStatus, "0") // 0-生效中 + .eq(XljkConsultationNoShow::getDeleted, 0) + .orderByDesc(XljkConsultationNoShow::getCreateTime); + XljkConsultationNoShow noShow = mapper.selectOne(queryWrapper); - + if (noShow != null) { Date now = new Date(); Date expireDate = noShow.getExpireDate(); - + // 如果限制已过期,更新状态 if (expireDate != null && now.after(expireDate)) { log.info("学生{}的预约限制已过期,自动更新状态", studentId); @@ -210,7 +213,7 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho // 限制仍在生效期内 result.put("limited", true); result.put("expireDate", expireDate); - + // 格式化日期为字符串 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); result.put("expireDateStr", sdf.format(expireDate)); @@ -219,10 +222,10 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho } catch (Exception e) { log.error("检查预约限制失败", e); } - + return result; } - + @Override @Transactional public boolean releaseLimitation(Long id) { @@ -232,7 +235,7 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho log.warn("未找到ID为{}的未到访记录", id); return false; } - + // 只有生效中的限制才能解除 if ("0".equals(noShow.getStatus())) { noShow.setStatus("2"); // 2-已解除 @@ -248,7 +251,7 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho return false; } } - + @Override @Transactional public boolean createNoShowRecord(Long studentId, Long appointmentId, Date noShowDate) { @@ -258,20 +261,20 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho noShow.setStudentId(studentId); noShow.setAppointmentId(appointmentId); noShow.setNoShowDate(noShowDate); - + // 检查30天内未到访次数 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, -30); Date thirtyDaysAgo = calendar.getTime(); - + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(XljkConsultationNoShow::getStudentId, studentId) - .ge(XljkConsultationNoShow::getNoShowDate, thirtyDaysAgo) - .eq(XljkConsultationNoShow::getDeleted, 0); - + .ge(XljkConsultationNoShow::getNoShowDate, thirtyDaysAgo) + .eq(XljkConsultationNoShow::getDeleted, 0); + long count = mapper.selectCount(queryWrapper); log.info("学生{}在30天内未到访次数: {}", studentId, count); - + // 如果达到3次,设置限制(包括本次) if (count >= 2) { // 已有2次,加上本次就是3次 log.info("学生{}达到3次未到访,设置预约限制", studentId); @@ -280,11 +283,11 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho calendar.setTime(noShowDate); calendar.add(Calendar.DAY_OF_MONTH, 7); Date expireDate = calendar.getTime(); - + noShow.setExpireDate(expireDate); noShow.setStatus("0"); // 0-生效中 } - + // 保存未到访记录 mapper.insert(noShow); log.info("创建未到访记录成功: {}", noShow); @@ -294,25 +297,25 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho return false; } } - + @Override @Transactional public int updateExpiredLimitations() { log.info("开始检查过期的预约限制"); int count = 0; - + try { Date now = new Date(); - + // 查询所有生效中但已过期的限制 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(XljkConsultationNoShow::getStatus, "0") // 0-生效中 - .lt(XljkConsultationNoShow::getExpireDate, now) // 过期日期早于当前日期 - .eq(XljkConsultationNoShow::getDeleted, 0); - + .lt(XljkConsultationNoShow::getExpireDate, now) // 过期日期早于当前日期 + .eq(XljkConsultationNoShow::getDeleted, 0); + List expiredList = mapper.selectList(queryWrapper); log.info("找到{}条已过期的预约限制", expiredList.size()); - + // 批量更新状态为已过期 for (XljkConsultationNoShow noShow : expiredList) { noShow.setStatus("1"); // 1-已过期 @@ -323,13 +326,13 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho } catch (Exception e) { log.error("更新过期预约限制失败", e); } - + return count; } /** * 将各种日期类型转换为java.util.Date - * + * * @param dateObj 日期对象,可能是LocalDateTime、LocalDate、Date或其他类型 * @return java.util.Date对象,如果转换失败则返回null */ @@ -337,7 +340,7 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho if (dateObj == null) { return null; } - + try { if (dateObj instanceof Date) { return (Date) dateObj; @@ -360,4 +363,4 @@ public class XljkConsultationNoShowServiceImpl implements IXljkConsultationNoSho return null; } } -} \ No newline at end of file +} diff --git a/backend/ruoyi-modules/ruoyi-xljk/src/main/resources/mapper/xljk/XljkSystemQueryMapper.xml b/backend/ruoyi-modules/ruoyi-xljk/src/main/resources/mapper/xljk/XljkSystemQueryMapper.xml index af24ec24..ec156779 100644 --- a/backend/ruoyi-modules/ruoyi-xljk/src/main/resources/mapper/xljk/XljkSystemQueryMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xljk/src/main/resources/mapper/xljk/XljkSystemQueryMapper.xml @@ -6,38 +6,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - SELECT DISTINCT major_id as id, major_name as name - FROM xg_class_msg + SELECT DISTINCT major_id as id, major_name as name + FROM xg_class_msg WHERE major_name IS NOT NULL AND college_name = #{collegeName} @@ -56,8 +56,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - SELECT id, class_name as name - FROM xg_class_msg + SELECT id, class_name as name + FROM xg_class_msg WHERE class_name IS NOT NULL AND college_name = #{collegeName} @@ -78,14 +78,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND major_name = #{majorName} + ORDER BY class_name, create_time DESC - \ No newline at end of file + diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml index 18e6125c..356face0 100644 --- a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml @@ -60,7 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and (student_no like concat('%', #{keyword}, '%') or name like concat('%', #{keyword}, '%')) - order by student_no + order by student_no desc limit ${(pageNum - 1) * pageSize}, #{pageSize, jdbcType=INTEGER} diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml index 1d78d650..9eaec6ad 100644 --- a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml @@ -97,7 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and (student_no like concat('%', #{keyword}, '%') or name like concat('%', #{keyword}, '%')) - order by name asc + order by student_no desc limit 50 diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentInfoMapper.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentInfoMapper.java index 877d1e19..f85d5969 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentInfoMapper.java +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentInfoMapper.java @@ -39,7 +39,7 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus> groupByMajor(); /** @@ -47,7 +47,7 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus> groupByRegion(); /** @@ -55,7 +55,7 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus> countByGenderList(); /** @@ -82,7 +82,7 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus= DATE_SUB(CURDATE(), INTERVAL #{days} DAY) AND deleted = 0 GROUP BY DATE_FORMAT(create_time, '%Y-%m-%d') ORDER BY date") + @Select("SELECT DATE_FORMAT(create_time, '%Y-%m-%d') as date, COUNT(id) as count FROM zsjy_enrollment_info WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL #{days} DAY) AND deleted = 0 GROUP BY DATE_FORMAT(create_time, '%Y-%m-%d') ORDER BY date DESC, MAX(create_time) DESC") List> countByDateRange(@Param("days") Integer days); /** @@ -110,7 +110,8 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByYear( @Param("startDate") Date startDate, @@ -142,7 +143,7 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByMonth( @Param("startDate") Date startDate, @@ -174,7 +175,8 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByDay( @Param("startDate") Date startDate, @@ -207,7 +209,8 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByMajor( @Param("startDate") Date startDate, @@ -241,7 +244,8 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByRegion( @Param("startDate") Date startDate, @@ -273,7 +277,8 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByGender( @Param("startDate") Date startDate, @@ -315,7 +320,8 @@ public interface ZsjyEnrollmentInfoMapper extends BaseMapperPlus statisticsByStatus( @Param("startDate") Date startDate, diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentProcessMapper.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentProcessMapper.java index 314a5f88..2d196254 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentProcessMapper.java +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyEnrollmentProcessMapper.java @@ -54,7 +54,8 @@ public interface ZsjyEnrollmentProcessMapper extends BaseMapperPlus> countByStatusList(); @@ -82,7 +83,7 @@ public interface ZsjyEnrollmentProcessMapper extends BaseMapperPlus selectMyAuditList(@Param("userId") Long userId); /** diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml index 7a42d5f0..2dae10a7 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml @@ -153,7 +153,7 @@ resultMap="InternshipInfoVOResult"> - ORDER BY s.class_name, s.student_no + ORDER BY s.student_no DESC, s.class_name, s.create_time DESC @@ -176,7 +176,7 @@ AND c.class_status = '1' AND c.class_teacher_id = #{teacherId} AND c.tenant_id = '000000' - ORDER BY c.grade DESC, c.class_name + ORDER BY c.grade DESC, c.class_name, c.create_time DESC diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipMonthlyMapper.xml b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipMonthlyMapper.xml index 092e5fce..53662a7b 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipMonthlyMapper.xml +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipMonthlyMapper.xml @@ -335,7 +335,7 @@ AND m.submit_time <= #{bo.submitTimeEnd} - ORDER BY m.review_time DESC, m.submit_time DESC + ORDER BY m.review_time DESC, m.submit_time DESC, m.create_time DESC diff --git a/docs/开发文档/API/API.md.backup-20250701-163220 b/docs/开发文档/API/API.md.backup-20250701-163220 index 419203e4..473956c1 100644 --- a/docs/开发文档/API/API.md.backup-20250701-163220 +++ b/docs/开发文档/API/API.md.backup-20250701-163220 @@ -1447,6 +1447,8 @@ admin 用户具有系统最高权限 `*:*:*`,可以访问所有功能模块和 **权限要求**: `pm:repairOrder:assign` +**排序规则**: 返回的维修人员选项按用户名(`user_name`)升序排列,便于快速定位目标用户 + **请求参数**: 无 **响应示例**: diff --git a/docs/开发文档/API/API文档基础规范.md b/docs/开发文档/API/API文档基础规范.md index d5820838..66f204fa 100644 --- a/docs/开发文档/API/API文档基础规范.md +++ b/docs/开发文档/API/API文档基础规范.md @@ -198,6 +198,8 @@ 4. **单条数据接口必须使用 R 类型包装返回结果** 5. **操作类接口必须使用 R 类型包装返回结果** 6. **必须包含 clientid、Content-Type 等必要请求头** +7. **查询类接口默认按创建时间倒序排列,若已有排序字段则在末尾追加 `create_time DESC` 保证新增数据优先展示** +7. **所有列表查询接口默认按 `create_time` 倒序排列;如接口自定义其他排序字段,必须在末尾追加 `create_time desc` 作为稳定排序项** --- diff --git a/docs/开发文档/API/API文档总览.md b/docs/开发文档/API/API文档总览.md index c947f27d..8f78b7ee 100644 --- a/docs/开发文档/API/API文档总览.md +++ b/docs/开发文档/API/API文档总览.md @@ -121,9 +121,17 @@ - `student_status = '1'` (在籍状态) - `class_id = 入参的classId` (班级ID) - `name LIKE '%入参的name%'` (姓名模糊查询,可选) -- **排序方式**: 按创建时间倒序排列 +- **排序方式**: 按学号降序排列 +- **最新变更**(2025-11-13): 所有学生信息列表接口默认按学号降序排序,便于优先查看学号靠后的学生 - **权限要求**: `studentMsg:studentMsg:query` +### 2025-11-13 - 学生列表排序策略统一 +- **心理健康测评**: `GET /xljk/evaluation/detail/students/{classId}` 现在按学号降序返回班级学生,满足最新业务要求 +- **学生考核奖励**: 学生候选下拉接口默认按学号降序排列,保持后台与移动端行为一致 +- **心理咨询预约**: 预约记录列表接口默认按学号降序,随后按ID降序排序,并以创建时间倒序兜底保证顺序稳定 +- **预约限制功能**: 未到访记录分页默认先按学号降序,再按未到访日期、创建时间倒序 +- **学生信息批次收集**: 批次学生列表默认按学号降序,当学号一致时以创建时间倒序作为补充 + ### 2025-07-24 - 学生信息管理界面重构 - **界面重构**: 学生信息管理新增弹窗调整为多tab页形式 - **功能增强**: 新增照片上传功能,支持完整的学生信息录入 diff --git a/docs/开发文档/API/出国申请管理API.md b/docs/开发文档/API/出国申请管理API.md index 9dc134e8..7cc420f4 100644 --- a/docs/开发文档/API/出国申请管理API.md +++ b/docs/开发文档/API/出国申请管理API.md @@ -90,6 +90,7 @@ - `rs:overseas:approve3` - 第3级:纪委审批权限 - `rs:overseas:approve4` - 第4级:学院分管领导审批权限 - `rs:overseas:approve5` - 第5级:学院党委书记审批权限 +- **数据返回顺序**:审批人下拉接口(`/system/user/list-by-permission`)默认按用户名(`user_name`)升序排序,确保审批人选择器顺序一致(2025-11-13) - **权限使用说明**: - 审批接口采用 **OR模式**,用户拥有以上任一权限即可调用接口 diff --git a/docs/开发文档/API/后勤满意度调查API.md b/docs/开发文档/API/后勤满意度调查API.md index 6f1de537..22e4fd5a 100644 --- a/docs/开发文档/API/后勤满意度调查API.md +++ b/docs/开发文档/API/后勤满意度调查API.md @@ -63,6 +63,7 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... | `/hq/satSurvey/{ids}` | DELETE | 删除问卷 | hq:satSurvey:remove | | `/hq/satSurvey/publish/{id}` | PUT | 发布问卷 | hq:satSurvey:publish | | `/hq/satQuestion/list` | GET | 查询题目列表 | hq:satQuestion:list | +> 📌 **排序策略更新(2025-11-13)**:题目列表在按指定字段排序时,会额外追加 `createTime DESC` 作为最后一位兜底排序,确保返回结果顺序稳定。 | `/hq/satQuestion/{id}` | GET | 获取题目详情 | hq:satQuestion:query | | `/hq/satQuestion` | POST | 新增题目 | hq:satQuestion:add | | `/hq/satQuestion` | PUT | 修改题目 | hq:satQuestion:edit | @@ -452,6 +453,7 @@ await Promise.all(promises); | 1.0.3 | 2025-07-17 | 添加选项保存防重复提交机制,解决幂等性控制冲突 | wuzilong | | 1.0.4 | 2025-07-18 | 优化问答题文本回答展示功能,提高Vue渲染稳定性 | wuzilong | | 1.0.5 | 2025-07-18 | 增强问卷答题记录接口功能,返回答题详情数据 | wuzilong | +| 1.0.6 | 2025-11-13 | 调整题目列表排序策略,追加创建时间倒序兜底,避免排序不稳定 | Cursor | ## 附录 diff --git a/docs/开发文档/API/学生信息批次收集API.md b/docs/开发文档/API/学生信息批次收集API.md index 8a37dea4..b4735a11 100644 --- a/docs/开发文档/API/学生信息批次收集API.md +++ b/docs/开发文档/API/学生信息批次收集API.md @@ -187,6 +187,8 @@ } ``` +> 📌 **排序说明**:分页列表默认按照学号 `studentNo` 降序排序;若学号相同,则继续按照 `createTime` 降序排列,确保最新学号优先展示。 + ### 2. 导出学生信息批次收集列表 - **接口路径**: POST `/studentMsgBatch/studentMsgBatch/export` diff --git a/docs/开发文档/API/心理健康测评API.md b/docs/开发文档/API/心理健康测评API.md index 26335476..9e75d815 100644 --- a/docs/开发文档/API/心理健康测评API.md +++ b/docs/开发文档/API/心理健康测评API.md @@ -489,6 +489,7 @@ - **接口URL**:/xljk/evaluation/detail/students/{classId} - **请求方式**:GET - **接口权限**:xljk:evaluation:query +- **排序方式**:按学号 `studentNo` 降序返回,确保默认展示最新学号 - **请求参数**: | 参数名 | 类型 | 是否必须 | 描述 | diff --git a/docs/开发文档/API/用户认证登录API.md b/docs/开发文档/API/用户认证登录API.md index eb32686b..9147c439 100644 --- a/docs/开发文档/API/用户认证登录API.md +++ b/docs/开发文档/API/用户认证登录API.md @@ -731,7 +731,7 @@ methods: { 1. 该接口需要用户登录后才能访问 2. 返回的用户信息已过滤敏感字段 3. 建议前端对结果进行缓存,避免频繁请求 -4. 返回结果按照用户ID升序排序 +4. 返回结果按照用户名(`user_name`)升序排序 ### 使用示例 ```typescript @@ -750,3 +750,66 @@ async function getAuditors() { } } ``` + +## 根据部门获取用户列表 + +### 基本信息 +- **接口URL**: `/system/user/list/dept/{deptId}` +- **请求方式**: GET +- **接口描述**: 根据部门ID获取该部门下所有启用状态的用户,用于部门人员选择器 +- **权限标识**: `system:user:list` + +### 路径参数 +| 参数名 | 类型 | 是否必须 | 说明 | 示例值 | +|--------|------|----------|------|--------| +| deptId | number | 是 | 部门ID | 1001 | + +### 响应参数 +```typescript +{ + code: number; + msg: string; + data: { + userId: number; + userName: string; + nickName: string; + phonenumber: string; + }[]; +} +``` + +### 注意事项 +1. 只返回未删除且状态为正常的用户 +2. 返回结果按照用户名(`user_name`)升序排序,便于快速定位 + +## 批量获取用户基础信息 + +### 基本信息 +- **接口URL**: `/system/user/optionselect` +- **请求方式**: GET +- **接口描述**: 根据用户ID集合(可选)和部门ID(可选)批量获取基础用户信息 +- **权限标识**: `system:user:query` + +### Query参数 +| 参数名 | 类型 | 是否必须 | 说明 | 示例值 | +|--------|------|----------|------|--------| +| userIds | string | 否 | 逗号分隔的用户ID集合 | 1,2,3 | +| deptId | number | 否 | 指定部门ID时仅返回该部门用户 | 1001 | + +### 响应参数 +```typescript +{ + code: number; + msg: string; + data: { + userId: number; + userName: string; + nickName: string; + phonenumber: string; + }[]; +} +``` + +### 注意事项 +1. 用户ID集合为空时返回有权限范围内的全部用户 +2. 返回结果默认按照用户名(`user_name`)升序排序,保持前端下拉展示一致性 diff --git a/docs/开发文档/API/预约限制功能API.md b/docs/开发文档/API/预约限制功能API.md index 56b575aa..f55c2bbd 100644 --- a/docs/开发文档/API/预约限制功能API.md +++ b/docs/开发文档/API/预约限制功能API.md @@ -57,6 +57,8 @@ } ``` +> 📌 **排序说明**:列表结果默认按照学号 `studentNo` 降序排列;当学号相同或为空时,继续按照未到访日期、创建时间倒序展示。 + ### 3.2 获取未到访记录详情 #### 接口信息 diff --git a/web/src/views/xg/xsjcxx/stuRoster/index.vue b/web/src/views/xg/xsjcxx/stuRoster/index.vue index 6e4a5004..fe7eb613 100644 --- a/web/src/views/xg/xsjcxx/stuRoster/index.vue +++ b/web/src/views/xg/xsjcxx/stuRoster/index.vue @@ -11,6 +11,13 @@ +
+ 班级状态: + + 全部班级 + {{ normalClassStatusLabel }} + +
+ > + + @@ -295,16 +317,19 @@