diff --git a/electron-vue-template/src/renderer/components/common/SettingsDialog.vue b/electron-vue-template/src/renderer/components/common/SettingsDialog.vue index 7a14d09..e2511d8 100644 --- a/electron-vue-template/src/renderer/components/common/SettingsDialog.vue +++ b/electron-vue-template/src/renderer/components/common/SettingsDialog.vue @@ -178,7 +178,7 @@ async function resetAllSettings() { async function handleClearCache() { try { await ElMessageBox.confirm( - '确定要清理客户端缓存吗?将清除所有缓存数据、更新文件及相关状态(不影响登录状态)', + '确定要清理客户端缓存吗?将清除本地设备的所有缓存数据、更新文件及相关状态(不影响登录状态)', '确认清理', { confirmButtonText: '确定', @@ -503,7 +503,7 @@ onMounted(() => {
- 清理应用缓存数据,不影响登录状态 + 清理本地设备的所有缓存数据,不影响登录状态 com.tashow.erp erp_client_sb - 2.5.3 + 2.5.5 erp_client_sb erp客户端 diff --git a/erp_client_sb/src/main/java/com/tashow/erp/controller/AmazonController.java b/erp_client_sb/src/main/java/com/tashow/erp/controller/AmazonController.java index 638ca78..999c70c 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/controller/AmazonController.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/controller/AmazonController.java @@ -42,7 +42,17 @@ public class AmazonController { @GetMapping("/products/latest") public JsonData getLatestProducts(HttpServletRequest request) { String username = JwtUtil.getUsernameFromRequest(request); - List products = amazonProductRepository.findLatestProducts(username); + List recentSessions = amazonProductRepository.findRecentSessionIds(org.springframework.data.domain.PageRequest.of(0, 1)); + String latestSession = recentSessions.stream() + .filter(sid -> sid != null && sid.startsWith(username + "#")) + .findFirst() + .orElse(""); + + if (latestSession.isEmpty()) { + return JsonData.buildSuccess(Map.of("products", List.of(), "total", 0)); + } + + List products = amazonProductRepository.findBySessionIdOrderByCreatedAtDesc(latestSession); return JsonData.buildSuccess(Map.of("products", products, "total", products.size())); } 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 7665989..c0d7d8f 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 @@ -83,9 +83,10 @@ public class SystemController { } @PostMapping("/genmai/open") - public JsonData openGenmaiWebsite(@RequestParam(required = false) Long accountId) { + public JsonData openGenmaiWebsite(@RequestParam(required = false) Long accountId, HttpServletRequest request) { try { - genmaiService.openGenmaiWebsite(accountId); + String username = com.tashow.erp.utils.JwtUtil.getUsernameFromRequest(request); + genmaiService.openGenmaiWebsite(accountId, username); return JsonData.buildSuccess("跟卖精灵已打开"); } catch (Exception e) { logger.error("打开跟卖精灵失败", e); @@ -130,9 +131,8 @@ public class SystemController { } @PostMapping("/cache/clear") - public JsonData clearCache(HttpServletRequest request) { - String username = com.tashow.erp.utils.JwtUtil.getUsernameFromRequest(request); - cacheService.clearCache(username); + public JsonData clearCache() { + cacheService.clearCache(); return JsonData.buildSuccess("缓存清理成功"); } } diff --git a/erp_client_sb/src/main/java/com/tashow/erp/repository/AmazonProductRepository.java b/erp_client_sb/src/main/java/com/tashow/erp/repository/AmazonProductRepository.java index d2cc5b4..6eb0d3b 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/repository/AmazonProductRepository.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/repository/AmazonProductRepository.java @@ -64,10 +64,10 @@ public interface AmazonProductRepository extends JpaRepository findLatestProducts(); /** - * 获取指定用户最新会话的产品数据(按用户隔离) + * 获取指定用户最新会话的产品数据(按用户和地区隔离) */ - @Query(value = "SELECT * FROM amazon_products WHERE session_id = (SELECT session_id FROM amazon_products WHERE session_id LIKE :username || '#%' GROUP BY session_id ORDER BY session_id DESC LIMIT 1) ORDER BY updated_at ", nativeQuery = true) - List findLatestProducts(@Param("username") String username); + @Query(value = "SELECT * FROM amazon_products WHERE session_id = (SELECT session_id FROM amazon_products WHERE session_id LIKE :username || '#%' AND region = :region GROUP BY session_id ORDER BY session_id DESC LIMIT 1) ORDER BY updated_at ", nativeQuery = true) + List findLatestProducts(@Param("username") String username, @Param("region") String region); /** * 删除指定ASIN在指定时间后的数据(用于清理12小时内重复) diff --git a/erp_client_sb/src/main/java/com/tashow/erp/service/CacheService.java b/erp_client_sb/src/main/java/com/tashow/erp/service/CacheService.java index 34a72a6..23bcd1e 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/service/CacheService.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/service/CacheService.java @@ -1,9 +1,6 @@ package com.tashow.erp.service; import com.tashow.erp.entity.AuthTokenEntity; -import com.tashow.erp.entity.RakutenProductEntity; -import com.tashow.erp.entity.AmazonProductEntity; -import com.tashow.erp.entity.BanmaOrderEntity; import com.tashow.erp.repository.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; -import java.util.List; import java.util.Optional; @Service @@ -49,39 +45,26 @@ public class CacheService { } @Transactional - public void clearCache(String username) { - if (username == null || username.isEmpty()) { - logger.warn("尝试清理缓存但未提供用户名,操作已跳过"); - return; - } + public void clearCache() { + - logger.info("开始清理用户缓存: {}", username); + // 清理所有产品数据 + rakutenProductRepository.deleteAll(); + - // 清理当前用户的 Rakuten 产品数据 - List rakutenProducts = rakutenProductRepository.findAll(); - List userRakutenProducts = rakutenProducts.stream() - .filter(p -> p.getSessionId() != null && p.getSessionId().startsWith(username + "#")) - .toList(); - rakutenProductRepository.deleteAll(userRakutenProducts); - logger.info("已清理 {} 条 Rakuten 产品数据", userRakutenProducts.size()); + amazonProductRepository.deleteAll(); + - // 清理当前用户的 Amazon 产品数据 - List amazonProducts = amazonProductRepository.findAll(); - List userAmazonProducts = amazonProducts.stream() - .filter(p -> p.getSessionId() != null && p.getSessionId().startsWith(username + "#")) - .toList(); - amazonProductRepository.deleteAll(userAmazonProducts); - logger.info("已清理 {} 条 Amazon 产品数据", userAmazonProducts.size()); + alibaba1688ProductRepository.deleteAll(); + - // 清理当前用户的 Banma 订单数据 - List banmaOrders = banmaOrderRepository.findAll(); - List userBanmaOrders = banmaOrders.stream() - .filter(o -> o.getSessionId() != null && o.getSessionId().startsWith(username + "#")) - .toList(); - banmaOrderRepository.deleteAll(userBanmaOrders); - logger.info("已清理 {} 条 Banma 订单数据", userBanmaOrders.size()); - - logger.info("用户 {} 的缓存清理完成", username); + // 清理所有订单数据 + banmaOrderRepository.deleteAll(); + + zebraOrderRepository.deleteAll(); + // 清理通用缓存和更新状态 + cacheDataRepository.deleteAll(); + } } diff --git a/erp_client_sb/src/main/java/com/tashow/erp/service/impl/AmazonScrapingServiceImpl.java b/erp_client_sb/src/main/java/com/tashow/erp/service/impl/AmazonScrapingServiceImpl.java index 621415e..3b27f06 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/service/impl/AmazonScrapingServiceImpl.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/service/impl/AmazonScrapingServiceImpl.java @@ -61,7 +61,6 @@ public class AmazonScrapingServiceImpl implements AmazonScrapingService, PagePro if (isEmpty(seller)) { seller = html.xpath("//span[@class='a-size-small offer-display-feature-text-message']/text()").toString(); } - // 关键数据为空时重试 if (isEmpty(price) && isEmpty(seller)) { throw new RuntimeException("Retry this page"); @@ -94,6 +93,8 @@ public class AmazonScrapingServiceImpl implements AmazonScrapingService, PagePro String sessionId = (batchId != null) ? batchId : "SINGLE_" + UUID.randomUUID(); LocalDateTime batchTime = LocalDateTime.now(); + resultCache.clear(); + // 第一步:清理1小时前的所有旧数据 amazonProductRepository.deleteAllDataBefore(LocalDateTime.now().minusHours(1)); @@ -110,7 +111,12 @@ public class AmazonScrapingServiceImpl implements AmazonScrapingService, PagePro Optional cached = amazonProductRepository.findByAsinAndRegion(cleanAsin, region); if (cached.isPresent() && !isEmpty(cached.get().getPrice()) && !isEmpty(cached.get().getSeller())) { - AmazonProductEntity entity = cached.get(); + AmazonProductEntity cachedEntity = cached.get(); + AmazonProductEntity entity = new AmazonProductEntity(); + entity.setAsin(cachedEntity.getAsin()); + entity.setRegion(cachedEntity.getRegion()); + entity.setPrice(cachedEntity.getPrice()); + entity.setSeller(cachedEntity.getSeller()); entity.setSessionId(sessionId); entity.setUpdatedAt(LocalDateTime.now()); amazonProductRepository.save(entity); 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 df3eff6..2956b14 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 @@ -19,17 +19,17 @@ public class GenmaiServiceImpl { private final RestTemplate restTemplate = new RestTemplate(); private final ObjectMapper objectMapper = new ObjectMapper(); - public void openGenmaiWebsite(Long accountId) throws Exception { - String token = getAndValidateToken(accountId); + public void openGenmaiWebsite(Long accountId, String username) throws Exception { + String token = getAndValidateToken(accountId, username); Runtime.getRuntime().exec("taskkill /f /im chrome.exe"); Thread.sleep(1000); ChromeOptions options = new ChromeOptions(); - String username = System.getProperty("user.name"); - char firstChar = username.charAt(0); + String systemUser = System.getProperty("user.name"); + char firstChar = systemUser.charAt(0); char flipped = Character.isUpperCase(firstChar) ? Character.toLowerCase(firstChar) : Character.toUpperCase(firstChar); String chromeUserData = System.getProperty("user.home") - .replace(username, UrlUtils.urlEncode(flipped + username.substring(1))) + .replace(systemUser, UrlUtils.urlEncode(flipped + systemUser.substring(1))) + "\\AppData\\Local\\Google\\Chrome\\User Data"; options.addArguments("user-data-dir=" + chromeUserData.toLowerCase(), "profile-directory=Default"); @@ -40,8 +40,9 @@ public class GenmaiServiceImpl { } @SuppressWarnings("unchecked") - private String getAndValidateToken(Long accountId) { - Map resp = restTemplate.getForObject(serverApiUrl + "/tool/genmai/accounts", Map.class); + private String getAndValidateToken(Long accountId, String username) { + String url = serverApiUrl + "/tool/genmai/accounts?name=" + username; + Map resp = restTemplate.getForObject(url, Map.class); List> list = (List>) resp.get("data"); Map account = accountId != null @@ -49,12 +50,10 @@ public class GenmaiServiceImpl { : list.get(0); String token = (String) account.get("token"); Long id = ((Number) account.get("id")).longValue(); - // 验证token是否有效 + if (!validateToken(token)) { - // token无效,调用服务器刷新 restTemplate.postForObject(serverApiUrl + "/tool/genmai/accounts/" + id + "/validate", null, Map.class); - // 重新获取token - resp = restTemplate.getForObject(serverApiUrl + "/tool/genmai/accounts", Map.class); + resp = restTemplate.getForObject(url, Map.class); list = (List>) resp.get("data"); account = list.stream().filter(m -> id.equals(((Number) m.get("id")).longValue())).findFirst().orElse(null); token = (String) account.get("token"); @@ -69,8 +68,7 @@ public class GenmaiServiceImpl { ResponseEntity response = restTemplate.exchange( "https://www.genmaijl.com/manage/user/balance", HttpMethod.GET, new HttpEntity<>(headers), String.class); - JsonNode root = objectMapper.readTree(response.getBody()); - return root.get("code").asInt() == 0; + return objectMapper.readTree(response.getBody()).get("code").asInt() == 0; } catch (Exception e) { return false; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/GenmaiAccountController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/GenmaiAccountController.java index c2fdbd4..afae6bb 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/GenmaiAccountController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/GenmaiAccountController.java @@ -42,6 +42,7 @@ public class GenmaiAccountController { public R saveAccount(@RequestBody GenmaiAccount body, String name) { if (body.getId() == null) { String token = accountService.validateAndGetToken(body.getUsername(), body.getPassword()); + if (token == null) throw new RuntimeException("账号密码验证失败,请检查后重试"); body.setToken(token); body.setTokenExpireAt(new Date(System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000)); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GenmaiAccountServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GenmaiAccountServiceImpl.java index 2ffe3e7..1ed6960 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GenmaiAccountServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GenmaiAccountServiceImpl.java @@ -7,6 +7,7 @@ import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; @@ -76,10 +77,11 @@ public class GenmaiAccountServiceImpl implements IGenmaiAccountService { @Override public boolean validateToken(String token) { try { - HttpEntity entity = new HttpEntity<>(null, null); + HttpHeaders headers = new HttpHeaders(); + headers.set("Token", token); ResponseEntity response = restTemplate.exchange( "https://www.genmaijl.com/manage/user/balance", - HttpMethod.GET, entity, String.class); + HttpMethod.GET, new HttpEntity<>(headers), String.class); return objectMapper.readTree(response.getBody()).get("code").asInt() == 0; } catch (Exception e) { return false;