feat(amazon): 实现商标筛查功能并优化用户体验

- 添加商标筛查面板和相关API接口- 实现Excel文件解析和数据过滤功能
- 添加文件上传进度跟踪和错误处理-优化空状态显示和操作引导- 实现tab状态持久化存储
- 添加订阅会员弹窗和付费入口
-优化文件选择和删除功能
- 改进UI样式和响应式布局
This commit is contained in:
2025-11-06 11:07:05 +08:00
parent 4e2ce48934
commit cfb70d5830
26 changed files with 1395 additions and 383 deletions

View File

@@ -25,16 +25,13 @@ import java.util.*;
@Anonymous
public class MarkController {
private static final String API_SECRET = "e10adc3949ba59abbe56e057f20f883e";
// erp_client_sb 服务地址
private static final String ERP_CLIENT_BASE_URL = "http://127.0.0.1:8081";
private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private RedisCache redisCache;
@Autowired
private IMarkService markService;
/**
* 获取任务列表
*/
@@ -82,42 +79,49 @@ public class MarkController {
dNode = reJson.get("D").get("items").get(0);
downloadUrl = reJson.get("D").get("items").get(0).get("download_url").asText();
}
String tempFilePath = System.getProperty("java.io.tmpdir") + "/trademark_" + System.currentTimeMillis() + ".xlsx";
HttpUtil.downloadFile(downloadUrl, FileUtil.file(tempFilePath));
List<Map<String, Object>> filteredData = new ArrayList<>();
List<String> excelHeaders = new ArrayList<>();
ExcelReader reader = null;
try {
reader = ExcelUtil.getReader(FileUtil.file(tempFilePath));
List<List<Object>> rows = reader.read();
// 找到各列的索引
int asinIndex = -1, brandIndex = -1, trademarkTypeIndex = -1, registerDateIndex = -1, productImageIndex = -1;
if (!rows.isEmpty()) {
List<Object> header = rows.get(0);
for (int i = 0; i < header.size(); i++) {
String headerName = header.get(i).toString().trim();
if (headerName.equals("ASIN")) asinIndex = i;
else if (headerName.equals("品牌")) brandIndex = i;
else if (headerName.equals("商标类型")) trademarkTypeIndex = i;
else if (headerName.equals("注册时间")) registerDateIndex = i;
else if (headerName.equals("商品主图")) productImageIndex = i;
if (rows.isEmpty()) {
throw new RuntimeException("Excel文件为空");
}
// 读取表头
List<Object> headerRow = rows.get(0);
for (Object cell : headerRow) {
excelHeaders.add(cell != null ? cell.toString().trim() : "");
}
// 找到商标类型列的索引
int trademarkTypeIndex = -1;
for (int i = 0; i < excelHeaders.size(); i++) {
if ("商标类型".equals(excelHeaders.get(i))) {
trademarkTypeIndex = i;
break;
}
}
// 过滤TM和未注册数据
if (trademarkTypeIndex < 0) {
throw new RuntimeException("未找到'商标类型'列");
}
// 过滤TM和未注册数据保留所有列
for (int i = 1; i < rows.size(); i++) {
List<Object> row = rows.get(i);
if (trademarkTypeIndex >= 0 && row.size() > trademarkTypeIndex) {
if (row.size() > trademarkTypeIndex) {
String trademarkType = row.get(trademarkTypeIndex).toString().trim();
if ("TM".equals(trademarkType) || "未注册".equals(trademarkType)) {
Map<String, Object> item = new HashMap<>();
if (asinIndex >= 0 && row.size() > asinIndex) item.put("ASIN", row.get(asinIndex));
if (brandIndex >= 0 && row.size() > brandIndex) item.put("品牌", row.get(brandIndex));
if (trademarkTypeIndex >= 0 && row.size() > trademarkTypeIndex) item.put("商标类型", row.get(trademarkTypeIndex));
if (registerDateIndex >= 0 && row.size() > registerDateIndex) item.put("注册时间", row.get(registerDateIndex));
if (productImageIndex >= 0 && row.size() > productImageIndex) item.put("商品主图", row.get(productImageIndex));
// 保存所有列的数据
for (int j = 0; j < excelHeaders.size() && j < row.size(); j++) {
item.put(excelHeaders.get(j), row.get(j));
}
filteredData.add(item);
}
}
@@ -131,6 +135,7 @@ public class MarkController {
Map<String, Object> combinedResult = new HashMap<>();
combinedResult.put("original", dNode);
combinedResult.put("filtered", filteredData);
combinedResult.put("headers", excelHeaders);
return AjaxResult.success(combinedResult);
} catch (Exception e) {
@@ -138,7 +143,6 @@ public class MarkController {
}
}
// 新建任务
@PostMapping("newTask")
public AjaxResult newTask(@RequestParam("file") MultipartFile file) {

View File

@@ -108,11 +108,6 @@ spring:
max-wait: 10s
# 关闭超时时间
shutdown-timeout: 100ms
# 心跳检测配置
cluster:
refresh:
adaptive: true
period: 30s
# token配置
token:
# 令牌自定义标识