去重导出列固定顺序为 id/ASIN/国家/价格/品牌;QueryAsin 按店铺加载数据并修正前端回退逻辑
Build Backend JAR / build (push) Has been cancelled
Build Backend JAR / build (push) Has been cancelled
This commit is contained in:
+33
-3
@@ -47,6 +47,7 @@ public class DedupeRunService {
|
|||||||
|
|
||||||
private static final String HEADER_SPLIT_MARKER = "idASIN国家状态价格变体数量";
|
private static final String HEADER_SPLIT_MARKER = "idASIN国家状态价格变体数量";
|
||||||
private static final String HEADER_STOP_COLUMN = "缩略图地址8";
|
private static final String HEADER_STOP_COLUMN = "缩略图地址8";
|
||||||
|
private static final List<String> EXPORT_COLUMN_PRIORITY = List.of("id", "ASIN", "国家", "价格", "品牌");
|
||||||
|
|
||||||
private final FileTaskMapper fileTaskMapper;
|
private final FileTaskMapper fileTaskMapper;
|
||||||
private final FileResultMapper fileResultMapper;
|
private final FileResultMapper fileResultMapper;
|
||||||
@@ -254,6 +255,7 @@ public class DedupeRunService {
|
|||||||
private void cleanExcelByLegacyRules(File inputFile, File outputFile, List<String> selectedColumns,
|
private void cleanExcelByLegacyRules(File inputFile, File outputFile, List<String> selectedColumns,
|
||||||
boolean keepIntegerIds, boolean keepUnderscoreIds,
|
boolean keepIntegerIds, boolean keepUnderscoreIds,
|
||||||
boolean keepIntegerMainIdsWhenNoSubIds) throws Exception {
|
boolean keepIntegerMainIdsWhenNoSubIds) throws Exception {
|
||||||
|
selectedColumns = reorderExportColumns(selectedColumns);
|
||||||
long readStartNs = System.nanoTime();
|
long readStartNs = System.nanoTime();
|
||||||
DedupeReadResult readResult = readDedupeRows(
|
DedupeReadResult readResult = readDedupeRows(
|
||||||
inputFile,
|
inputFile,
|
||||||
@@ -310,13 +312,14 @@ public class DedupeRunService {
|
|||||||
}
|
}
|
||||||
long writeNs = elapsedNs(writeStartNs);
|
long writeNs = elapsedNs(writeStartNs);
|
||||||
log.info(
|
log.info(
|
||||||
"dedupe clean stages file={} scannedRows={} keptRows={} uniqueAsins={} matchedAsins={} outputRows={} readFilterMs={} dbMs={} writeMs={} totalCleanMs={}",
|
"dedupe clean stages file={} scannedRows={} keptRows={} uniqueAsins={} matchedAsins={} outputRows={} filteredFbaRows={} readFilterMs={} dbMs={} writeMs={} totalCleanMs={}",
|
||||||
inputFile.getName(),
|
inputFile.getName(),
|
||||||
readResult.scannedRows(),
|
readResult.scannedRows(),
|
||||||
readResult.rows().size(),
|
readResult.rows().size(),
|
||||||
candidateAsinValues.size(),
|
candidateAsinValues.size(),
|
||||||
matchedAsinValues.size(),
|
matchedAsinValues.size(),
|
||||||
outputRows,
|
outputRows,
|
||||||
|
readResult.filteredFbaRows(),
|
||||||
toMs(readNs),
|
toMs(readNs),
|
||||||
toMs(dbNs),
|
toMs(dbNs),
|
||||||
toMs(writeNs),
|
toMs(writeNs),
|
||||||
@@ -324,6 +327,24 @@ public class DedupeRunService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> reorderExportColumns(List<String> selectedColumns) {
|
||||||
|
if (selectedColumns == null || selectedColumns.isEmpty()) {
|
||||||
|
return selectedColumns;
|
||||||
|
}
|
||||||
|
List<String> ordered = new ArrayList<>(selectedColumns.size() + EXPORT_COLUMN_PRIORITY.size());
|
||||||
|
for (String priority : EXPORT_COLUMN_PRIORITY) {
|
||||||
|
if (selectedColumns.contains(priority)) {
|
||||||
|
ordered.add(priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String column : selectedColumns) {
|
||||||
|
if (!ordered.contains(column)) {
|
||||||
|
ordered.add(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ordered;
|
||||||
|
}
|
||||||
|
|
||||||
private DedupeReadResult readDedupeRows(File inputFile, List<String> selectedColumns,
|
private DedupeReadResult readDedupeRows(File inputFile, List<String> selectedColumns,
|
||||||
boolean keepIntegerIds, boolean keepUnderscoreIds,
|
boolean keepIntegerIds, boolean keepUnderscoreIds,
|
||||||
boolean keepIntegerMainIdsWhenNoSubIds) throws Exception {
|
boolean keepIntegerMainIdsWhenNoSubIds) throws Exception {
|
||||||
@@ -356,14 +377,23 @@ public class DedupeRunService {
|
|||||||
}
|
}
|
||||||
Integer idColumnIndex = headerMap.get("id");
|
Integer idColumnIndex = headerMap.get("id");
|
||||||
Integer asinColumnIndex = headerMap.get("ASIN");
|
Integer asinColumnIndex = headerMap.get("ASIN");
|
||||||
|
Integer shippingTypeColumnIndex = headerMap.get("发货类型");
|
||||||
|
|
||||||
int scannedRows = 0;
|
int scannedRows = 0;
|
||||||
|
int filteredFbaRows = 0;
|
||||||
for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
|
for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
|
||||||
Row row = sheet.getRow(rowNum);
|
Row row = sheet.getRow(rowNum);
|
||||||
if (row == null) {
|
if (row == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scannedRows++;
|
scannedRows++;
|
||||||
|
if (shippingTypeColumnIndex != null) {
|
||||||
|
String shippingType = normalizeCellText(formatter.formatCellValue(row.getCell(shippingTypeColumnIndex)));
|
||||||
|
if ("FBA".equalsIgnoreCase(shippingType)) {
|
||||||
|
filteredFbaRows++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (idColumnIndex == null) {
|
if (idColumnIndex == null) {
|
||||||
rows.add(buildCandidateRow(row, selectedIndexes, asinColumnIndex, formatter));
|
rows.add(buildCandidateRow(row, selectedIndexes, asinColumnIndex, formatter));
|
||||||
continue;
|
continue;
|
||||||
@@ -383,7 +413,7 @@ public class DedupeRunService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pendingMainIdGroup.flush(rows);
|
pendingMainIdGroup.flush(rows);
|
||||||
return new DedupeReadResult(sheet.getSheetName(), rows, scannedRows);
|
return new DedupeReadResult(sheet.getSheetName(), rows, scannedRows, filteredFbaRows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,7 +671,7 @@ public class DedupeRunService {
|
|||||||
return nanos / 1_000_000L;
|
return nanos / 1_000_000L;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record DedupeReadResult(String sheetName, List<DedupeCandidateRow> rows, int scannedRows) {
|
private record DedupeReadResult(String sheetName, List<DedupeCandidateRow> rows, int scannedRows, int filteredFbaRows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private record DedupeCandidateRow(List<String> selectedValues, String asinValue) {
|
private record DedupeCandidateRow(List<String> selectedValues, String asinValue) {
|
||||||
|
|||||||
+25
-5
@@ -24,6 +24,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -136,16 +137,33 @@ public class QueryAsinResolveService {
|
|||||||
if (ordered.isEmpty()) {
|
if (ordered.isEmpty()) {
|
||||||
throw new BusinessException("shop_names 无有效店铺名");
|
throw new BusinessException("shop_names 无有效店铺名");
|
||||||
}
|
}
|
||||||
List<QueryAsinEntity> allAsins = queryAsinMapper.selectList(
|
Map<String, List<QueryAsinEntity>> rowsByShop = loadAsinsGroupByShop(new ArrayList<>(ordered));
|
||||||
new LambdaQueryWrapper<QueryAsinEntity>().orderByAsc(QueryAsinEntity::getId));
|
|
||||||
List<QueryAsinCountryAsinsDto> preloadedQueryAsins = toCountryAsins(allAsins);
|
|
||||||
ProductRiskMatchShopsVo vo = new ProductRiskMatchShopsVo();
|
ProductRiskMatchShopsVo vo = new ProductRiskMatchShopsVo();
|
||||||
for (String shopName : ordered) {
|
for (String shopName : ordered) {
|
||||||
vo.getItems().add(matchOneShop(shopName, preloadedQueryAsins));
|
vo.getItems().add(matchOneShop(shopName,
|
||||||
|
toCountryAsins(rowsByShop.getOrDefault(shopName, List.of()))));
|
||||||
}
|
}
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, List<QueryAsinEntity>> loadAsinsGroupByShop(List<String> shopNames) {
|
||||||
|
LambdaQueryWrapper<QueryAsinEntity> wrapper = shopNames.size() == 1
|
||||||
|
? new LambdaQueryWrapper<QueryAsinEntity>()
|
||||||
|
.eq(QueryAsinEntity::getShopName, shopNames.get(0))
|
||||||
|
.orderByAsc(QueryAsinEntity::getId)
|
||||||
|
: new LambdaQueryWrapper<QueryAsinEntity>()
|
||||||
|
.in(QueryAsinEntity::getShopName, shopNames)
|
||||||
|
.orderByAsc(QueryAsinEntity::getId);
|
||||||
|
Map<String, List<QueryAsinEntity>> rowsByShop = new HashMap<>();
|
||||||
|
for (QueryAsinEntity row : queryAsinMapper.selectList(wrapper)) {
|
||||||
|
if (row.getShopName() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rowsByShop.computeIfAbsent(row.getShopName(), k -> new ArrayList<>()).add(row);
|
||||||
|
}
|
||||||
|
return rowsByShop;
|
||||||
|
}
|
||||||
|
|
||||||
public List<QueryAsinCountryAsinsDto> loadQueryAsinsForShop(Long userId, String shopName) {
|
public List<QueryAsinCountryAsinsDto> loadQueryAsinsForShop(Long userId, String shopName) {
|
||||||
validateUserId(userId);
|
validateUserId(userId);
|
||||||
String normalizedShopName = ziniaoShopSwitchService.normalizeShopName(shopName);
|
String normalizedShopName = ziniaoShopSwitchService.normalizeShopName(shopName);
|
||||||
@@ -153,7 +171,9 @@ public class QueryAsinResolveService {
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
List<QueryAsinEntity> rows = queryAsinMapper.selectList(
|
List<QueryAsinEntity> rows = queryAsinMapper.selectList(
|
||||||
new LambdaQueryWrapper<QueryAsinEntity>().orderByAsc(QueryAsinEntity::getId));
|
new LambdaQueryWrapper<QueryAsinEntity>()
|
||||||
|
.eq(QueryAsinEntity::getShopName, normalizedShopName)
|
||||||
|
.orderByAsc(QueryAsinEntity::getId));
|
||||||
return toCountryAsins(rows);
|
return toCountryAsins(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -548,8 +548,7 @@ function fallbackQueryAsinsForShop(shopName?: string) {
|
|||||||
...matchedItems.value,
|
...matchedItems.value,
|
||||||
];
|
];
|
||||||
const exact = candidates.find((item) => (item?.shopName || "").trim() === normalizedShopName && hasQueryAsins(item));
|
const exact = candidates.find((item) => (item?.shopName || "").trim() === normalizedShopName && hasQueryAsins(item));
|
||||||
const any = candidates.find((item) => hasQueryAsins(item));
|
return readQueryAsins(exact);
|
||||||
return readQueryAsins(exact || any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function withQueryAsinFallback<T extends QueryAsinHistoryItem | QueryAsinShopQueueItem>(
|
function withQueryAsinFallback<T extends QueryAsinHistoryItem | QueryAsinShopQueueItem>(
|
||||||
|
|||||||
Reference in New Issue
Block a user