feat(client): 实现稳定的设备ID生成与认证优化
- 重构设备ID生成逻辑,采用多重降级策略确保唯一性与稳定性- 移除客户端SQLite缓存依赖,改用localStorage存储token与设备ID - 优化认证流程,简化token管理与会话恢复逻辑- 增加设备数量限制检查,防止超出配额 - 更新SSE连接逻辑,适配新的认证机制 - 调整Redis连接池配置,提升并发性能与稳定性 - 移除冗余的缓存接口与本地退出逻辑 - 修复设备移除时的状态处理问题,避免重复调用offline接口 - 引入OSHI库用于硬件信息采集(备用方案)- 更新开发环境API地址配置
This commit is contained in:
@@ -139,7 +139,26 @@ public class ClientAccountController extends BaseController {
|
||||
if (!"0".equals(account.getStatus())) {
|
||||
return AjaxResult.error("账号已被停用");
|
||||
}
|
||||
|
||||
// 检查设备数量限制
|
||||
String clientId = loginData.get("clientId");
|
||||
if (!StringUtils.isEmpty(clientId)) {
|
||||
ClientDevice currentDevice = clientDeviceMapper.selectByDeviceId(clientId);
|
||||
if (currentDevice == null || "removed".equals(currentDevice.getStatus())) {
|
||||
int deviceLimit = account.getDeviceLimit();
|
||||
java.util.List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||
int activeDeviceCount = 0;
|
||||
for (ClientDevice d : userDevices) {
|
||||
if (!"removed".equals(d.getStatus()) && !d.getDeviceId().equals(clientId)) {
|
||||
activeDeviceCount++;
|
||||
}
|
||||
}
|
||||
if (activeDeviceCount >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String accessToken = Jwts.builder()
|
||||
.setHeaderParam("kid", jwtRsaKeyService.getKeyId())
|
||||
.setSubject(username)
|
||||
@@ -157,6 +176,7 @@ public class ClientAccountController extends BaseController {
|
||||
result.put("expireTime", account.getExpireTime());
|
||||
return AjaxResult.success("登录成功", result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,27 @@ public class ClientDeviceController {
|
||||
return account.getDeviceLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查设备数量限制
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param currentDeviceId 当前设备ID(检查时排除此设备)
|
||||
* @throws RuntimeException 如果设备数量已达上限
|
||||
*/
|
||||
private void checkDeviceLimit(String username, String currentDeviceId) {
|
||||
int deviceLimit = getDeviceLimit(username);
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||
int activeDeviceCount = 0;
|
||||
for (ClientDevice d : userDevices) {
|
||||
if (!"removed".equals(d.getStatus()) && !d.getDeviceId().equals(currentDeviceId)) {
|
||||
activeDeviceCount++;
|
||||
}
|
||||
}
|
||||
if (activeDeviceCount >= deviceLimit) {
|
||||
throw new RuntimeException("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备配额与已使用数量
|
||||
*
|
||||
@@ -83,20 +104,15 @@ public class ClientDeviceController {
|
||||
public AjaxResult register(@RequestBody ClientDevice device, HttpServletRequest request) {
|
||||
ClientDevice exists = clientDeviceMapper.selectByDeviceId(device.getDeviceId());
|
||||
String ip = IpUtils.getIpAddr(request);
|
||||
// 从请求体读取用户名和操作系统,构建设备名称
|
||||
String username = device.getUsername();
|
||||
String os = device.getOs();
|
||||
String deviceName = username + "@" + ip + " (" + os + ")";
|
||||
if (exists == null) {
|
||||
// 检查设备数量限制
|
||||
int deviceLimit = getDeviceLimit(device.getUsername());
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(device.getUsername());
|
||||
int activeDeviceCount = 0;
|
||||
for (ClientDevice d : userDevices) {
|
||||
if (!"removed".equals(d.getStatus())) activeDeviceCount++;
|
||||
}
|
||||
if (activeDeviceCount >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
try {
|
||||
checkDeviceLimit(device.getUsername(), device.getDeviceId());
|
||||
} catch (RuntimeException e) {
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
device.setIp(ip);
|
||||
device.setStatus("online");
|
||||
@@ -128,7 +144,6 @@ public class ClientDeviceController {
|
||||
}
|
||||
/**
|
||||
* 移除设备
|
||||
*
|
||||
* 根据 deviceId 删除设备绑定记录。
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@@ -173,36 +188,42 @@ public class ClientDeviceController {
|
||||
/**
|
||||
* 设备心跳
|
||||
* 若设备未注册则按注册逻辑插入;已注册则更新在线状态和设备信息
|
||||
* 所有情况都检查设备数量限制,被移除设备允许重新注册(需检查配额)
|
||||
*/
|
||||
@PostMapping("/heartbeat")
|
||||
public AjaxResult heartbeat(@RequestBody ClientDevice device, HttpServletRequest request) {
|
||||
ClientDevice exists = clientDeviceMapper.selectByDeviceId(device.getDeviceId());
|
||||
String ip = IpUtils.getIpAddr(request);
|
||||
// 从请求体读取用户名和操作系统,构建设备名称
|
||||
String username = device.getUsername() ;
|
||||
String username = device.getUsername();
|
||||
String os = device.getOs();
|
||||
String deviceName = username + "@" + ip + " (" + os + ")";
|
||||
|
||||
// 统一检查设备数量限制
|
||||
try {
|
||||
checkDeviceLimit(device.getUsername(), device.getDeviceId());
|
||||
} catch (RuntimeException e) {
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
if (exists == null) {
|
||||
// 检查设备数量限制
|
||||
int deviceLimit = getDeviceLimit(device.getUsername());
|
||||
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(device.getUsername());
|
||||
int activeDeviceCount = 0;
|
||||
for (ClientDevice d : userDevices) {
|
||||
if (!"removed".equals(d.getStatus())) activeDeviceCount++;
|
||||
}
|
||||
if (activeDeviceCount >= deviceLimit) {
|
||||
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||
}
|
||||
// 新设备注册
|
||||
device.setIp(ip);
|
||||
device.setStatus("online");
|
||||
device.setLastActiveAt(new java.util.Date());
|
||||
device.setName(deviceName);
|
||||
clientDeviceMapper.insert(device);
|
||||
} else if ("removed".equals(exists.getStatus())) {
|
||||
AjaxResult res = AjaxResult.error("设备已被移除");
|
||||
res.put("bizCode", "DEVICE_REMOVED");
|
||||
return res;
|
||||
// 被移除设备重新激活
|
||||
exists.setUsername(device.getUsername());
|
||||
exists.setName(deviceName);
|
||||
exists.setOs(device.getOs());
|
||||
exists.setStatus("online");
|
||||
exists.setIp(ip);
|
||||
exists.setLocation(device.getLocation());
|
||||
exists.setLastActiveAt(new java.util.Date());
|
||||
clientDeviceMapper.updateByDeviceId(exists);
|
||||
} else {
|
||||
// 已存在设备更新
|
||||
exists.setUsername(device.getUsername());
|
||||
exists.setStatus("online");
|
||||
exists.setIp(ip);
|
||||
|
||||
Reference in New Issue
Block a user