feat(xg): 新增按学号重置学生密码(Web/移动端)
学工老师可按学号查询并重置学生登录密码为固定默认值,独立权限不复用系统用户重置。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
0765f00458
commit
df4c21bd0d
14 files changed
+781
No files matched your search
+24
@@ -44,6 +44,7 @@ import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.xg.domain.vo.XgStudentMsgVo;
|
||||
import org.dromara.xg.domain.vo.StudentPwdResetVo;
|
||||
import org.dromara.xg.domain.bo.XgStudentMsgBo;
|
||||
import org.dromara.xg.domain.bo.XgStudentMsgAdvancedSearchBo;
|
||||
import org.dromara.xg.service.IXgStudentMsgService;
|
||||
@@ -660,6 +661,29 @@ public class XgStudentMsgController extends BaseController {
|
||||
return R.ok(studentInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按学号查询学生基本信息(重置密码页)
|
||||
* 须声明在 /{id} 之前,避免被路径变量吞掉
|
||||
*/
|
||||
@SaCheckPermission("studentMsg:studentPwdReset:query")
|
||||
@GetMapping("/queryByStudentNo/{studentNo}")
|
||||
public R<StudentPwdResetVo> queryByStudentNo(
|
||||
@NotBlank(message = "学号不能为空") @PathVariable("studentNo") String studentNo) {
|
||||
return R.ok(xgStudentMsgService.queryForPwdResetByStudentNo(studentNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按学号重置学生登录密码为固定默认值
|
||||
*/
|
||||
@SaCheckPermission("studentMsg:studentPwdReset:reset")
|
||||
@Log(title = "重置学生密码", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/resetStudentPassword/{studentNo}")
|
||||
public R<Void> resetStudentPassword(
|
||||
@NotBlank(message = "学号不能为空") @PathVariable("studentNo") String studentNo) {
|
||||
return toAjax(xgStudentMsgService.resetStudentPasswordByStudentNo(studentNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取学生信息详细信息
|
||||
*
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package org.dromara.xg.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 重置学生密码:按学号查询展示信息
|
||||
*/
|
||||
@Data
|
||||
public class StudentPwdResetVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 学生ID(与 sys_user.user_id 相同) */
|
||||
private Long id;
|
||||
|
||||
/** 学号 */
|
||||
private String studentNo;
|
||||
|
||||
/** 姓名 */
|
||||
private String name;
|
||||
|
||||
/** 班级名称 */
|
||||
private String className;
|
||||
|
||||
/** 班主任姓名 */
|
||||
private String classTeacherName;
|
||||
}
|
||||
+17
@@ -3,6 +3,7 @@ package org.dromara.xg.service;
|
||||
import org.dromara.xg.domain.vo.XgStudentMsgExportVo;
|
||||
import org.dromara.xg.domain.vo.XgStudentMsgVo;
|
||||
import org.dromara.xg.domain.vo.XgStudentTreeVo;
|
||||
import org.dromara.xg.domain.vo.StudentPwdResetVo;
|
||||
import org.dromara.xg.domain.bo.XgStudentMsgBo;
|
||||
import org.dromara.xg.domain.bo.XgStudentMsgAdvancedSearchBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -176,4 +177,20 @@ public interface IXgStudentMsgService {
|
||||
* @return 学生信息树
|
||||
*/
|
||||
List<XgStudentTreeVo> getCurrentUserStudentTree();
|
||||
|
||||
/**
|
||||
* 按学号查询学生基本信息(重置密码页展示)
|
||||
*
|
||||
* @param studentNo 学号
|
||||
* @return 姓名/学号/班级/班主任
|
||||
*/
|
||||
StudentPwdResetVo queryForPwdResetByStudentNo(String studentNo);
|
||||
|
||||
/**
|
||||
* 按学号重置学生登录密码为固定默认值
|
||||
*
|
||||
* @param studentNo 学号
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean resetStudentPasswordByStudentNo(String studentNo);
|
||||
}
|
||||
+77
@@ -25,6 +25,8 @@ import org.dromara.system.mapper.SysDeptMapper;
|
||||
import org.dromara.system.domain.bo.SysUserBo;
|
||||
import org.dromara.system.domain.SysDept;
|
||||
import org.dromara.system.domain.vo.SysDeptVo;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
import org.dromara.xg.domain.vo.StudentPwdResetVo;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import java.util.List;
|
||||
@@ -1557,4 +1559,79 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
|
||||
private Long getCurrentUserCollegeId() {
|
||||
return currentUserCollegeHelper.resolveCurrentUserCollegeId();
|
||||
}
|
||||
|
||||
/** 学生账号重置密码固定值(仅用于管理端重置学生密码) */
|
||||
private static final String STUDENT_RESET_PASSWORD = "Hzdyjsxs123456!@#";
|
||||
|
||||
@Override
|
||||
public StudentPwdResetVo queryForPwdResetByStudentNo(String studentNo) {
|
||||
if (StringUtils.isBlank(studentNo)) {
|
||||
throw new ServiceException("学号不能为空");
|
||||
}
|
||||
XgStudentMsg student = baseMapper.selectOne(
|
||||
Wrappers.<XgStudentMsg>lambdaQuery()
|
||||
.eq(XgStudentMsg::getStudentNo, studentNo.trim())
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
if (student == null) {
|
||||
throw new ServiceException("未找到学号对应的学生信息");
|
||||
}
|
||||
StudentPwdResetVo vo = new StudentPwdResetVo();
|
||||
vo.setId(student.getId());
|
||||
vo.setStudentNo(student.getStudentNo());
|
||||
vo.setName(student.getName());
|
||||
vo.setClassName(student.getClassName());
|
||||
vo.setClassTeacherName(student.getClassTeacherName());
|
||||
// 学生档案班主任为空时,回退班级表
|
||||
if (StringUtils.isBlank(vo.getClassTeacherName()) && StringUtils.isNotBlank(student.getClassId())) {
|
||||
try {
|
||||
XgClassMsg classMsg = xgClassMsgMapper.selectById(Long.valueOf(student.getClassId()));
|
||||
if (classMsg != null && StringUtils.isNotBlank(classMsg.getClassTeacherName())) {
|
||||
vo.setClassTeacherName(classMsg.getClassTeacherName());
|
||||
}
|
||||
if (StringUtils.isBlank(vo.getClassName()) && classMsg != null) {
|
||||
vo.setClassName(classMsg.getClassName());
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// classId 非数字时忽略回退
|
||||
}
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean resetStudentPasswordByStudentNo(String studentNo) {
|
||||
if (StringUtils.isBlank(studentNo)) {
|
||||
throw new ServiceException("学号不能为空");
|
||||
}
|
||||
String no = studentNo.trim();
|
||||
XgStudentMsg student = baseMapper.selectOne(
|
||||
Wrappers.<XgStudentMsg>lambdaQuery()
|
||||
.eq(XgStudentMsg::getStudentNo, no)
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
if (student == null) {
|
||||
throw new ServiceException("未找到学号对应的学生信息");
|
||||
}
|
||||
if (student.getId() == null) {
|
||||
throw new ServiceException("学生数据异常,缺少主键");
|
||||
}
|
||||
SysUserVo user = sysUserService.selectUserById(student.getId());
|
||||
if (user == null) {
|
||||
throw new ServiceException("该学生没有登录账号,无法重置密码");
|
||||
}
|
||||
if (!"2".equals(user.getAccountType())) {
|
||||
throw new ServiceException("该账号不是学生账号,禁止重置");
|
||||
}
|
||||
if (StringUtils.isNotBlank(user.getUserName()) && !no.equals(user.getUserName())) {
|
||||
throw new ServiceException("学号与登录账号不一致,请联系管理员");
|
||||
}
|
||||
int rows = sysUserService.resetUserPwd(student.getId(), BCrypt.hashpw(STUDENT_RESET_PASSWORD));
|
||||
if (rows <= 0) {
|
||||
throw new ServiceException("重置密码失败,请稍后重试");
|
||||
}
|
||||
log.info("学生密码已重置, studentNo={}, studentId={}, operator={}",
|
||||
no, student.getId(), LoginHelper.getUserId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
-- =============================================================================
|
||||
-- 重置学生密码:菜单 + 按钮权限
|
||||
-- 日期:2026-10-26
|
||||
-- 父菜单:学生管理 (1959499382894141441)
|
||||
-- Web 页面:xg/xsjcxx/studentMsg/studentPwdReset/index
|
||||
-- 移动端首页入口权限:student:pwdreset:listapp
|
||||
-- 重置密码固定值(服务端写死):Hzdyjsxs123456!@#
|
||||
-- 执行:开发/生产库均可幂等执行;执行后给角色勾选菜单或跑下方角色授权段
|
||||
-- =============================================================================
|
||||
|
||||
-- 1. 菜单页(学生管理下级)
|
||||
INSERT INTO `sys_menu` (
|
||||
`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`,
|
||||
`is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`,
|
||||
`create_dept`, `create_by`, `create_time`, `remark`
|
||||
)
|
||||
SELECT 2026102610000000101, '重置学生密码', 1959499382894141441, 16, 'studentPwdReset',
|
||||
'xg/xsjcxx/studentMsg/studentPwdReset/index', NULL,
|
||||
1, 0, 'C', '0', '0', 'studentMsg:studentPwdReset:list', 'password',
|
||||
103, 1, NOW(), '按学号查询并重置学生登录密码'
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `menu_id` = 2026102610000000101);
|
||||
|
||||
-- 2. 按钮:查询
|
||||
INSERT INTO `sys_menu` (
|
||||
`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`,
|
||||
`is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`,
|
||||
`create_dept`, `create_by`, `create_time`, `remark`
|
||||
)
|
||||
SELECT 2026102610000000102, '查询学生', 2026102610000000101, 1, '#', '', NULL,
|
||||
1, 0, 'F', '0', '0', 'studentMsg:studentPwdReset:query', '#',
|
||||
103, 1, NOW(), '按学号查询学生信息'
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `menu_id` = 2026102610000000102);
|
||||
|
||||
-- 3. 按钮:重置密码
|
||||
INSERT INTO `sys_menu` (
|
||||
`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`,
|
||||
`is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`,
|
||||
`create_dept`, `create_by`, `create_time`, `remark`
|
||||
)
|
||||
SELECT 2026102610000000103, '确认重置', 2026102610000000101, 2, '#', '', NULL,
|
||||
1, 0, 'F', '0', '0', 'studentMsg:studentPwdReset:reset', '#',
|
||||
103, 1, NOW(), '确认重置学生密码'
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `menu_id` = 2026102610000000103);
|
||||
|
||||
-- 4. 移动端首页入口权限(挂在同一菜单页下,供 hasPermi 控制入口可见)
|
||||
INSERT INTO `sys_menu` (
|
||||
`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`,
|
||||
`is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`,
|
||||
`create_dept`, `create_by`, `create_time`, `remark`
|
||||
)
|
||||
SELECT 2026102610000000104, '重置学生密码(移动端)', 2026102610000000101, 3, '', '', NULL,
|
||||
1, 0, 'F', '0', '0', 'student:pwdreset:listapp', '#',
|
||||
103, 1, NOW(), '移动端首页入口权限'
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `menu_id` = 2026102610000000104);
|
||||
|
||||
-- 5. 给已有「学生信息」菜单权限的角色补授权(幂等)
|
||||
INSERT INTO `sys_role_menu` (`role_id`, `menu_id`)
|
||||
SELECT DISTINCT rm.role_id, m.menu_id
|
||||
FROM `sys_role_menu` rm
|
||||
CROSS JOIN (
|
||||
SELECT 2026102610000000101 AS menu_id UNION ALL
|
||||
SELECT 2026102610000000102 UNION ALL
|
||||
SELECT 2026102610000000103 UNION ALL
|
||||
SELECT 2026102610000000104
|
||||
) m
|
||||
WHERE rm.menu_id = 1948289114628902914
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM `sys_role_menu` x
|
||||
WHERE x.role_id = rm.role_id AND x.menu_id = m.menu_id
|
||||
);
|
||||
|
||||
-- 核对
|
||||
SELECT menu_id, menu_name, parent_id, path, component, perms, menu_type
|
||||
FROM sys_menu
|
||||
WHERE menu_id BETWEEN 2026102610000000101 AND 2026102610000000104
|
||||
ORDER BY menu_id;
|
||||
Reference in new issue
Block a user