refactor(client):优化设备管理与登录逻辑
- 移除冗余的日志记录器声明 - 简化设备心跳接口,合并注册与更新逻辑 - 调整设备数量限制检查逻辑,提高代码可读性 - 修改默认设备数量限制从3台调整为1台- 更新客户端登出提示文案- 固定启动窗口尺寸并移除延迟启动逻辑 - 调整设备移除时的消息提示内容
This commit is contained in:
@@ -199,7 +199,7 @@ function startSpringBoot() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// startSpringBoot();
|
startSpringBoot();
|
||||||
|
|
||||||
function stopSpringBoot() {
|
function stopSpringBoot() {
|
||||||
if (!springProcess) return;
|
if (!springProcess) return;
|
||||||
@@ -269,10 +269,9 @@ app.whenReady().then(() => {
|
|||||||
createWindow();
|
createWindow();
|
||||||
createTray(mainWindow);
|
createTray(mainWindow);
|
||||||
|
|
||||||
const {width: sw, height: sh} = screen.getPrimaryDisplay().workAreaSize;
|
|
||||||
splashWindow = new BrowserWindow({
|
splashWindow = new BrowserWindow({
|
||||||
width: Math.min(Math.floor(sw * 0.8), 1800),
|
width: 1200,
|
||||||
height: Math.min(Math.floor(sh * 0.8), 1200),
|
height: 675,
|
||||||
frame: false,
|
frame: false,
|
||||||
transparent: false,
|
transparent: false,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
@@ -296,9 +295,9 @@ app.whenReady().then(() => {
|
|||||||
splashWindow.loadFile(splashPath);
|
splashWindow.loadFile(splashPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
openAppIfNotOpened();
|
// openAppIfNotOpened();
|
||||||
}, 2000);
|
// }, 2000);
|
||||||
|
|
||||||
app.on('activate', () => {
|
app.on('activate', () => {
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
|
|||||||
@@ -191,10 +191,7 @@ async function handleLoginSuccess(data: { token: string; permissions?: string; e
|
|||||||
const deviceExpired = deviceTrialExpired.value
|
const deviceExpired = deviceTrialExpired.value
|
||||||
const isPaid = accountType.value === 'paid'
|
const isPaid = accountType.value === 'paid'
|
||||||
|
|
||||||
if (isPaid) {
|
if (deviceExpired && accountExpired) {
|
||||||
// 场景5: 付费用户
|
|
||||||
ElMessage.success('登录成功')
|
|
||||||
} else if (deviceExpired && accountExpired) {
|
|
||||||
// 场景4: 试用已到期,请订阅
|
// 场景4: 试用已到期,请订阅
|
||||||
trialExpiredType.value = 'both'
|
trialExpiredType.value = 'both'
|
||||||
showTrialExpiredDialog.value = true
|
showTrialExpiredDialog.value = true
|
||||||
@@ -206,9 +203,6 @@ async function handleLoginSuccess(data: { token: string; permissions?: string; e
|
|||||||
// 场景2: 设备试用已到期,请更换设备或订阅
|
// 场景2: 设备试用已到期,请更换设备或订阅
|
||||||
trialExpiredType.value = 'device'
|
trialExpiredType.value = 'device'
|
||||||
showTrialExpiredDialog.value = true
|
showTrialExpiredDialog.value = true
|
||||||
} else {
|
|
||||||
// 场景1: 允许使用
|
|
||||||
ElMessage.success('登录成功')
|
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
isAuthenticated.value = false
|
isAuthenticated.value = false
|
||||||
@@ -234,7 +228,7 @@ function clearLocalAuth() {
|
|||||||
async function logout() {
|
async function logout() {
|
||||||
try {
|
try {
|
||||||
const deviceId = getClientIdFromToken()
|
const deviceId = getClientIdFromToken()
|
||||||
if (deviceId) await deviceApi.offline({ deviceId, username: currentUsername.value })
|
if (deviceId) await deviceApi.remove({ deviceId, username: currentUsername.value })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('离线通知失败:', error)
|
console.warn('离线通知失败:', error)
|
||||||
}
|
}
|
||||||
@@ -253,7 +247,6 @@ async function handleUserClick() {
|
|||||||
cancelButtonText: '取消'
|
cancelButtonText: '取消'
|
||||||
})
|
})
|
||||||
await logout()
|
await logout()
|
||||||
ElMessage.success('已退出登录')
|
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +359,7 @@ const SSEManager = {
|
|||||||
break
|
break
|
||||||
case 'DEVICE_REMOVED':
|
case 'DEVICE_REMOVED':
|
||||||
clearLocalAuth()
|
clearLocalAuth()
|
||||||
ElMessage.warning('您的设备已被移除,请重新登录')
|
ElMessage.warning('会话已失效,请重新登录')
|
||||||
break
|
break
|
||||||
case 'FORCE_LOGOUT':
|
case 'FORCE_LOGOUT':
|
||||||
logout()
|
logout()
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PageProcessor {
|
public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PageProcessor {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AmazonScrapingServiceImpl.class);
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AmazonProductRepository amazonProductRepository;
|
private AmazonProductRepository amazonProductRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -102,7 +101,7 @@ public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PagePr
|
|||||||
@Override
|
@Override
|
||||||
public List<AmazonProductEntity> batchGetProductInfo(List<String> asinList, String batchId, String region) {
|
public List<AmazonProductEntity> batchGetProductInfo(List<String> asinList, String batchId, String region) {
|
||||||
String sessionId = (batchId != null) ? batchId : "SINGLE_" + UUID.randomUUID();
|
String sessionId = (batchId != null) ? batchId : "SINGLE_" + UUID.randomUUID();
|
||||||
LocalDateTime batchTime = LocalDateTime.now(); // 统一的批次时间
|
LocalDateTime batchTime = LocalDateTime.now();
|
||||||
|
|
||||||
// 第一步:清理1小时前的所有旧数据
|
// 第一步:清理1小时前的所有旧数据
|
||||||
amazonProductRepository.deleteAllDataBefore(LocalDateTime.now().minusHours(1));
|
amazonProductRepository.deleteAllDataBefore(LocalDateTime.now().minusHours(1));
|
||||||
|
|||||||
@@ -24,40 +24,6 @@ public class ClientDeviceController {
|
|||||||
private ClientAccountMapper clientAccountMapper;
|
private ClientAccountMapper clientAccountMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SseHubService sseHubService;
|
private SseHubService sseHubService;
|
||||||
private static final int DEFAULT_LIMIT = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取账号的设备数量限制
|
|
||||||
*
|
|
||||||
* @param username 用户名
|
|
||||||
* @return 设备数量限制,如果账号不存在或未配置则返回默认值
|
|
||||||
*/
|
|
||||||
private int getDeviceLimit(String username) {
|
|
||||||
if (username == null || username.isEmpty()) {
|
|
||||||
return DEFAULT_LIMIT;
|
|
||||||
}
|
|
||||||
ClientAccount account = clientAccountMapper.selectClientAccountByUsername(username);
|
|
||||||
if (account == null || account.getDeviceLimit() == null) {
|
|
||||||
return DEFAULT_LIMIT;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
if (userDevices.size() >= deviceLimit) {
|
|
||||||
throw new RuntimeException("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备配额与已使用数量
|
* 查询设备配额与已使用数量
|
||||||
@@ -72,7 +38,8 @@ public class ClientDeviceController {
|
|||||||
for (ClientDevice d : all) {
|
for (ClientDevice d : all) {
|
||||||
if (!"removed".equals(d.getStatus())) used++;
|
if (!"removed".equals(d.getStatus())) used++;
|
||||||
}
|
}
|
||||||
int limit = getDeviceLimit(username);
|
ClientAccount account = clientAccountMapper.selectClientAccountByUsername(username);
|
||||||
|
int limit = (account != null && account.getDeviceLimit() != null) ? account.getDeviceLimit() : 3;
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("limit", limit);
|
map.put("limit", limit);
|
||||||
map.put("used", used);
|
map.put("used", used);
|
||||||
@@ -102,14 +69,21 @@ public class ClientDeviceController {
|
|||||||
String deviceId = device.getDeviceId();
|
String deviceId = device.getDeviceId();
|
||||||
String os = device.getOs();
|
String os = device.getOs();
|
||||||
String deviceName = username + "@" + ip + " (" + os + ")";
|
String deviceName = username + "@" + ip + " (" + os + ")";
|
||||||
|
|
||||||
|
// 检查设备数量限制
|
||||||
|
ClientAccount account = clientAccountMapper.selectClientAccountByUsername(username);
|
||||||
|
int deviceLimit = (account != null && account.getDeviceLimit() != null) ? account.getDeviceLimit() : 3;
|
||||||
|
List<ClientDevice> userDevices = clientDeviceMapper.selectByUsername(username);
|
||||||
|
int userDevice = userDevices.size();
|
||||||
|
boolean deviceExists = userDevices.stream().anyMatch(d -> deviceId.equals(d.getDeviceId()));
|
||||||
|
if (deviceExists) userDevice--;
|
||||||
|
if (userDevice >= deviceLimit) {
|
||||||
|
return AjaxResult.error("设备数量已达上限(" + deviceLimit + "个),请先移除其他设备");
|
||||||
|
}
|
||||||
|
|
||||||
ClientDevice exists = clientDeviceMapper.selectByDeviceIdAndUsername(deviceId, username);
|
ClientDevice exists = clientDeviceMapper.selectByDeviceIdAndUsername(deviceId, username);
|
||||||
if (exists == null) {
|
if (exists == null) {
|
||||||
// 检查设备数量限制
|
|
||||||
try {
|
|
||||||
checkDeviceLimit(username, deviceId);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
return AjaxResult.error(e.getMessage());
|
|
||||||
}
|
|
||||||
device.setIp(ip);
|
device.setIp(ip);
|
||||||
device.setStatus("online");
|
device.setStatus("online");
|
||||||
device.setLastActiveAt(new java.util.Date());
|
device.setLastActiveAt(new java.util.Date());
|
||||||
@@ -117,6 +91,7 @@ public class ClientDeviceController {
|
|||||||
device.setName(deviceName);
|
device.setName(deviceName);
|
||||||
clientDeviceMapper.insert(device);
|
clientDeviceMapper.insert(device);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
exists.setName(deviceName);
|
exists.setName(deviceName);
|
||||||
exists.setOs(os);
|
exists.setOs(os);
|
||||||
exists.setStatus("online");
|
exists.setStatus("online");
|
||||||
@@ -188,48 +163,6 @@ public class ClientDeviceController {
|
|||||||
return AjaxResult.success();
|
return AjaxResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设备心跳
|
|
||||||
* 若设备未注册则按注册逻辑插入;已注册则更新在线状态和设备信息
|
|
||||||
* 所有情况都检查设备数量限制,被移除设备允许重新注册(需检查配额)
|
|
||||||
*/
|
|
||||||
@PostMapping("/heartbeat")
|
|
||||||
public AjaxResult heartbeat(@RequestBody ClientDevice device, HttpServletRequest request) {
|
|
||||||
String ip = IpUtils.getIpAddr(request);
|
|
||||||
String username = device.getUsername();
|
|
||||||
String deviceId = device.getDeviceId();
|
|
||||||
String os = device.getOs();
|
|
||||||
String deviceName = username + "@" + ip + " (" + os + ")";
|
|
||||||
|
|
||||||
ClientDevice exists = clientDeviceMapper.selectByDeviceIdAndUsername(deviceId, username);
|
|
||||||
if (exists == null) {
|
|
||||||
// 新设备注册
|
|
||||||
device.setIp(ip);
|
|
||||||
device.setStatus("online");
|
|
||||||
device.setLastActiveAt(new java.util.Date());
|
|
||||||
device.setTrialExpireTime(new java.util.Date(System.currentTimeMillis() + 3 * 24L * 60 * 60 * 1000));
|
|
||||||
device.setName(deviceName);
|
|
||||||
clientDeviceMapper.insert(device);
|
|
||||||
} else if ("removed".equals(exists.getStatus())) {
|
|
||||||
// 被移除设备重新激活
|
|
||||||
exists.setName(deviceName);
|
|
||||||
exists.setOs(os);
|
|
||||||
exists.setStatus("online");
|
|
||||||
exists.setIp(ip);
|
|
||||||
exists.setLocation(device.getLocation());
|
|
||||||
exists.setLastActiveAt(new java.util.Date());
|
|
||||||
clientDeviceMapper.updateByDeviceIdAndUsername(exists);
|
|
||||||
} else {
|
|
||||||
// 已存在设备更新
|
|
||||||
exists.setStatus("online");
|
|
||||||
exists.setIp(ip);
|
|
||||||
exists.setLastActiveAt(new java.util.Date());
|
|
||||||
exists.setName(deviceName);
|
|
||||||
clientDeviceMapper.updateByDeviceIdAndUsername(exists);
|
|
||||||
}
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@
|
|||||||
placeholder="请输入设备数量限制"
|
placeholder="请输入设备数量限制"
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
></el-input-number>
|
></el-input-number>
|
||||||
<span style="color: #909399; font-size: 12px;">允许同时登录的设备数量,默认3台</span>
|
<span style="color: #909399; font-size: 12px;">允许同时登录的设备数量,默认1台</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="功能权限" prop="permissions">
|
<el-form-item label="功能权限" prop="permissions">
|
||||||
<div class="permission-config">
|
<div class="permission-config">
|
||||||
|
|||||||
Reference in New Issue
Block a user