diff --git a/electron-vue-template/src/main/main.ts b/electron-vue-template/src/main/main.ts index 26d0c7a..bf0ada9 100644 --- a/electron-vue-template/src/main/main.ts +++ b/electron-vue-template/src/main/main.ts @@ -804,6 +804,9 @@ ipcMain.handle('set-launch-config', (event, launchConfig: { autoLaunch: boolean; return { success: true }; }); +// 刷新页面 +ipcMain.handle('reload', () => mainWindow?.webContents.reload()); + async function getFileSize(url: string): Promise { return new Promise((resolve) => { diff --git a/electron-vue-template/src/main/preload.ts b/electron-vue-template/src/main/preload.ts index 3f5f4b3..a3cbde2 100644 --- a/electron-vue-template/src/main/preload.ts +++ b/electron-vue-template/src/main/preload.ts @@ -34,6 +34,9 @@ const electronAPI = { getLaunchConfig: () => ipcRenderer.invoke('get-launch-config'), setLaunchConfig: (config: { autoLaunch: boolean; launchMinimized: boolean }) => ipcRenderer.invoke('set-launch-config', config), + // 刷新页面 API + reload: () => ipcRenderer.invoke('reload'), + onDownloadProgress: (callback: (progress: any) => void) => { ipcRenderer.removeAllListeners('download-progress') ipcRenderer.on('download-progress', (event, progress) => callback(progress)) diff --git a/electron-vue-template/src/renderer/App.vue b/electron-vue-template/src/renderer/App.vue index f537c10..7e9ffb2 100644 --- a/electron-vue-template/src/renderer/App.vue +++ b/electron-vue-template/src/renderer/App.vue @@ -150,7 +150,7 @@ function goForward() { } function reloadPage() { - window.location.reload() + window.electronAPI.reload() } function handleMenuSelect(key: string) { diff --git a/electron-vue-template/src/renderer/api/device.ts b/electron-vue-template/src/renderer/api/device.ts index 29f2224..da64f25 100644 --- a/electron-vue-template/src/renderer/api/device.ts +++ b/electron-vue-template/src/renderer/api/device.ts @@ -14,18 +14,6 @@ export interface DeviceQuota { used: number } -/** - * 获取本机内网IP地址 - */ -async function getLocalIP(): Promise { - try { - const res = await http.get<{ data: string }>('/api/system/local-ip') - return res.data - } catch { - return '127.0.0.1' - } -} - export const deviceApi = { getQuota(username: string) { return http.get<{ data: DeviceQuota }>('/monitor/device/quota', { username }) @@ -36,8 +24,15 @@ export const deviceApi = { }, async register(payload: { username: string; deviceId: string; os?: string }) { - const ip = await getLocalIP() - return http.post('/monitor/device/register', { ...payload, ip }) + const [ipRes, nameRes] = await Promise.all([ + http.get<{ data: string }>('/api/system/local-ip'), + http.get<{ data: string }>('/api/system/computer-name') + ]) + return http.post('/monitor/device/register', { + ...payload, + ip: ipRes.data, + computerName: nameRes.data + }) }, remove(payload: { deviceId: string; username: string }) { diff --git a/electron-vue-template/src/renderer/api/http.ts b/electron-vue-template/src/renderer/api/http.ts index 3418b62..c9a1eb0 100644 --- a/electron-vue-template/src/renderer/api/http.ts +++ b/electron-vue-template/src/renderer/api/http.ts @@ -1,5 +1,4 @@ export type HttpMethod = 'GET' | 'POST' | 'DELETE'; - export const CONFIG = { CLIENT_BASE: 'http://localhost:8081', RUOYI_BASE: 'http://8.138.23.49:8085', diff --git a/electron-vue-template/src/renderer/components/amazon/AmazonDashboard.vue b/electron-vue-template/src/renderer/components/amazon/AmazonDashboard.vue index 1b8c2b4..f4781dc 100644 --- a/electron-vue-template/src/renderer/components/amazon/AmazonDashboard.vue +++ b/electron-vue-template/src/renderer/components/amazon/AmazonDashboard.vue @@ -259,8 +259,10 @@ async function openGenmaiSpirit() { genmaiLoading.value = true try { await systemApi.openGenmaiSpirit() + showMessage('跟卖精灵已打开', 'success') } catch (error: any) { - showMessage(error.message || '打开跟卖精灵失败', 'error') + const errorMsg = error?.msg || error?.message || '打开跟卖精灵失败' + showMessage(errorMsg, 'error') } finally { genmaiLoading.value = false } diff --git a/electron-vue-template/src/renderer/components/auth/RegisterDialog.vue b/electron-vue-template/src/renderer/components/auth/RegisterDialog.vue index 2cd4334..eaa2e13 100644 --- a/electron-vue-template/src/renderer/components/auth/RegisterDialog.vue +++ b/electron-vue-template/src/renderer/components/auth/RegisterDialog.vue @@ -35,6 +35,10 @@ const canRegister = computed(() => { usernameCheckResult.value === true }) +function filterUsername(value: string) { + registerForm.value.username = value.replace(/[^a-zA-Z0-9_]/g, '') +} + async function checkUsernameAvailability() { if (!registerForm.value.username) { usernameCheckResult.value = null @@ -123,10 +127,11 @@ function backToLogin() { diff --git a/erp_client_sb/pom.xml b/erp_client_sb/pom.xml index 51e7e70..26ffc95 100644 --- a/erp_client_sb/pom.xml +++ b/erp_client_sb/pom.xml @@ -10,7 +10,7 @@ com.tashow.erp erp_client_sb - 2.4.8 + 2.4.9 erp_client_sb erp客户端 diff --git a/erp_client_sb/src/main/java/com/tashow/erp/controller/SystemController.java b/erp_client_sb/src/main/java/com/tashow/erp/controller/SystemController.java index 96d78b1..c93e189 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/controller/SystemController.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/controller/SystemController.java @@ -65,12 +65,13 @@ public class SystemController { } @GetMapping("/local-ip") - public JsonData getLocalIp() { - try { - return JsonData.buildSuccess(java.net.InetAddress.getLocalHost().getHostAddress()); - } catch (Exception e) { - return JsonData.buildSuccess("127.0.0.1"); - } + public JsonData getLocalIp() throws Exception { + return JsonData.buildSuccess(java.net.InetAddress.getLocalHost().getHostAddress()); + } + + @GetMapping("/computer-name") + public JsonData getComputerName() { + return JsonData.buildSuccess(System.getenv("COMPUTERNAME")); } @GetMapping("/version") @@ -84,8 +85,14 @@ public class SystemController { } @PostMapping("/genmai/open") - public void openGenmaiWebsite() { - genmaiService.openGenmaiWebsite(); + public JsonData openGenmaiWebsite() { + try { + genmaiService.openGenmaiWebsite(); + return JsonData.buildSuccess("跟卖精灵已打开"); + } catch (Exception e) { + logger.error("打开跟卖精灵失败", e); + return JsonData.buildError(e.getMessage() != null ? e.getMessage() : "打开跟卖精灵失败"); + } } @GetMapping("/proxy/image") diff --git a/erp_client_sb/src/main/java/com/tashow/erp/service/impl/GenmaiServiceImpl.java b/erp_client_sb/src/main/java/com/tashow/erp/service/impl/GenmaiServiceImpl.java index 5156982..78faa81 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/service/impl/GenmaiServiceImpl.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/service/impl/GenmaiServiceImpl.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.qiniu.util.UrlUtils; import io.github.bonigarcia.wdm.WebDriverManager; -import lombok.SneakyThrows; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; @@ -25,26 +24,32 @@ public class GenmaiServiceImpl { private String updateGenmaijlToken; private final RestTemplate restTemplate = new RestTemplate(); ObjectMapper objectMapper = new ObjectMapper(); - @SneakyThrows public void openGenmaiWebsite() { - // 先关闭所有Chrome进程 - Runtime.getRuntime().exec("taskkill /f /im chrome.exe"); - WebDriverManager.chromedriver().setup(); - ChromeOptions options = new ChromeOptions(); - String username = System.getProperty("user.name", "user"); - String safeUsername; - char firstChar = username.charAt(0); - char flippedFirstChar = Character.isUpperCase(firstChar) ? Character.toLowerCase(firstChar) : Character.toUpperCase(firstChar); - safeUsername = flippedFirstChar + username.substring(1); - String chromeUserData = System.getProperty("user.home").replace(username, UrlUtils.urlEncode(safeUsername) ) - + "\\AppData\\Local\\Google\\Chrome\\User Data"; - options.addArguments("user-data-dir=" + chromeUserData.toLowerCase()); - options.addArguments("profile-directory=Default"); - WebDriver driver = new ChromeDriver(options); - driver.get("https://www.genmaijl.com/#/profile"); - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript(String.format("localStorage.setItem('token','%s')", checkTokenExpired())); - driver.navigate().refresh(); + try { + // 先关闭所有Chrome进程 + Runtime.getRuntime().exec("taskkill /f /im chrome.exe"); + Thread.sleep(1000); // 等待进程关闭 + + WebDriverManager.chromedriver().setup(); + ChromeOptions options = new ChromeOptions(); + String username = System.getProperty("user.name", "user"); + String safeUsername; + char firstChar = username.charAt(0); + char flippedFirstChar = Character.isUpperCase(firstChar) ? Character.toLowerCase(firstChar) : Character.toUpperCase(firstChar); + safeUsername = flippedFirstChar + username.substring(1); + String chromeUserData = System.getProperty("user.home").replace(username, UrlUtils.urlEncode(safeUsername)) + + "\\AppData\\Local\\Google\\Chrome\\User Data"; + options.addArguments("user-data-dir=" + chromeUserData.toLowerCase()); + options.addArguments("profile-directory=Default"); + + WebDriver driver = new ChromeDriver(options); + driver.get("https://www.genmaijl.com/#/profile"); + JavascriptExecutor js = (JavascriptExecutor) driver; + js.executeScript(String.format("localStorage.setItem('token','%s')", checkTokenExpired())); + driver.navigate().refresh(); + } catch (Exception e) { + throw new RuntimeException("打开跟卖精灵失败,请确保已安装Chrome浏览器", e); + } } /** * 获取token验证token是否过期 @@ -67,23 +72,26 @@ public class GenmaiServiceImpl { /** * 登录 */ - @SneakyThrows public String login() { - Map requestBody = new HashMap<>(); - requestBody.put("nickname", "changzhu-4"); - requestBody.put("password", "123456QWe@"); - HttpEntity> entity = new HttpEntity<>(requestBody); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.TEXT_PLAIN); - ResponseEntity response = restTemplate.exchange("https://www.genmaijl.com/manage/user/subLogin", HttpMethod.POST, entity, String.class); - String body = response.getBody(); - JsonNode root = objectMapper.readTree(body); - requestBody.clear(); - String token= root.get("result").asText(); - HttpEntity updateEntity = new HttpEntity<>(token,headers); - ResponseEntity exchange = restTemplate.exchange(serverApiUrl + updateGenmaijlToken, HttpMethod.POST, updateEntity, String.class); - System.out.println(exchange.getBody()); - return token; + try { + Map requestBody = new HashMap<>(); + requestBody.put("nickname", "changzhu-4"); + requestBody.put("password", "123456QWe@"); + HttpEntity> entity = new HttpEntity<>(requestBody); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_PLAIN); + ResponseEntity response = restTemplate.exchange("https://www.genmaijl.com/manage/user/subLogin", HttpMethod.POST, entity, String.class); + String body = response.getBody(); + JsonNode root = objectMapper.readTree(body); + requestBody.clear(); + String token = root.get("result").asText(); + HttpEntity updateEntity = new HttpEntity<>(token, headers); + ResponseEntity exchange = restTemplate.exchange(serverApiUrl + updateGenmaijlToken, HttpMethod.POST, updateEntity, String.class); + System.out.println(exchange.getBody()); + return token; + } catch (Exception e) { + throw new RuntimeException("跟卖精灵登录失败", e); + } } } \ No newline at end of file diff --git a/erp_client_sb/src/main/java/com/tashow/erp/utils/DeviceUtils.java b/erp_client_sb/src/main/java/com/tashow/erp/utils/DeviceUtils.java index b732fbb..9e954c1 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/utils/DeviceUtils.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/utils/DeviceUtils.java @@ -194,7 +194,6 @@ public class DeviceUtils { return "SYS_" + SecureUtil.md5(combined).substring(0, 16).toUpperCase(); } catch (Exception e) { log.error("获取系统信息异常: {}", e.getMessage()); - // 最终的最终降级:时间戳哈希(不推荐,但保证不返回null) String fallbackId = "FALLBACK_" + SecureUtil.md5(String.valueOf(System.currentTimeMillis())).substring(0, 16).toUpperCase(); log.warn("使用最终降级方案(时间戳哈希),设备ID: {}", fallbackId); return fallbackId; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ClientAccountController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ClientAccountController.java index 6b695c2..fc1d4f6 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ClientAccountController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ClientAccountController.java @@ -259,7 +259,7 @@ public class ClientAccountController extends BaseController { clientAccount.setPermissions("{\"amazon\":true,\"rakuten\":true,\"zebra\":true}"); clientAccount.setPassword(passwordEncoder.encode(password)); clientAccount.setAccountType("trial"); - clientAccount.setDeviceLimit(3); + clientAccount.setDeviceLimit(1); clientAccount.setExpireTime(new Date(System.currentTimeMillis() + 3 * 24L * 60 * 60 * 1000)); int result = clientAccountService.insertClientAccount(clientAccount); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/ClientDeviceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/ClientDeviceController.java index 531f955..4383011 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/ClientDeviceController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/ClientDeviceController.java @@ -27,6 +27,10 @@ public class ClientDeviceController { return accountMapper.selectClientAccountByUsername(username); } + private int getDeviceLimit(ClientAccount account) { + return account.getDeviceLimit() != null ? account.getDeviceLimit() : 1; + } + private boolean exceedDeviceLimit(Long accountId, String deviceId, int limit) { int count = accountDeviceMapper.countActiveDevicesByAccountId(accountId); ClientAccountDevice binding = accountDeviceMapper.selectByAccountIdAndDeviceId(accountId, deviceId); @@ -37,22 +41,25 @@ public class ClientDeviceController { @GetMapping("/quota") public AjaxResult quota(@RequestParam String username) { ClientAccount account = getAccount(username); + if (account == null) return AjaxResult.error("账号不存在"); int used = accountDeviceMapper.countActiveDevicesByAccountId(account.getId()); - int limit = account.getDeviceLimit() != null ? account.getDeviceLimit() : 3; - return AjaxResult.success(Map.of("limit", limit, "used", used)); + return AjaxResult.success(Map.of("limit", getDeviceLimit(account), "used", used)); } @GetMapping("/list") public AjaxResult list(@RequestParam String username) { - return AjaxResult.success(accountDeviceMapper.selectDevicesByAccountId(getAccount(username).getId())); + ClientAccount account = getAccount(username); + if (account == null) return AjaxResult.error("账号不存在"); + return AjaxResult.success(accountDeviceMapper.selectDevicesByAccountId(account.getId())); } @PostMapping("/register") public AjaxResult register(@RequestBody Map data) { String username = data.get("username"); String deviceId = data.get("deviceId"); ClientAccount account = getAccount(username); - int limit = account.getDeviceLimit() != null ? account.getDeviceLimit() : 3; + if (account == null) return AjaxResult.error("账号不存在"); + int limit = getDeviceLimit(account); if (exceedDeviceLimit(account.getId(), deviceId, limit)) { return AjaxResult.error("设备数量已达上限(" + limit + "个)"); } @@ -62,17 +69,14 @@ public class ClientDeviceController { if (device == null) { device = new ClientDevice(); device.setDeviceId(deviceId); - device.setName(username + "@" + data.get("ip") + " (" + data.get("os") + ")"); - device.setOs(data.get("os")); - device.setIp(data.get("ip")); - device.setLocation(data.get("location")); device.setTrialExpireTime(new Date(System.currentTimeMillis() + 3 * 24L * 60 * 60 * 1000)); deviceMapper.insert(device); } + device.setName(username + "@" + data.get("computerName") + " (" + data.get("os") + ")"); + device.setOs(data.get("os")); + device.setIp(data.get("ip")); device.setStatus("online"); device.setLastActiveAt(now); - device.setIp(data.get("ip")); - device.setLocation(data.get("location")); deviceMapper.updateByDeviceId(device); ClientAccountDevice binding = accountDeviceMapper.selectByAccountIdAndDeviceId(account.getId(), deviceId); @@ -90,14 +94,8 @@ public class ClientDeviceController { return AjaxResult.success(); } - @PostMapping("/rename") - public AjaxResult rename(@RequestBody ClientDevice device) { - deviceMapper.updateByDeviceId(device); - return AjaxResult.success(); - } - - @PostMapping("/updateExpire") - public AjaxResult updateExpire(@RequestBody ClientDevice device) { + @PostMapping("/update") + public AjaxResult update(@RequestBody ClientDevice device) { deviceMapper.updateByDeviceId(device); return AjaxResult.success(); } @@ -106,9 +104,10 @@ public class ClientDeviceController { public AjaxResult remove(@RequestBody Map data) { String deviceId = data.get("deviceId"); String username = data.get("username"); - Long accountId = getAccount(username).getId(); + ClientAccount account = getAccount(username); + if (account == null) return AjaxResult.error("账号不存在"); - accountDeviceMapper.updateStatus(accountId, deviceId, "removed"); + accountDeviceMapper.updateStatus(account.getId(), deviceId, "removed"); sseHubService.sendEvent(username, deviceId, "DEVICE_REMOVED", "{}"); sseHubService.disconnectDevice(username, deviceId); return AjaxResult.success(); @@ -124,6 +123,4 @@ public class ClientDeviceController { } return AjaxResult.success(); } -} - - +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/monitor/account.js b/ruoyi-ui/src/api/monitor/account.js index e4e9650..ba2f59e 100644 --- a/ruoyi-ui/src/api/monitor/account.js +++ b/ruoyi-ui/src/api/monitor/account.js @@ -79,10 +79,10 @@ export function getDeviceList(username) { }) } -// 修改设备试用期过期时间 +// 更新设备信息 export function updateDeviceExpire(data) { return request({ - url: '/monitor/device/updateExpire', + url: '/monitor/device/update', method: 'post', data: data }) diff --git a/ruoyi-ui/src/views/monitor/account/index.vue b/ruoyi-ui/src/views/monitor/account/index.vue index 2743399..61f4381 100644 --- a/ruoyi-ui/src/views/monitor/account/index.vue +++ b/ruoyi-ui/src/views/monitor/account/index.vue @@ -148,16 +148,16 @@ - + - + - +