diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java index 4fa57f51..4c82a33d 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java @@ -146,4 +146,9 @@ public class SysUserVo implements Serializable { private Long roleId; private String lawCertificateNum; + + /** + * 登录账号 + */ + private String loginName; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java index 0100908c..a520ebf3 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java @@ -60,6 +60,14 @@ public interface ISysUserService { */ SysUserVo selectUserByUserName(String userName); + /** + * 通过登录账号查询用户 + * + * @param loginName 登录账号 + * @return 用户对象信息 + */ + SysUserVo selectUserByLoginName(String loginName); + /** * 通过手机号查询用户 * diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index b4e2753b..e37b2d96 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -158,6 +158,17 @@ public class SysUserServiceImpl implements ISysUserService, UserService { return baseMapper.selectVoOne(new LambdaQueryWrapper().eq(SysUser::getUserName, userName)); } + /** + * 通过登录账号查询用户 + * + * @param loginName 登录账号 + * @return 用户对象信息 + */ + @Override + public SysUserVo selectUserByLoginName(String loginName) { + return baseMapper.selectVoOne(new LambdaQueryWrapper().eq(SysUser::getLoginName, loginName)); + } + /** * 通过手机号查询用户 * diff --git a/ruoyi-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java b/ruoyi-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java index 7ac9546a..9f44b4ee 100644 --- a/ruoyi-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java +++ b/ruoyi-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java @@ -32,23 +32,23 @@ public class AppEnfLoginController extends LoginController { /** * 执法端用户登录 * - * @param params 包含 secretName(用户名)和 secretKey(AES加密后的密码) + * @param params 包含 secretName(登录账号)和 secretKey(AES加密后的密码) * @return 登录结果(token + 用户信息) */ @SaIgnore @PostMapping("/do") public R> validate(@RequestBody Map params) { - String secretName = params.get("secretName"); + String loginName = params.get("secretName"); String secretKey = params.get("secretKey"); // 1. 参数校验 - R> paramCheck = validateLoginParams(secretName, secretKey); + R> paramCheck = validateLoginParams(loginName, secretKey); if (paramCheck != null) { return paramCheck; } - // 2. 根据用户名查询 sys_user 表 - SysUserVo user = sysUserService.selectUserByUserName(secretName); + // 2. 根据登录账号查询 sys_user 表 + SysUserVo user = sysUserService.selectUserByLoginName(loginName); if (user == null) { return R.fail("用户不存在"); } @@ -64,8 +64,8 @@ public class AppEnfLoginController extends LoginController { return R.fail("密码解密失败"); } - // 5. MD5加盐校验密码 - if (!verifyPassword(user.getUserName(), decryptedPassword, user.getSalt(), user.getPassword())) { + // 5. MD5加盐校验密码(使用loginName作为加盐因子) + if (!verifyPassword(loginName, decryptedPassword, user.getSalt(), user.getPassword())) { return R.fail("用户名或密码错误"); } @@ -87,6 +87,7 @@ public class AppEnfLoginController extends LoginController { data.put("token", token); data.put("userId", user.getUserId()); data.put("userName", user.getUserName()); + data.put("loginName", user.getLoginName()); data.put("nickName", user.getNickName()); data.put("phonenumber", user.getPhonenumber() != null ? user.getPhonenumber() : ""); data.put("deptId", user.getDeptId() != null ? user.getDeptId() : ""); diff --git a/zdxt-web-client/zdxt-enforcement-code-app/src/views/enforcement/login.vue b/zdxt-web-client/zdxt-enforcement-code-app/src/views/enforcement/login.vue index c3620d10..cf2799aa 100644 --- a/zdxt-web-client/zdxt-enforcement-code-app/src/views/enforcement/login.vue +++ b/zdxt-web-client/zdxt-enforcement-code-app/src/views/enforcement/login.vue @@ -51,7 +51,14 @@ const showTestPicker = ref(false); const testUsers = [ - { account: 'admin', name: '管理员', password: 'szsf@zfjd' }, + { account: 'liuqianlin', name: '刘倩琳', password: 'szsf@zfjd' }, + { account: 'baining', name: '白宁', password: 'szsf@zfjd' }, + { account: 'caizifan', name: '蔡梓帆', password: 'szsf@zfjd' }, + { account: 'chenchong4', name: '陈冲', password: 'szsf@zfjd' }, + { account: 'chenggaozhan', name: '程高展', password: 'szsf@zfjd' }, + { account: 'chenhaitao2', name: '陈海涛', password: 'szsf@zfjd' }, + { account: 'chenhanyu', name: '陈汉羽', password: 'szsf@zfjd' } + ]; const selectTestUser = (item) => { diff --git a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java b/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java index 4f1f2e16..1768bbeb 100644 --- a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java +++ b/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java @@ -11,11 +11,24 @@ import org.dromara.system.mapper.SysUserMapper; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; +import cn.dev33.satoken.stp.StpUtil; +import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.satoken.utils.LoginHelper; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + /** * 批量重置 enterprise_user 表用户密码 *

@@ -23,6 +36,7 @@ import java.util.List; *

*/ @SpringBootTest(classes = ZdxtAdminApplication.class) +@AutoConfigureMockMvc @DisplayName("批量重置企业用户密码") public class ResetUserPasswordTest { @@ -35,6 +49,46 @@ public class ResetUserPasswordTest { /** 重置后的明文密码 */ private static final String NEW_PASSWORD = "szsf@zfjd"; + private static final String TEST_CLIENT_ID = "e5cd7e4891bf95d1d19206ce24a7b32e"; + + @BeforeEach + public void setUp() { + // 初始化 Sa-Token 上下文(非 Web 环境下 StpUtil.login 需要) + SaTokenContextMockUtil.setMockContext(); + + // 设置模拟请求上下文(数据权限拦截器需要从 SaToken 上下文获取用户信息) + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + mockRequest.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(mockRequest)); + + // 构造测试用登录用户 + LoginUser loginUser = new LoginUser(); + loginUser.setUserId(1L); + loginUser.setUserType("sys_user"); + loginUser.setTenantId("000000"); + loginUser.setUsername("test_admin"); + loginUser.setNickname("测试管理员"); + loginUser.setDeptId("103"); + loginUser.setDeptName("测试部门"); + loginUser.setRolePermission(new HashSet<>()); + loginUser.setMenuPermission(new HashSet<>()); + + // 模拟登录 + SaLoginParameter param = new SaLoginParameter(); + param.setExtra(LoginHelper.CLIENT_KEY, TEST_CLIENT_ID); + LoginHelper.login(loginUser, param); + } + + @AfterEach + public void tearDown() { + try { + StpUtil.logout(); + } catch (Exception ignored) { + } + RequestContextHolder.resetRequestAttributes(); + SaTokenContextMockUtil.clearContext(); + } + @DisplayName("批量重置 enterprise_user 所有用户密码为 szsf@zfjd") @Test public void resetAllEnterpriseUserPassword() { @@ -108,13 +162,13 @@ public class ResetUserPasswordTest { // 1. 指定需要重置密码的用户ID列表 List userIds = Arrays.asList( // TODO: 在此填入需要重置的用户ID - 1L, 2L + 7897L, 17608416858L,17608416876L, 17608416904L,17608416912L, 17608416926L,17608416927L, 17608416945L ); // 2. 根据ID列表查询系统用户 List userList = sysUserMapper.selectList( new LambdaQueryWrapper() - .select(SysUser::getUserId, SysUser::getUserName, SysUser::getSalt) + .select(SysUser::getUserId, SysUser::getLoginName, SysUser::getSalt) .in(SysUser::getUserId, userIds) ); @@ -124,11 +178,11 @@ public class ResetUserPasswordTest { int skipCount = 0; for (SysUser user : userList) { - String userName = user.getUserName(); + String loginName = user.getLoginName(); String salt = user.getSalt(); - if (userName == null || userName.isBlank()) { - System.out.println("跳过: userId=" + user.getUserId() + ", userName为空"); + if (loginName == null || loginName.isBlank()) { + System.out.println("跳过: userId=" + user.getUserId() + ", loginName为空"); skipCount++; continue; } @@ -138,8 +192,8 @@ public class ResetUserPasswordTest { continue; } - // 3. 按规则生成新密码: MD5(userName + newPassword + salt) - String newMd5Password = DigestUtil.md5Hex(userName + NEW_PASSWORD + salt); + // 3. 按规则生成新密码: MD5( + newPassword + salt) + String newMd5Password = DigestUtil.md5Hex(loginName + NEW_PASSWORD + salt); // 4. 更新密码 int rows = sysUserMapper.update(null,