后台店铺数据重复ASIN:全选移至表头、Tab总数、独立筛选、按ASIN分组表格展示
Build Backend JAR / build (push) Has been cancelled

- 列表全选复选框从工具栏移到表格表头,事件委托处理动态元素
- 重复ASIN Tab 标题加总数(XX 为重复 ASIN 数量)
- 重复ASIN 筛选独立:ASIN/店铺/国家/上架时间(开始+结束),与原店铺数据筛选互不影响
- 后端支持 asin/shop_name/country/date_from/date_to 参数:
  行级筛选命中 ASIN 后展示完整记录(含其他店铺,跨店语义更直观)
- 日期文本归一化(支持 2026年8月19日 上午4:34 中文格式)
- 按 ASIN 分组表格展示:ASIN/店铺数/记录条数/品牌/对应店铺/国家/上架时间/操作,
  详情展开显示每条记录的店铺/分组/国家/日期/价格/品牌
- 修复 _shop_data_crawl_fetch_result_bytes 兼容 result_id 列别名(生产首个真实调用报 KeyError)
- 新增单测:筛选语义、日期归一化、record_count
This commit is contained in:
2026-09-03 09:32:25 +08:00
parent 417a2bf831
commit 672b9f9b46
5 changed files with 263 additions and 115 deletions
+41 -53
View File
@@ -75,16 +75,18 @@
width: 32px;
height: 32px;
border-radius: 9px;
background: linear-gradient(135deg, #6366f1, #7a8bf0);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
font-weight: 700;
overflow: hidden;
background: #fff;
box-shadow: 0 4px 10px rgba(99, 102, 241, 0.35);
}
.admin-brand-logo {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.admin-brand-text {
min-width: 0;
line-height: 1.2;
@@ -302,21 +304,6 @@
flex: 0 0 auto;
}
.admin-user-avatar {
width: 30px;
height: 30px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #7a8bf0);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 600;
flex: 0 0 auto;
box-shadow: 0 2px 6px rgba(99, 102, 241, 0.3);
}
.admin-user-name {
font-size: 13px;
font-weight: 500;
@@ -2532,8 +2519,7 @@
width: 36px;
height: 36px;
border-radius: 11px;
background: linear-gradient(135deg, #818cf8, #4f46e5);
color: #eef2ff;
background: #fff;
box-shadow: 0 8px 22px rgba(79, 70, 229, 0.36);
}
@@ -2680,19 +2666,6 @@
gap: 12px;
}
.admin-user-avatar {
width: 34px;
height: 34px;
background: linear-gradient(135deg, #818cf8, #4f46e5);
color: #eef2ff;
box-shadow: 0 6px 16px rgba(79, 70, 229, 0.28);
}
.admin-user-name {
color: #dbe4f1;
font-weight: 550;
}
.admin-user-role {
color: #c7d2fe;
background: rgba(129, 140, 248, 0.15);
@@ -3484,10 +3457,8 @@
}
.admin-brand { border-bottom-color: #d5ded7; }
.admin-brand-mark,
.admin-user-avatar {
background: linear-gradient(135deg, #7f998a, #607a6d);
color: #ffffff;
.admin-brand-mark {
background: #fff;
box-shadow: 0 8px 20px rgba(96, 122, 109, 0.25);
}
.admin-brand-name { color: var(--c-text); }
@@ -3685,10 +3656,8 @@
box-shadow: 14px 0 34px -28px rgba(39, 67, 94, 0.34);
}
.admin-brand { border-bottom-color: #d4e0eb; }
.admin-brand-mark,
.admin-user-avatar {
background: linear-gradient(135deg, #7094ba, #4f78a5);
color: #ffffff;
.admin-brand-mark {
background: #fff;
box-shadow: 0 8px 20px rgba(79, 120, 165, 0.24);
}
.admin-brand-name { color: var(--c-text); }
@@ -4022,7 +3991,7 @@
<div class="admin-layout">
<aside class="admin-sidebar">
<div class="admin-brand">
<span class="admin-brand-mark" aria-hidden="true"></span>
<span class="admin-brand-mark"><img class="admin-brand-logo" src="/static/logo.jpg" alt="数富AI"></span>
<span class="admin-brand-text">
<span class="admin-brand-name">数富AI</span>
<span class="admin-brand-sub">电商运营管理后台</span>
@@ -4091,7 +4060,6 @@
</div>
</div>
<div class="admin-user-box">
<span class="admin-user-avatar" id="adminUserAvatar" aria-hidden="true"></span>
<span class="admin-user-name" id="adminCurrentUsername">加载中...</span>
<span class="admin-user-role" id="adminCurrentUserRole" style="display:none;"></span>
<button class="admin-user-logout" id="btnAdminLogout" type="button">退出登录</button>
@@ -4716,7 +4684,7 @@
<button class="shop-data-sub-tab active" type="button" id="shopDataSubTabRecords"
role="tab" aria-selected="true">店铺数据</button>
<button class="shop-data-sub-tab" type="button" id="shopDataSubTabDuplicates"
role="tab" aria-selected="false">重复 ASIN</button>
role="tab" aria-selected="false">重复ASIN(<span id="shopDataDuplicateTabCount">0</span>)</button>
</div>
<h4 style="margin-bottom:14px;">筛选条件</h4>
<div class="form-row">
@@ -4755,10 +4723,6 @@
</svg>
批量下载
</button>
<label class="image-video-select-all">
<input type="checkbox" id="shopDataTaskSelectAll">
全选当前页
</label>
<span class="image-video-download-progress" id="shopDataTaskDownloadProgress"
aria-live="polite"></span>
</div>
@@ -4769,6 +4733,30 @@
<div class="pagination" id="shopDataTaskPagination"></div>
</div>
<div id="shopDataDuplicatesView" style="display:none;">
<div class="form-box" style="margin-bottom:14px;">
<h4 style="margin-bottom:12px;">筛选条件</h4>
<div class="form-row">
<div class="form-group" style="min-width:150px;"><label>ASIN</label><input type="text"
id="shopDataDupFilterAsin" placeholder="模糊搜索 ASIN"></div>
<div class="form-group" style="min-width:150px;"><label>店铺</label><input type="text"
id="shopDataDupFilterShop" placeholder="模糊搜索店铺名"></div>
<div class="form-group" style="min-width:120px;"><label>国家</label><select
id="shopDataDupFilterCountry">
<option value="">全部国家</option>
<option value="DE">德国</option>
<option value="UK">英国</option>
<option value="FR">法国</option>
<option value="IT">意大利</option>
<option value="ES">西班牙</option>
</select></div>
<div class="form-group" style="min-width:170px;"><label>上架时间开始</label><input
type="datetime-local" id="shopDataDupFilterDateFrom"></div>
<div class="form-group" style="min-width:170px;"><label>上架时间结束</label><input
type="datetime-local" id="shopDataDupFilterDateTo"></div>
<button class="btn" id="btnFilterShopDataDuplicates" type="button">查询</button>
<button class="btn btn-secondary" id="btnResetShopDataDuplicates" type="button">重置</button>
</div>
</div>
<div class="image-video-results">
<div class="image-video-toolbar">
<div class="image-video-toolbar-main">
@@ -4779,7 +4767,7 @@
</div>
<span class="image-video-summary" id="shopDataDuplicateTotal"></span>
</div>
<div class="duplicate-asin-list" id="shopDataDuplicateList" aria-live="polite"></div>
<div class="table-scroll shop-data-record-table-scroll" id="shopDataDuplicateList" aria-live="polite"></div>
</div>
<div class="pagination" id="shopDataDuplicatePagination"></div>
</div>