feat(system): 新增方舟账号管理与任务接口
- 新增 MarkController 控制器,提供方舟任务列表获取和新建任务接口 - 实现 IMarkService 接口及 MarkServiceImpl 实现类,支持注册、登录和MD5加密功能 - 在 CacheConstants 中添加方舟账号 Redis key 常量 - 集成 RestTemplate用于调用方舟API,支持自动注册与登录机制- 添加文件上传支持,用于新建任务时提交文件 - 实现 token 失效自动重新登录逻辑,确保接口调用稳定性
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
package com.tashow.erp.config;
|
||||
import com.tashow.erp.utils.SeleniumStealthUtil;
|
||||
import com.tashow.erp.utils.SeleniumUtil;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
@@ -23,14 +23,14 @@ public class ChromeDriverPreloader implements ApplicationRunner {
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
new Thread(() -> {
|
||||
globalDriver = SeleniumStealthUtil.createDriver(true);
|
||||
globalDriver = SeleniumUtil.createDriver(true);
|
||||
log.info("ChromeDriver 预加载完成");
|
||||
}, "ChromeDriver-Preloader").start();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChromeDriver chromeDriver() {
|
||||
if (globalDriver == null) globalDriver = SeleniumStealthUtil.createDriver(true);
|
||||
if (globalDriver == null) globalDriver = SeleniumUtil.createDriver(true);
|
||||
return globalDriver;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 亚马逊数据控制器
|
||||
* 提供亚马逊商品采集、批量获取、Excel导入等功能
|
||||
*
|
||||
* @author 占子杰牛逼
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/amazon")
|
||||
public class AmazonController {
|
||||
@@ -23,6 +29,13 @@ public class AmazonController {
|
||||
@Autowired
|
||||
private AmazonProductRepository amazonProductRepository;
|
||||
|
||||
/**
|
||||
* 批量获取亚马逊商品信息
|
||||
*
|
||||
* @param request 包含asinList、batchId和region的请求参数
|
||||
* @param httpRequest HTTP请求对象,用于获取用户信息
|
||||
* @return 商品列表和总数
|
||||
*/
|
||||
@PostMapping("/products/batch")
|
||||
public JsonData batchGetProducts(@RequestBody Map<String, Object> request, HttpServletRequest httpRequest) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -39,6 +52,12 @@ public class AmazonController {
|
||||
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的亚马逊商品数据
|
||||
*
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 最新商品列表和总数
|
||||
*/
|
||||
@GetMapping("/products/latest")
|
||||
public JsonData getLatestProducts(HttpServletRequest request) {
|
||||
String username = JwtUtil.getUsernameFromRequest(request);
|
||||
@@ -56,6 +75,12 @@ public class AmazonController {
|
||||
return JsonData.buildSuccess(Map.of("products", products, "total", products.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Excel文件导入ASIN列表
|
||||
*
|
||||
* @param file Excel文件
|
||||
* @return ASIN列表和总数
|
||||
*/
|
||||
@PostMapping("/import/asin")
|
||||
public JsonData importAsinFromExcel(@RequestParam("file") MultipartFile file) {
|
||||
try {
|
||||
|
||||
@@ -12,6 +12,12 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 斑马订单控制器
|
||||
* 提供斑马订单查询、店铺列表等功能
|
||||
*
|
||||
* @author 占子杰牛逼
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/banma")
|
||||
public class BanmaOrderController {
|
||||
@@ -21,6 +27,19 @@ public class BanmaOrderController {
|
||||
@Autowired
|
||||
BanmaOrderRepository banmaOrderRepository;
|
||||
|
||||
/**
|
||||
* 分页查询斑马订单
|
||||
*
|
||||
* @param accountId 账号ID(可选)
|
||||
* @param startDate 开始日期(可选)
|
||||
* @param endDate 结束日期(可选)
|
||||
* @param page 页码,默认为1
|
||||
* @param pageSize 每页大小,默认为10
|
||||
* @param batchId 批次ID
|
||||
* @param shopIds 店铺ID列表,多个用逗号分隔(可选)
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 订单列表和分页信息
|
||||
*/
|
||||
@GetMapping("/orders")
|
||||
public JsonData getOrders(
|
||||
@RequestParam(required = false, name = "accountId") Long accountId,
|
||||
@@ -42,12 +61,25 @@ public class BanmaOrderController {
|
||||
? JsonData.buildError((String)result.get("message"))
|
||||
: JsonData.buildSuccess(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取店铺列表
|
||||
*
|
||||
* @param accountId 账号ID(可选)
|
||||
* @return 店铺列表
|
||||
*/
|
||||
@GetMapping("/shops")
|
||||
public JsonData getShops(@RequestParam(required = false, name = "accountId") Long accountId) {
|
||||
Map<String, Object> response = banmaOrderService.getShops(accountId);
|
||||
return JsonData.buildSuccess(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的斑马订单数据
|
||||
*
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 最新订单列表和总数
|
||||
*/
|
||||
@GetMapping("/orders/latest")
|
||||
public JsonData getLatestOrders(HttpServletRequest request) {
|
||||
String username = JwtUtil.getUsernameFromRequest(request);
|
||||
|
||||
@@ -15,6 +15,13 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 乐天数据控制器
|
||||
* 提供乐天商品采集、1688识图搜索等功能
|
||||
*
|
||||
* @author 占子杰牛逼
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/rakuten")
|
||||
@Slf4j
|
||||
@@ -28,6 +35,15 @@ public class RakutenController {
|
||||
@Autowired
|
||||
private DataReportUtil dataReportUtil;
|
||||
|
||||
/**
|
||||
* 从Excel获取乐天商品信息
|
||||
* 支持缓存机制,避免重复采集
|
||||
*
|
||||
* @param file 包含店铺名称的Excel文件
|
||||
* @param batchId 批次ID(可选)
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 商品列表、总数、跳过的店铺等信息
|
||||
*/
|
||||
@PostMapping(value = "/products")
|
||||
public JsonData getProducts(@RequestParam("file") MultipartFile file, @RequestParam(value = "batchId", required = false) String batchId, HttpServletRequest request) {
|
||||
try {
|
||||
@@ -80,6 +96,14 @@ public class RakutenController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1688识图搜索
|
||||
* 根据图片URL在1688平台进行识图搜索
|
||||
*
|
||||
* @param params 包含imageUrl和sessionId的参数
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 搜索结果
|
||||
*/
|
||||
@PostMapping("/search1688")
|
||||
public JsonData search1688(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||
String imageUrl = (String) params.get("imageUrl");
|
||||
@@ -99,6 +123,12 @@ public class RakutenController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的乐天商品数据
|
||||
*
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 最新商品列表和总数
|
||||
*/
|
||||
@GetMapping("/products/latest")
|
||||
public JsonData getLatestProducts(HttpServletRequest request) {
|
||||
try {
|
||||
|
||||
@@ -13,6 +13,13 @@ import org.springframework.http.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统管理控制器
|
||||
* 提供系统配置、认证管理、设备信息等功能
|
||||
*
|
||||
* @author 占子杰牛逼
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/system")
|
||||
public class SystemController {
|
||||
@@ -31,6 +38,13 @@ public class SystemController {
|
||||
private String buildTime;
|
||||
@Value("${api.server.base-url}")
|
||||
private String serverBaseUrl;
|
||||
|
||||
/**
|
||||
* 保存服务认证信息
|
||||
*
|
||||
* @param data 包含serviceName和authKey的认证信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/auth/save")
|
||||
public JsonData saveAuth(@RequestBody Map<String, Object> data) {
|
||||
String serviceName = (String) data.get("serviceName");
|
||||
@@ -45,6 +59,12 @@ public class SystemController {
|
||||
return JsonData.buildSuccess("认证信息保存成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定服务的认证信息
|
||||
*
|
||||
* @param serviceName 服务名称
|
||||
* @return 认证token信息
|
||||
*/
|
||||
@GetMapping("/auth/get")
|
||||
public JsonData getAuth(@RequestParam String serviceName) {
|
||||
return JsonData.buildSuccess(authTokenRepository.findByServiceName(serviceName)
|
||||
@@ -52,36 +72,76 @@ public class SystemController {
|
||||
.orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定服务的认证信息
|
||||
*
|
||||
* @param serviceName 服务名称
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/auth/remove")
|
||||
public JsonData removeAuth(@RequestParam String serviceName) {
|
||||
authTokenRepository.findByServiceName(serviceName).ifPresent(authTokenRepository::delete);
|
||||
return JsonData.buildSuccess("认证信息删除成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备唯一标识
|
||||
*
|
||||
* @return 设备ID
|
||||
*/
|
||||
@GetMapping("/device-id")
|
||||
public JsonData getDeviceId() {
|
||||
return JsonData.buildSuccess(com.tashow.erp.utils.DeviceUtils.generateDeviceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本机IP地址
|
||||
*
|
||||
* @return 本机IP地址
|
||||
* @throws Exception 获取IP失败时抛出异常
|
||||
*/
|
||||
@GetMapping("/local-ip")
|
||||
public JsonData getLocalIp() throws Exception {
|
||||
return JsonData.buildSuccess(java.net.InetAddress.getLocalHost().getHostAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取计算机名称
|
||||
*
|
||||
* @return 计算机名称
|
||||
*/
|
||||
@GetMapping("/computer-name")
|
||||
public JsonData getComputerName() {
|
||||
return JsonData.buildSuccess(System.getenv("COMPUTERNAME"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统版本信息
|
||||
*
|
||||
* @return 包含当前版本号和构建时间的信息
|
||||
*/
|
||||
@GetMapping("/version")
|
||||
public Map<String, Object> getVersion() {
|
||||
return Map.of("success", true, "currentVersion", currentVersion, "buildTime", buildTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器配置信息
|
||||
*
|
||||
* @return 包含服务器基础URL和SSE URL的配置信息
|
||||
*/
|
||||
@GetMapping("/config/server")
|
||||
public Map<String, Object> getServerConfig() {
|
||||
return Map.of("baseUrl", serverBaseUrl, "sseUrl", serverBaseUrl + "/monitor/account/events");
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开跟卖精灵网站
|
||||
*
|
||||
* @param accountId 账号ID
|
||||
* @param request HTTP请求对象,用于获取用户信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/genmai/open")
|
||||
public JsonData openGenmaiWebsite(@RequestParam(required = false) Long accountId, HttpServletRequest request) {
|
||||
try {
|
||||
@@ -94,6 +154,13 @@ public class SystemController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片代理接口
|
||||
* 用于代理获取外部图片资源,解决跨域问题
|
||||
*
|
||||
* @param imageUrl 图片URL
|
||||
* @return 图片字节数组响应
|
||||
*/
|
||||
@GetMapping("/proxy/image")
|
||||
public ResponseEntity<byte[]> proxyImage(@RequestParam("url") String imageUrl) {
|
||||
if (imageUrl == null || imageUrl.isEmpty()) {
|
||||
@@ -130,6 +197,11 @@ public class SystemController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理系统缓存
|
||||
*
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/cache/clear")
|
||||
public JsonData clearCache() {
|
||||
cacheService.clearCache();
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.tashow.erp.test;
|
||||
|
||||
import com.tashow.erp.utils.DeviceUtils;
|
||||
|
||||
/**
|
||||
* 设备ID获取测试
|
||||
* 独立运行,不依赖 Spring Boot
|
||||
*/
|
||||
public class DeviceIdTest {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=================================");
|
||||
System.out.println("设备ID获取测试");
|
||||
System.out.println("=================================\n");
|
||||
|
||||
try {
|
||||
String deviceId = DeviceUtils.generateDeviceId();
|
||||
System.out.println("✓ 成功获取设备ID: " + deviceId);
|
||||
System.out.println("\n设备ID格式说明:");
|
||||
System.out.println(" MGUID_ - Windows MachineGuid(最可靠)");
|
||||
System.out.println(" HW_ - 硬件UUID");
|
||||
System.out.println(" CPU_ - 处理器ID");
|
||||
System.out.println(" MB_ - 主板序列号");
|
||||
System.out.println(" MAC_ - MAC地址");
|
||||
System.out.println(" SYS_ - 系统信息组合");
|
||||
|
||||
// 再次获取,验证稳定性
|
||||
System.out.println("\n验证稳定性(再次获取):");
|
||||
String deviceId2 = DeviceUtils.generateDeviceId();
|
||||
System.out.println("第二次获取: " + deviceId2);
|
||||
|
||||
if (deviceId.equals(deviceId2)) {
|
||||
System.out.println("✓ 设备ID稳定,两次获取结果一致");
|
||||
} else {
|
||||
System.out.println("✗ 警告:设备ID不稳定,两次获取结果不同");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("✗ 获取设备ID失败:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("\n=================================");
|
||||
System.out.println("测试完成");
|
||||
System.out.println("=================================");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.tashow.erp.test;
|
||||
import com.tashow.erp.utils.DeviceUtils;
|
||||
import java.util.regex.Pattern;
|
||||
public class SeleniumWithProfile {
|
||||
private static final Pattern WEIGHT_PATTERN = Pattern.compile("\"(?:unitWeight|weight)\":(\\d+(?:\\.\\d+)?)");
|
||||
public static void main(String[] args) {
|
||||
// 使用新的 DeviceUtils 获取设备ID
|
||||
String deviceId = DeviceUtils.generateDeviceId();
|
||||
System.out.println("设备ID: " + deviceId);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,6 @@ public class Alibaba1688CookieUtil {
|
||||
}
|
||||
cookieBuilder.append(entry.getKey()).append("=").append(entry.getValue());
|
||||
}
|
||||
|
||||
return cookieBuilder.toString();
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package com.tashow.erp.utils;
|
||||
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Selenium 防检测工具类
|
||||
* 提供配置好的 ChromeDriver,隐藏自动化痕迹
|
||||
*/
|
||||
public class SeleniumStealthUtil {
|
||||
public class SeleniumUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 创建防检测的 ChromeDriver
|
||||
@@ -3,11 +3,15 @@ import org.openqa.selenium.JavascriptExecutor;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
public class TrademarkCheckUtil {
|
||||
@Autowired
|
||||
private ChromeDriver driver;
|
||||
@Autowired
|
||||
RestTemplate restTemplate;
|
||||
|
||||
public boolean checkTrademark(String brandName) {
|
||||
try {
|
||||
driver.get("https://tmsearch.uspto.gov/search/search-results");
|
||||
@@ -34,4 +38,5 @@ public class TrademarkCheckUtil {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user