From ef75668eb382547e388e25ca9c27b3c75334b446 Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Tue, 26 May 2026 15:22:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E6=9C=BA=E7=99=BB=E5=BD=95=E9=99=90?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sys/controller/SysLoginController.java | 38 +++++++++++++++++++ .../modules/sys/entity/SysUserEntity.java | 26 +++++++++++++ .../spring/modules/sys/form/SysLoginForm.java | 2 + .../sys/service/impl/SysUserServiceImpl.java | 14 +++++++ src/main/resources/mapper/sys/SysUserDao.xml | 2 + 5 files changed, 82 insertions(+) diff --git a/src/main/java/com/spring/modules/sys/controller/SysLoginController.java b/src/main/java/com/spring/modules/sys/controller/SysLoginController.java index f8ab767a..5a89adfc 100644 --- a/src/main/java/com/spring/modules/sys/controller/SysLoginController.java +++ b/src/main/java/com/spring/modules/sys/controller/SysLoginController.java @@ -125,6 +125,36 @@ public class SysLoginController extends AbstractController { + String currentDeviceId = normalizeDeviceId(form.getDeviceId()); + // 规则1:如果当前电脑已经被其他账号绑定,则不允许其他账号在该电脑登录 + if (StringUtils.isNotBlank(currentDeviceId)) { + List bindUserList = sysUserService.lambdaQuery() + .eq(SysUserEntity::getBindDeviceId, currentDeviceId) + .ne(SysUserEntity::getUserId, user.getUserId()) + .list(); + if (!bindUserList.isEmpty()) { + return R.error("当前电脑已绑定账号【" + bindUserList.get(0).getUsername() + "】,不允许其他账号登录"); + } + } + + // 规则2:当前账号开启“单机登录限制”时,账号只能在绑定电脑登录 + if (Integer.valueOf(1).equals(user.getSingleComputerLimit())) { + if (StringUtils.isBlank(currentDeviceId)) { + return R.error("账号已开启单机登录限制,请先启动本地小程序后再登录"); + } + String bindDeviceId = normalizeDeviceId(user.getBindDeviceId()); + // 首次登录自动绑定当前设备 + if (StringUtils.isBlank(bindDeviceId)) { + SysUserEntity updateUser = new SysUserEntity(); + updateUser.setUserId(user.getUserId()); + updateUser.setBindDeviceId(currentDeviceId); + sysUserService.updateById(updateUser); + user.setBindDeviceId(currentDeviceId); + } else if (!StringUtils.equals(bindDeviceId, currentDeviceId)) { + return R.error("该账号已绑定其他电脑,不允许在当前电脑登录"); + } + } + session.setAttribute("user", user); //生成token,并保存到数据库 @@ -159,5 +189,13 @@ public class SysLoginController extends AbstractController { sysUserTokenService.logout(getUserId()); return R.ok(getLanguageMsg(SysMsgConstant.OBJECT_ID_200000)); } + + private String normalizeDeviceId(String deviceId) { + if (StringUtils.isBlank(deviceId)) { + return ""; + } + String trimVal = deviceId.trim(); + return trimVal.length() > 128 ? trimVal.substring(0, 128) : trimVal; + } } diff --git a/src/main/java/com/spring/modules/sys/entity/SysUserEntity.java b/src/main/java/com/spring/modules/sys/entity/SysUserEntity.java index 1fe373fe..3468398d 100644 --- a/src/main/java/com/spring/modules/sys/entity/SysUserEntity.java +++ b/src/main/java/com/spring/modules/sys/entity/SysUserEntity.java @@ -67,6 +67,16 @@ public class SysUserEntity extends QueryPage implements Serializable { */ private Integer status; + /** + * 是否限制仅允许 1 台电脑登录:0-否,1-是 + */ + private Integer singleComputerLimit; + + /** + * 已绑定的设备标识(开启单机限制后首次登录自动绑定) + */ + private String bindDeviceId; + /** * 角色ID列表 */ @@ -248,6 +258,22 @@ public class SysUserEntity extends QueryPage implements Serializable { this.status = status; } + public Integer getSingleComputerLimit() { + return singleComputerLimit; + } + + public void setSingleComputerLimit(Integer singleComputerLimit) { + this.singleComputerLimit = singleComputerLimit; + } + + public String getBindDeviceId() { + return bindDeviceId; + } + + public void setBindDeviceId(String bindDeviceId) { + this.bindDeviceId = bindDeviceId; + } + public List getRoleIdList() { return roleIdList; } diff --git a/src/main/java/com/spring/modules/sys/form/SysLoginForm.java b/src/main/java/com/spring/modules/sys/form/SysLoginForm.java index 0020636b..0fc07cd3 100644 --- a/src/main/java/com/spring/modules/sys/form/SysLoginForm.java +++ b/src/main/java/com/spring/modules/sys/form/SysLoginForm.java @@ -17,6 +17,8 @@ public class SysLoginForm { private String uuid; private String type; private String site; + // 设备标识(本地小程序返回) + private String deviceId; // 域控账号 private String domainControlAccount; // token diff --git a/src/main/java/com/spring/modules/sys/service/impl/SysUserServiceImpl.java b/src/main/java/com/spring/modules/sys/service/impl/SysUserServiceImpl.java index a1bc1402..1d4f4564 100644 --- a/src/main/java/com/spring/modules/sys/service/impl/SysUserServiceImpl.java +++ b/src/main/java/com/spring/modules/sys/service/impl/SysUserServiceImpl.java @@ -95,6 +95,13 @@ public class SysUserServiceImpl extends ServiceImpl i throw new RuntimeException("用户已存在!"); } user.setCreateTime(new Date()); + // 默认不开启单机登录限制 + if (user.getSingleComputerLimit() == null) { + user.setSingleComputerLimit(0); + } + if (!Integer.valueOf(1).equals(user.getSingleComputerLimit())) { + user.setBindDeviceId(null); + } //sha256加密 String salt = RandomStringUtils.randomAlphanumeric(20); user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex()); @@ -134,6 +141,13 @@ public class SysUserServiceImpl extends ServiceImpl i user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex()); } this.updateById(user); + // 关闭单机登录限制时清空绑定设备,避免后续重新开启时误锁定旧设备 + if (user.getUserId() != null && user.getSingleComputerLimit() != null && !Integer.valueOf(1).equals(user.getSingleComputerLimit())) { + this.lambdaUpdate() + .set(SysUserEntity::getBindDeviceId, null) + .eq(SysUserEntity::getUserId, user.getUserId()) + .update(); + } //检查角色是否越权 //checkRole(user); diff --git a/src/main/resources/mapper/sys/SysUserDao.xml b/src/main/resources/mapper/sys/SysUserDao.xml index db81eae2..844e7aca 100644 --- a/src/main/resources/mapper/sys/SysUserDao.xml +++ b/src/main/resources/mapper/sys/SysUserDao.xml @@ -65,6 +65,8 @@ a.create_user_id, a.user_display, a.language_default, + a.single_computer_limit, + a.bind_device_id, b.bu_desc, c.department_name, d.post_name,