refactor(api):重构API服务接口与实现

- 移除多余的接口定义文件,简化依赖关系- 更新控制器和服务实现类的注入方式-优化请求参数处理逻辑
- 统一响应数据结构格式- 调整方法签名以提高一致性
- 删除冗余注释和无用代码- 修改系统API调用路径引用位置
- 简化认证服务实现并移除不必要的抽象层
- 优化Excel文件解析相关功能
- 清理无用的工具类和配置项
- 调整错误上报机制的依赖注入方式
- 更新跟卖精灵服务的实现细节- 优化HTTP请求工具函数结构
- 移除废弃的缓存管理服务接口定义
- 调整设备配额检查逻辑复用性
- 优化订单服务的数据返回格式
- 更新产品服务中的数据处理方式
- 重构客户端账户控制器中的设备限制检查逻辑
This commit is contained in:
2025-10-21 10:15:33 +08:00
parent 17f03c3ade
commit 281ae6a846
29 changed files with 237 additions and 599 deletions

View File

@@ -1,63 +1,42 @@
package com.tashow.erp.controller;
import com.tashow.erp.entity.AmazonProductEntity;
import com.tashow.erp.repository.AmazonProductRepository;
import com.tashow.erp.service.IAmazonScrapingService;
import com.tashow.erp.service.AmazonScrapingService;
import com.tashow.erp.utils.ExcelParseUtil;
import com.tashow.erp.utils.ExcelExportUtil;
import com.tashow.erp.utils.JsonData;
import com.tashow.erp.utils.LoggerUtil;
import com.tashow.erp.fx.controller.JavaBridge;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Optional;
@RestController
@RequestMapping("/api/amazon")
public class AmazonController {
private static final Logger logger = LoggerUtil.getLogger(AmazonController.class);
@Autowired
private IAmazonScrapingService amazonScrapingService;
private AmazonScrapingService amazonScrapingService;
@Autowired
private AmazonProductRepository amazonProductRepository;
/**
* 批量获取亚马逊产品信息
*/
@PostMapping("/products/batch")
public JsonData batchGetProducts(@RequestBody Object request) {
public JsonData batchGetProducts(@RequestBody Map<String, Object> request) {
@SuppressWarnings("unchecked")
Map<String, Object> requestMap = (Map<String, Object>) request;
List<String> asinList = (List<String>) requestMap.get("asinList");
String batchId = (String) requestMap.get("batchId");
String region = (String) requestMap.getOrDefault("region", "JP");
List<String> asinList = (List<String>) request.get("asinList");
String batchId = (String) request.get("batchId");
String region = (String) request.getOrDefault("region", "JP");
List<AmazonProductEntity> products = amazonScrapingService.batchGetProductInfo(asinList, batchId, region);
Map<String, Object> result = new HashMap<>();
result.put("products", products);
result.put("total", products.size());
return JsonData.buildSuccess(result);
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
}
/**
* 获取最新产品数据
*/
@GetMapping("/products/latest")
public JsonData getLatestProducts() {
List<AmazonProductEntity> products = amazonProductRepository.findLatestProducts();
Map<String, Object> result = new HashMap<>();
result.put("products", products);
result.put("total", products.size());
return JsonData.buildSuccess(result);
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
}
/**
* 解析Excel文件获取ASIN列表
*/
@PostMapping("/import/asin")
public JsonData importAsinFromExcel(@RequestParam("file") MultipartFile file) {
try {
@@ -65,16 +44,10 @@ public class AmazonController {
if (asinList.isEmpty()) {
return JsonData.buildError("未从文件中解析到ASIN数据");
}
Map<String, Object> result = new HashMap<>();
result.put("asinList", asinList);
result.put("total", asinList.size());
return JsonData.buildSuccess(result);
return JsonData.buildSuccess(Map.of("asinList", asinList, "total", asinList.size()));
} catch (Exception e) {
logger.error("解析文件失败: {}", e.getMessage(), e);
return JsonData.buildError("解析失败: " + e.getMessage());
}
}
}

View File

@@ -1,57 +1,45 @@
package com.tashow.erp.controller;
import com.tashow.erp.fx.controller.JavaBridge;
import com.tashow.erp.repository.BanmaOrderRepository;
import com.tashow.erp.service.IBanmaOrderService;
import com.tashow.erp.utils.ExcelExportUtil;
import com.tashow.erp.service.BanmaOrderService;
import com.tashow.erp.utils.JsonData;
import com.tashow.erp.utils.LoggerUtil;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/banma")
public class BanmaOrderController {
private static final Logger logger = LoggerUtil.getLogger(BanmaOrderController.class);
@Autowired
IBanmaOrderService banmaOrderService;
BanmaOrderService banmaOrderService;
@Autowired
BanmaOrderRepository banmaOrderRepository;
@GetMapping("/orders")
public ResponseEntity<Map<String, Object>> getOrders(
public JsonData getOrders(
@RequestParam(required = false, name = "accountId") Long accountId,
@RequestParam(required = false, name = "startDate") String startDate,
@RequestParam(required = false, name = "endDate") String endDate,
@RequestParam(defaultValue = "1", name = "page") int page,
@RequestParam(defaultValue = "10", name = "pageSize") int pageSize,
@RequestParam( "batchId") String batchId,
@RequestParam("batchId") String batchId,
@RequestParam(required = false, name = "shopIds") String shopIds) {
List<String> shopIdList = shopIds != null ? java.util.Arrays.asList(shopIds.split(",")) : null;
Map<String, Object> result = banmaOrderService.getOrdersByPage(accountId, startDate, endDate, page, pageSize, batchId, shopIdList);
return ResponseEntity.ok(result);
return result.containsKey("success") && !(Boolean)result.get("success")
? JsonData.buildError((String)result.get("message"))
: JsonData.buildSuccess(result);
}
/**
* 获取店铺列表
*/
@GetMapping("/shops")
public JsonData getShops(@RequestParam(required = false, name = "accountId") Long accountId) {
try {
Map<String, Object> response = banmaOrderService.getShops(accountId);
return JsonData.buildSuccess(response);
} catch (Exception e) {
logger.error("获取店铺列表失败: {}", e.getMessage(), e);
return JsonData.buildError("获取店铺列表失败: " + e.getMessage());
}
Map<String, Object> response = banmaOrderService.getShops(accountId);
return JsonData.buildSuccess(response);
}
/**
* 获取最新订单数据
*/
@GetMapping("/orders/latest")
public JsonData getLatestOrders() {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
@@ -68,8 +56,6 @@ public class BanmaOrderController {
})
.filter(order -> !order.isEmpty())
.toList();
return JsonData.buildSuccess(Map.of("orders", orders, "total", orders.size()));
}
}

View File

@@ -2,31 +2,19 @@ package com.tashow.erp.controller;
import com.tashow.erp.model.RakutenProduct;
import com.tashow.erp.model.SearchResult;
import com.tashow.erp.repository.RakutenProductRepository;
import com.tashow.erp.service.Alibaba1688Service;
import com.tashow.erp.service.IRakutenCacheService;
import com.tashow.erp.service.RakutenCacheService;
import com.tashow.erp.service.RakutenScrapingService;
import com.tashow.erp.service.impl.Alibaba1688ServiceImpl;
import com.tashow.erp.utils.DataReportUtil;
import com.tashow.erp.utils.ExcelParseUtil;
import com.tashow.erp.utils.JsonData;
import com.tashow.erp.utils.QiniuUtil;
import com.tashow.erp.fx.controller.JavaBridge;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.client.RestTemplate;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@RestController
@RequestMapping("/api/rakuten")
@@ -37,19 +25,10 @@ public class RakutenController {
@Autowired
private Alibaba1688Service alibaba1688Service;
@Autowired
private IRakutenCacheService rakutenCacheService;
@Autowired
private JavaBridge javaBridge;
private RakutenCacheService rakutenCacheService;
@Autowired
private DataReportUtil dataReportUtil;
/**
* 获取乐天商品数据
*
* @param file Excel文件首列为店铺名
* @param batchId 可选,批次号
* @return JsonData 响应
*/
@PostMapping(value = "/products")
public JsonData getProducts(@RequestParam("file") MultipartFile file, @RequestParam(value = "batchId", required = false) String batchId) {
try {
@@ -80,21 +59,23 @@ public class RakutenController {
if (!newProducts.isEmpty()) {
rakutenCacheService.saveProductsWithSessionId(newProducts, batchId);
}
// 4. 上报缓存数据使用情况
int cachedCount = allProducts.size() - newProducts.size();
if (cachedCount > 0) {
dataReportUtil.reportDataCollection("RAKUTEN_CACHE", cachedCount, "0");
}
return JsonData.buildSuccess(Map.of("products", allProducts, "total", allProducts.size(), "sessionId", batchId, "skippedShops", skippedShops, "newProductsCount", newProducts.size()));
return JsonData.buildSuccess(Map.of(
"products", allProducts,
"total", allProducts.size(),
"sessionId", batchId,
"skippedShops", skippedShops,
"newProductsCount", newProducts.size()
));
} catch (Exception e) {
log.error("获取乐天商品失败", e);
return JsonData.buildError("获取乐天商品失败: " + e.getMessage());
}
}
/**
* 1688识图搜索API - 自动保存1688搜索结果
*/
@PostMapping("/search1688")
public JsonData search1688(@RequestBody Map<String, Object> params) {
String imageUrl = (String) params.get("imageUrl");
@@ -109,21 +90,14 @@ public class RakutenController {
}
}
@GetMapping("/products/latest")
public JsonData getLatestProducts() {
try {
List<Map<String, Object>> products = rakutenScrapingService.getLatestProductsForDisplay();
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
} catch (Exception e) {
e.printStackTrace();
log.info("获取最新商品数据失败", e);
log.error("获取最新商品数据失败", e);
return JsonData.buildError("获取最新数据失败: " + e.getMessage());
}
}
}

View File

@@ -2,49 +2,36 @@ package com.tashow.erp.controller;
import com.tashow.erp.entity.AuthTokenEntity;
import com.tashow.erp.repository.AuthTokenRepository;
import com.tashow.erp.service.impl.CacheManagementServiceImpl;
import com.tashow.erp.service.CacheService;
import com.tashow.erp.service.impl.GenmaiServiceImpl;
import com.tashow.erp.utils.JsonData;
import com.tashow.erp.utils.LoggerUtil;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* 系统级接口控制器
* 整合:认证、配置、版本、工具、代理等功能
*/
@RestController
@RequestMapping("/api/system")
public class SystemController {
private static final Logger logger = LoggerUtil.getLogger(SystemController.class);
@Autowired
private AuthTokenRepository authTokenRepository;
@Autowired
private GenmaiServiceImpl genmaiService;
@Autowired
private CacheManagementServiceImpl cacheManagementService;
private CacheService cacheService;
@Autowired
private RestTemplate restTemplate;
@Value("${project.version:2.3.6}")
private String currentVersion;
@Value("${project.build.time:}")
private String buildTime;
@Value("${api.server.base-url}")
private String serverBaseUrl;
/**
* 保存认证密钥
*/
@PostMapping("/auth/save")
public JsonData saveAuth(@RequestBody Map<String, Object> data) {
String serviceName = (String) data.get("serviceName");
@@ -52,17 +39,13 @@ public class SystemController {
if (serviceName == null || authKey == null) {
return JsonData.buildError("serviceName和authKey不能为空");
}
AuthTokenEntity entity = authTokenRepository.findByServiceName(serviceName)
.orElse(new AuthTokenEntity());
AuthTokenEntity entity = authTokenRepository.findByServiceName(serviceName).orElse(new AuthTokenEntity());
entity.setServiceName(serviceName);
entity.setToken(authKey);
authTokenRepository.save(entity);
return JsonData.buildSuccess("认证信息保存成功");
}
/**
* 获取认证密钥
*/
@GetMapping("/auth/get")
public JsonData getAuth(@RequestParam String serviceName) {
return JsonData.buildSuccess(authTokenRepository.findByServiceName(serviceName)
@@ -70,82 +53,41 @@ public class SystemController {
.orElse(null));
}
/**
* 删除认证密钥
*/
@DeleteMapping("/auth/remove")
public JsonData removeAuth(@RequestParam String serviceName) {
authTokenRepository.findByServiceName(serviceName)
.ifPresent(authTokenRepository::delete);
authTokenRepository.findByServiceName(serviceName).ifPresent(authTokenRepository::delete);
return JsonData.buildSuccess("认证信息删除成功");
}
// ==================== 设备管理 ====================
/**
* 获取设备ID
*/
@GetMapping("/device-id")
public JsonData getDeviceId() {
String deviceId = com.tashow.erp.utils.DeviceUtils.generateDeviceId();
return JsonData.buildSuccess(deviceId);
return JsonData.buildSuccess(com.tashow.erp.utils.DeviceUtils.generateDeviceId());
}
/**
* 获取本机内网IP地址
*/
@GetMapping("/local-ip")
public JsonData getLocalIp() {
try {
java.net.InetAddress localHost = java.net.InetAddress.getLocalHost();
return JsonData.buildSuccess(localHost.getHostAddress());
return JsonData.buildSuccess(java.net.InetAddress.getLocalHost().getHostAddress());
} catch (Exception e) {
return JsonData.buildSuccess("127.0.0.1");
}
}
// ==================== 版本信息 ====================
/**
* 获取当前版本号
*/
@GetMapping("/version")
public Map<String, Object> getVersion() {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("currentVersion", currentVersion);
result.put("buildTime", buildTime);
return result;
return Map.of("success", true, "currentVersion", currentVersion, "buildTime", buildTime);
}
// ==================== 配置信息 ====================
/**
* 获取服务器配置
*/
@GetMapping("/config/server")
public Map<String, Object> getServerConfig() {
return Map.of(
"baseUrl", serverBaseUrl,
"sseUrl", serverBaseUrl + "/monitor/account/events"
);
return Map.of("baseUrl", serverBaseUrl, "sseUrl", serverBaseUrl + "/monitor/account/events");
}
// ==================== 工具功能 ====================
/**
* 打开跟卖精灵网页
*/
@PostMapping("/genmai/open")
public void openGenmaiWebsite() {
genmaiService.openGenmaiWebsite();
}
// ==================== 图片代理 ====================
/**
* 代理获取图片解决CORS跨域问题
*/
@GetMapping("/proxy/image")
public ResponseEntity<byte[]> proxyImage(@RequestParam("url") String imageUrl) {
if (imageUrl == null || imageUrl.isEmpty()) {
@@ -178,24 +120,15 @@ public class SystemController {
return new ResponseEntity<>(response.getBody(), responseHeaders, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
logger.error("代理图片失败: {}", imageUrl, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
// ==================== 缓存管理 ====================
/**
* 清理缓存
*/
@PostMapping("/cache/clear")
public JsonData clearCache() {
try {
cacheManagementService.clearCache();
return JsonData.buildSuccess("缓存清理成功");
} catch (Exception e) {
return JsonData.buildError("清理缓存失败: " + e.getMessage());
}
cacheService.clearCache();
return JsonData.buildSuccess("缓存清理成功");
}
}

View File

@@ -1,7 +1,7 @@
package com.tashow.erp.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tashow.erp.service.IAuthService;
import com.tashow.erp.service.impl.AuthServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@@ -10,16 +10,13 @@ import org.springframework.web.servlet.HandlerInterceptor;
import java.io.IOException;
import java.util.Base64;
/**
* 本地拦截器
*/
@Component
public class LocalJwtAuthInterceptor implements HandlerInterceptor {
private final IAuthService authService;
private final AuthServiceImpl authService;
private final ObjectMapper objectMapper = new ObjectMapper();
public LocalJwtAuthInterceptor(IAuthService authService) {
public LocalJwtAuthInterceptor(AuthServiceImpl authService) {
this.authService = authService;
}

View File

@@ -3,12 +3,7 @@ package com.tashow.erp.service;
import com.tashow.erp.entity.AmazonProductEntity;
import java.util.List;
/**
* 亚马逊数据采集服务接口
*
* @author ruoyi
*/
public interface IAmazonScrapingService {
public interface AmazonScrapingService {
/**
* 批量获取亚马逊产品信息
@@ -19,10 +14,5 @@ public interface IAmazonScrapingService {
* @return 产品信息列表
*/
List<AmazonProductEntity> batchGetProductInfo(List<String> asinList, String batchId, String region);
}
}

View File

@@ -3,12 +3,7 @@ package com.tashow.erp.service;
import java.util.List;
import java.util.Map;
/**
* 斑马订单服务接口
*
* @author ruoyi
*/
public interface IBanmaOrderService {
public interface BanmaOrderService {
// 客户端不再暴露刷新认证Token
@@ -30,3 +25,4 @@ public interface IBanmaOrderService {
*/
Map<String, Object> getOrdersByPage(Long accountId, String startDate, String endDate, int page, int pageSize, String batchId, List<String> shopIds);
}

View File

@@ -1,39 +1,49 @@
package com.tashow.erp.service.impl;
package com.tashow.erp.service;
import com.tashow.erp.entity.AuthTokenEntity;
import com.tashow.erp.repository.*;
import com.tashow.erp.service.ICacheManagementService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Optional;
/**
* 缓存管理服务实现
*/
@Service
public class CacheManagementServiceImpl implements ICacheManagementService {
public class CacheService {
private static final Logger logger = LoggerFactory.getLogger(CacheService.class);
@Autowired
private AuthTokenRepository authTokenRepository;
@Autowired
private RakutenProductRepository rakutenProductRepository;
@Autowired
private AmazonProductRepository amazonProductRepository;
@Autowired
private Alibaba1688ProductRepository alibaba1688ProductRepository;
@Autowired
private ZebraOrderRepository zebraOrderRepository;
@Autowired
private BanmaOrderRepository banmaOrderRepository;
@Autowired
private CacheDataRepository cacheDataRepository;
@Autowired
private UpdateStatusRepository updateStatusRepository;
@Override
public void saveAuthToken(String service, String token, long expireTimeMillis) {
try {
Optional<AuthTokenEntity> existing = authTokenRepository.findByServiceName(service);
AuthTokenEntity entity = existing.orElse(new AuthTokenEntity());
entity.setServiceName(service);
entity.setToken(token);
entity.setExpireTime(LocalDateTime.now().plusSeconds(expireTimeMillis / 1000));
authTokenRepository.save(entity);
} catch (Exception e) {
logger.error("保存认证令牌失败: {}", service, e);
}
}
@Transactional
public void clearCache() {
rakutenProductRepository.deleteAll();

View File

@@ -1,52 +0,0 @@
package com.tashow.erp.service;
import java.util.Map;
/**
* 认证服务接口
*/
public interface IAuthService {
/**
* 客户端登录认证
*/
Map<String, Object> login(String username, String password);
/**
* 获取客户端信息
*/
Map<String, Object> getClientInfo();
/**
* 上报错误
*/
void reportError(String errorType, String errorMessage, Exception e);
/**
* 检查版本更新
*/
String checkVersion(String currentVersion);
/**
* 获取客户端ID
*/
String getClientId();
void logout();
/**
* 验证token
*/
Map<String, Object> verifyToken(String token);
/**
* 注册新账号
*/
Map<String, Object> register(String username, String password);
/**
* 检查用户名是否可用
*/
boolean checkUsername(String username);
}

View File

@@ -1,12 +0,0 @@
package com.tashow.erp.service;
/**
* 缓存服务接口
*/
public interface ICacheService {
/**
* 保存认证令牌
*/
void saveAuthToken(String service, String token, long expireTimeMillis);
}

View File

@@ -1,18 +0,0 @@
package com.tashow.erp.service;
/**
* 跟卖精灵服务接口
*
* @author ruoyi
*/
public interface IGenmaiService {
/**
* 使用Playwright打开跟卖精灵网页
*
* @return 是否成功打开
*/
void openGenmaiWebsite();
}

View File

@@ -1,13 +1,9 @@
package com.tashow.erp.service;
import com.tashow.erp.model.RakutenProduct;
import java.util.List;
/**
* 乐天产品缓存服务接口
*/
public interface IRakutenCacheService {
public interface RakutenCacheService {
/**
* 保存产品数据
@@ -19,8 +15,6 @@ public interface IRakutenCacheService {
*/
void saveProductsWithSessionId(List<RakutenProduct> products, String sessionId);
/**
* 检查店铺是否有最近的数据12小时内
*/
@@ -45,6 +39,5 @@ public interface IRakutenCacheService {
* 清理指定店铺12小时内的重复数据为新采集做准备
*/
void cleanRecentDuplicateData(String shopName);
}
}

View File

@@ -1,6 +1,7 @@
package com.tashow.erp.service.impl;
import com.tashow.erp.entity.AmazonProductEntity;
import com.tashow.erp.repository.AmazonProductRepository;
import com.tashow.erp.service.AmazonScrapingService;
import com.tashow.erp.utils.DataReportUtil;
import com.tashow.erp.utils.ErrorReporter;
import com.tashow.erp.utils.RakutenProxyUtil;
@@ -20,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @author ruoyi
*/
@Service
public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PageProcessor {
public class AmazonScrapingServiceImpl implements AmazonScrapingService, PageProcessor {
@Autowired
private AmazonProductRepository amazonProductRepository;
@Autowired
@@ -68,8 +69,9 @@ public class AmazonScrapingServiceImpl implements IAmazonScrapingService, PagePr
if (isEmpty(price)) errorReporter.reportDataEmpty("amazon", asin, price);
if (isEmpty(seller)) errorReporter.reportDataEmpty("amazon", asin, seller);
AmazonProductEntity entity = new AmazonProductEntity();
entity.setAsin(asin != null ? asin : "");
entity.setAsin(asin == null ? "" : asin);
entity.setPrice(price);
entity.setSeller(seller);
resultCache.put(asin, entity);

View File

@@ -1,24 +1,17 @@
package com.tashow.erp.service.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tashow.erp.service.IAuthService;
import com.tashow.erp.utils.ApiForwarder;
import com.tashow.erp.utils.DeviceUtils;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* 认证服务实现类 - 简化版
* 仅提供错误上报和客户端信息获取功能
*/
@Service
public class AuthServiceImpl implements IAuthService {
public class AuthServiceImpl {
@Value("${project.version:2.1.0}")
private String appVersion;
@@ -29,10 +22,6 @@ public class AuthServiceImpl implements IAuthService {
@Getter
private String clientId = DeviceUtils.generateDeviceId();
/**
* 获取客户端基本信息
*/
@Override
public Map<String, Object> getClientInfo() {
Map<String, Object> info = new HashMap<>();
info.put("clientId", clientId);
@@ -41,10 +30,6 @@ public class AuthServiceImpl implements IAuthService {
return info;
}
/**
* 上报错误信息
*/
@Override
public void reportError(String errorType, String errorMessage, Exception e) {
try {
Map<String, Object> errorData = new HashMap<>();

View File

@@ -2,6 +2,8 @@ package com.tashow.erp.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tashow.erp.entity.BanmaOrderEntity;
import com.tashow.erp.repository.BanmaOrderRepository;
import com.tashow.erp.service.BanmaOrderService;
import com.tashow.erp.service.CacheService;
import com.tashow.erp.utils.DataReportUtil;
import com.tashow.erp.utils.ErrorReporter;
import com.tashow.erp.utils.LoggerUtil;
@@ -24,7 +26,7 @@ import java.util.stream.Collectors;
* @author ruoyi
*/
@Service
public class BanmaOrderServiceImpl {
public class BanmaOrderServiceImpl implements BanmaOrderService {
private static final Logger logger = LoggerUtil.getLogger(BanmaOrderServiceImpl.class);
private static final String API_URL = "https://banma365.cn/api/order/list?%srecipientName=&page=%d&size=%d&markFlag=0&state=4&_t=%d";
private static final String API_URL_WITH_TIME = "https://banma365.cn/api/order/list?%srecipientName=&page=%d&size=%d&markFlag=0&state=4&orderedAtStart=%s&orderedAtEnd=%s&_t=%d";
@@ -34,7 +36,7 @@ public class BanmaOrderServiceImpl {
private String ruoyiAdminBase;
private RestTemplate restTemplate;
private final ObjectMapper objectMapper = new ObjectMapper();
private final CacheServiceImpl cacheService;
private final CacheService cacheService;
private final BanmaOrderRepository banmaOrderRepository;
private final DataReportUtil dataReportUtil;
private final ErrorReporter errorReporter;
@@ -44,7 +46,7 @@ public class BanmaOrderServiceImpl {
private String currentBatchSessionId = null;
// 物流信息缓存,避免重复查询
private final Map<String, String> trackingInfoCache = new ConcurrentHashMap<>();
public BanmaOrderServiceImpl(BanmaOrderRepository banmaOrderRepository, CacheServiceImpl cacheService, DataReportUtil dataReportUtil, ErrorReporter errorReporter) {
public BanmaOrderServiceImpl(BanmaOrderRepository banmaOrderRepository, CacheService cacheService, DataReportUtil dataReportUtil, ErrorReporter errorReporter) {
this.banmaOrderRepository = banmaOrderRepository;
this.cacheService = cacheService;
this.dataReportUtil = dataReportUtil;
@@ -233,9 +235,6 @@ public class BanmaOrderServiceImpl {
return result;
}
/**
* 提取子订单字段
*/
private void extractSubOrderFields(Map<String, Object> simplifiedOrder, Map<String, Object> subOrder) {
String[] basicFields = {"orderedAt", "timeSinceOrder", "createdAt", "poTrackingNumber"};
String[] productFields = {"productTitle", "shopOrderNumber", "priceJpy", "productQuantity", "shippingFeeJpy", "productNumber", "serviceFee", "productImage"};
@@ -245,20 +244,11 @@ public class BanmaOrderServiceImpl {
Arrays.stream(purchaseFields).forEach(field -> simplifiedOrder.put(field, subOrder.get(field)));
}
/**
* 从API获取物流信息
*/
private String fetchTrackingInfo(String trackingNumber) {
// 优先尝试佐川物流
Map<String, Object> trackInfoMap = (Map<String, Object>) new SagawaExpressSdk().getTrackingInfo(trackingNumber).get("trackInfo");
if (trackInfoMap != null) {
return trackInfoMap.get("dateTime") + " " + trackInfoMap.get("office") + " " + trackInfoMap.get("status");
}
// 斑马API
ResponseEntity<Map> response = restTemplate.getForEntity(String.format(TRACKING_URL, trackingNumber), Map.class);
return Optional.ofNullable(response.getBody())
.filter(body -> Integer.valueOf(0).equals(body.get("code")))
@@ -268,9 +258,4 @@ public class BanmaOrderServiceImpl {
.map(track -> (String) track.get("track"))
.orElse("暂无物流信息");
}
}

View File

@@ -1,34 +0,0 @@
package com.tashow.erp.service.impl;
import com.tashow.erp.entity.AuthTokenEntity;
import com.tashow.erp.repository.AuthTokenRepository;
import com.tashow.erp.service.ICacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Optional;
@Service
public class CacheServiceImpl implements ICacheService {
private static final Logger logger = LoggerFactory.getLogger(CacheServiceImpl.class);
@Autowired
private AuthTokenRepository authTokenRepository;
@Override
public void saveAuthToken(String service, String token, long expireTimeMillis) {
try {
Optional<AuthTokenEntity> existing = authTokenRepository.findByServiceName(service);
AuthTokenEntity entity = existing.orElse(new AuthTokenEntity());
entity.setServiceName(service);
entity.setToken(token);
entity.setExpireTime(LocalDateTime.now().plusSeconds(expireTimeMillis / 1000));
authTokenRepository.save(entity);
} catch (Exception e) {
logger.error("保存认证令牌失败: {}", service, e);
}
}
}

View File

@@ -8,20 +8,15 @@ import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import com.tashow.erp.service.IGenmaiService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* 跟卖精灵服务实现类
*
* @author ruoyi
*/
@Service
public class GenmaiServiceImpl implements IGenmaiService {
public class GenmaiServiceImpl {
@Value("${api.server.base-url}")
private String serverApiUrl;
@Value("${api.server.paths.getGenmaijlToken}")
@@ -30,7 +25,6 @@ public class GenmaiServiceImpl implements IGenmaiService {
private String updateGenmaijlToken;
private final RestTemplate restTemplate = new RestTemplate();
ObjectMapper objectMapper = new ObjectMapper();
@Override
@SneakyThrows
public void openGenmaiWebsite() {
// 先关闭所有Chrome进程

View File

@@ -2,7 +2,7 @@ package com.tashow.erp.service.impl;
import com.tashow.erp.entity.RakutenProductEntity;
import com.tashow.erp.model.RakutenProduct;
import com.tashow.erp.repository.RakutenProductRepository;
import com.tashow.erp.service.IRakutenCacheService;
import com.tashow.erp.service.RakutenCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,7 +20,7 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
public class RakutenCacheServiceImpl implements IRakutenCacheService {
public class RakutenCacheServiceImpl implements RakutenCacheService {
@Autowired
private RakutenProductRepository repository;

View File

@@ -132,30 +132,24 @@ public class RakutenScrapingServiceImpl implements RakutenScrapingService {
}
}
/**
* 获取最新的产品数据用于前端展示
*/
@Override
public List<Map<String, Object>> getLatestProductsForDisplay() {
return rakutenProductRepository.findLatestProducts().stream().map(entity -> {
Map<String, Object> result = new HashMap<>();
result.put("originalShopName", Optional.ofNullable(entity.getOriginalShopName()).orElse(""));
result.put("productUrl", Optional.ofNullable(entity.getProductUrl()).orElse(""));
result.put("imgUrl", Optional.ofNullable(entity.getImgUrl()).orElse(""));
result.put("productTitle", Optional.ofNullable(entity.getProductTitle()).orElse(""));
result.put("price", Optional.ofNullable(entity.getPrice()).orElse(""));
result.put("ranking", Optional.ofNullable(entity.getRanking()).orElse(""));
result.put("image1688Url", Optional.ofNullable(entity.getImage1688Url()).orElse(""));
result.put("detailUrl1688", Optional.ofNullable(entity.getDetailUrl1688()).orElse(""));
// 使用正确的实体字段
result.put("mapRecognitionLink", Optional.ofNullable(entity.getMapRecognitionLink()).orElse(""));
result.put("originalShopName", entity.getOriginalShopName());
result.put("productUrl", entity.getProductUrl());
result.put("imgUrl", entity.getImgUrl());
result.put("productTitle", entity.getProductTitle());
result.put("price", entity.getPrice());
result.put("ranking", entity.getRanking());
result.put("image1688Url", entity.getImage1688Url());
result.put("detailUrl1688", entity.getDetailUrl1688());
result.put("mapRecognitionLink", entity.getMapRecognitionLink());
result.put("freight", entity.getFreight());
result.put("median", entity.getMedian());
result.put("weight", Optional.ofNullable(entity.getWeight()).orElse(""));
result.put("skuPrice",entity.getSkuPriceJson());
result.put("weight", entity.getWeight());
result.put("skuPrice", entity.getSkuPriceJson());
return result;
}).collect(Collectors.toList());
}
}

View File

@@ -8,12 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.tashow.erp.service.IAuthService;
/**
* 错误上报工具类 - 立即上报所有错误
*
* @author ERP
*/
import com.tashow.erp.service.impl.AuthServiceImpl;
@Component
public class ErrorReporter {
@@ -21,7 +17,7 @@ public class ErrorReporter {
private String serverUrl;
@Autowired
private IAuthService authService;
private AuthServiceImpl authService;
private final RestTemplate restTemplate = new RestTemplate();