Files
crawler-plugin/backend/web_source/admin.html

1853 lines
70 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>管理后台 - 南日AI</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
background: #f5f5f5;
padding: 24px;
}
.page-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 20px;
}
.page-head h1 {
margin-bottom: 0;
}
.admin-user-box {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: #fff;
border: 1px solid #e6eaf2;
border-radius: 999px;
box-shadow: 0 4px 14px rgba(102, 126, 234, 0.08);
}
.admin-user-name {
font-size: 14px;
color: #333;
max-width: 220px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.admin-user-role {
font-size: 12px;
color: #667eea;
background: #eef1ff;
padding: 4px 8px;
border-radius: 999px;
}
.admin-user-logout {
padding: 6px 12px;
font-size: 13px;
}
.nav {
margin-bottom: 24px;
}
.nav a {
color: #667eea;
text-decoration: none;
}
.nav a:hover {
text-decoration: underline;
}
h1 {
font-size: 20px;
margin-bottom: 20px;
}
/* Tabs */
.tabs {
display: flex;
gap: 4px;
margin-bottom: 20px;
border-bottom: 1px solid #e0e0e0;
}
.tab {
padding: 12px 24px;
cursor: pointer;
color: #666;
font-size: 15px;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
}
.tab:hover {
color: #667eea;
}
.tab.active {
color: #667eea;
font-weight: 600;
border-bottom-color: #667eea;
}
.tab-panel {
display: none;
}
.tab-panel.active {
display: block;
}
/* Form & Table */
.form-box,
.panel-box {
background: #fff;
border-radius: 8px;
padding: 24px;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 16px;
}
.form-group label {
display: block;
font-size: 14px;
margin-bottom: 6px;
}
.form-group input,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 6px;
}
.form-group input[type="checkbox"] {
width: auto;
margin-right: 8px;
}
.form-row {
display: flex;
gap: 16px;
flex-wrap: wrap;
align-items: flex-end;
margin-bottom: 16px;
}
.form-row .form-group {
margin-bottom: 0;
flex: 1;
min-width: 120px;
}
.btn {
padding: 10px 20px;
background: #667eea;
color: #fff;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.btn:hover {
opacity: 0.9;
}
.btn-sm {
padding: 6px 12px;
font-size: 13px;
}
.btn-danger {
background: #e74c3c;
}
.btn-secondary {
background: #95a5a6;
}
.msg {
margin-top: 12px;
font-size: 14px;
}
.msg.ok {
color: #27ae60;
}
.msg.err {
color: #e74c3c;
}
.progress-wrap {
margin-top: 12px;
}
.progress-bar {
width: 100%;
height: 10px;
background: #edf0f5;
border-radius: 999px;
overflow: hidden;
}
.progress-fill {
width: 0;
height: 100%;
background: #667eea;
transition: width 0.2s ease;
}
.progress-text {
margin-top: 8px;
font-size: 13px;
color: #666;
}
.request-loading-bar {
position: fixed;
left: 0;
top: 0;
width: 0;
height: 3px;
background: #667eea;
opacity: 0;
z-index: 3000;
transition: width 0.2s ease, opacity 0.2s ease;
}
.request-loading-bar.show {
width: 74%;
opacity: 1;
}
.request-loading-bar.finishing {
width: 100%;
opacity: 0;
}
.request-loading {
position: fixed;
right: 24px;
top: 72px;
display: none;
align-items: center;
gap: 10px;
padding: 10px 14px;
color: #333;
background: rgba(255, 255, 255, 0.96);
border: 1px solid #e6eaf2;
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
font-size: 13px;
z-index: 3000;
pointer-events: none;
}
.request-loading.show {
display: flex;
}
.request-spinner {
width: 16px;
height: 16px;
border: 2px solid #dce2ff;
border-top-color: #667eea;
border-radius: 50%;
animation: request-spin 0.8s linear infinite;
}
@keyframes request-spin {
to {
transform: rotate(360deg);
}
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #eee;
font-size: 14px;
}
th {
background: #f8f9fa;
font-weight: 600;
}
.pagination {
display: flex;
align-items: center;
gap: 8px;
margin-top: 16px;
flex-wrap: wrap;
}
.pagination span {
font-size: 14px;
color: #666;
}
.pagination button {
padding: 6px 12px;
border: 1px solid #ddd;
background: #fff;
cursor: pointer;
border-radius: 4px;
}
.pagination button:hover:not(:disabled) {
background: #f0f0f0;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.thumb {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 4px;
margin-right: 8px;
vertical-align: middle;
}
.thumb-wrap {
display: flex;
flex-wrap: wrap;
gap: 4px;
}
.empty-tip {
color: #999;
font-size: 14px;
padding: 24px;
text-align: center;
}
.tree-name-cell {
display: flex;
align-items: center;
gap: 8px;
min-height: 24px;
}
.tree-indent {
flex: 0 0 auto;
width: var(--indent, 0px);
}
.tree-node-mark {
width: 18px;
height: 18px;
border: 0;
border-radius: 4px;
background: #eef1ff;
color: #667eea;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 700;
cursor: pointer;
padding: 0;
line-height: 1;
}
.tree-node-mark.is-leaf {
background: transparent;
cursor: default;
}
.category-path {
color: #777;
font-size: 12px;
margin-top: 4px;
}
.category-tag {
display: inline-block;
padding: 3px 8px;
border-radius: 999px;
background: #f1f3f5;
color: #666;
font-size: 12px;
}
.modal-mask {
display: none;
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal-mask.show {
display: flex;
}
#shopManageGroupModal {
z-index: 1010;
}
.modal {
background: #fff;
border-radius: 8px;
padding: 24px;
min-width: 320px;
width: min(920px, calc(100vw - 48px));
max-width: 90%;
max-height: calc(100vh - 48px);
overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box;
}
.modal h3 {
margin-bottom: 16px;
font-size: 16px;
}
#shopManageGroupModal .shop-group-modal {
width: min(1180px, calc(100vw - 48px));
max-width: none;
max-height: calc(100vh - 48px);
padding: 0;
overflow: hidden;
display: flex;
flex-direction: column;
}
.shop-group-modal-header {
padding: 20px 24px 14px;
border-bottom: 1px solid #edf0f5;
flex: 0 0 auto;
}
.shop-group-modal-header h3 {
margin: 0;
}
.shop-group-editor {
padding: 18px 24px 14px;
display: grid;
grid-template-columns: minmax(180px, 240px) minmax(240px, 320px) minmax(360px, 1fr);
gap: 16px;
align-items: start;
flex: 0 0 auto;
}
.shop-group-editor .form-group {
margin-bottom: 0;
}
.shop-group-member-select {
min-height: 128px;
max-height: 180px;
}
.shop-group-help {
color: #777;
font-size: 12px;
line-height: 1.5;
margin-top: 6px;
}
.shop-group-action-bar {
padding: 0 24px 12px;
display: flex;
gap: 8px;
justify-content: flex-end;
align-items: center;
flex: 0 0 auto;
}
#msgShopManageGroup {
margin: 0;
padding: 0 24px 10px;
min-height: 18px;
flex: 0 0 auto;
}
.shop-group-table-wrap {
margin: 0 24px;
border: 1px solid #edf0f5;
border-radius: 8px;
overflow: auto;
min-height: 220px;
flex: 1 1 auto;
}
.shop-group-table {
min-width: 1040px;
table-layout: fixed;
}
.shop-group-table th {
position: sticky;
top: 0;
z-index: 1;
}
.shop-group-table th,
.shop-group-table td {
vertical-align: top;
}
.shop-group-table .col-index {
width: 58px;
}
.shop-group-table .col-name {
width: 130px;
}
.shop-group-table .col-leader {
width: 110px;
}
.shop-group-table .col-count {
width: 86px;
}
.shop-group-table .col-members {
width: auto;
}
.shop-group-table .col-time {
width: 120px;
}
.shop-group-table .col-action {
width: 128px;
}
.shop-group-time-cell,
.shop-group-action-cell {
white-space: nowrap;
}
.shop-group-name-cell,
.shop-group-leader-cell {
word-break: break-word;
}
.shop-group-members {
display: flex;
flex-wrap: wrap;
gap: 6px;
max-height: 96px;
overflow-y: auto;
padding-right: 4px;
}
.shop-group-member-chip {
display: inline-flex;
align-items: center;
max-width: 150px;
padding: 3px 8px;
border-radius: 999px;
background: #eef1ff;
color: #4f63d8;
font-size: 12px;
line-height: 1.4;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.shop-group-modal-footer {
padding: 14px 24px 18px;
display: flex;
gap: 8px;
justify-content: flex-end;
border-top: 1px solid #edf0f5;
flex: 0 0 auto;
}
@media (max-width: 900px) {
#shopManageGroupModal .shop-group-modal {
width: calc(100vw - 24px);
max-height: calc(100vh - 24px);
}
.shop-group-editor {
grid-template-columns: 1fr;
}
.shop-group-table-wrap {
margin: 0 16px;
}
}
.column-permission-cards {
display: flex;
flex-wrap: wrap;
gap: 8px;
min-height: 32px;
margin-bottom: 8px;
width: 100%;
max-width: 100%;
overflow: hidden;
}
.multi-select-native {
position: absolute;
opacity: 0;
pointer-events: none;
width: 1px !important;
height: 1px !important;
min-height: 0 !important;
padding: 0 !important;
border: 0 !important;
}
.multi-select-dropdown {
position: relative;
width: 100%;
}
.multi-select-trigger {
width: 100%;
min-height: 42px;
padding: 10px 34px 10px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
color: #333;
font-size: 14px;
text-align: left;
cursor: pointer;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.multi-select-trigger::after {
content: "";
position: absolute;
right: 12px;
top: 50%;
width: 7px;
height: 7px;
border-right: 1.5px solid #666;
border-bottom: 1.5px solid #666;
transform: translateY(-65%) rotate(45deg);
}
.multi-select-dropdown.open .multi-select-trigger {
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.12);
}
.multi-select-panel {
display: none;
position: absolute;
left: 0;
right: 0;
top: calc(100% + 6px);
z-index: 30;
background: #fff;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.14);
padding: 6px;
max-height: 220px;
overflow-y: auto;
}
.multi-select-dropdown.open .multi-select-panel {
display: block;
}
.multi-select-option {
display: flex;
align-items: center;
gap: 8px;
min-height: 34px;
padding: 7px 8px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
color: #333;
}
.multi-select-option:hover {
background: #f4f6ff;
}
.multi-select-option input {
width: auto;
margin: 0;
}
.column-permission-card {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
background: #e8ebf7;
color: #667eea;
border-radius: 6px;
font-size: 13px;
max-width: 100%;
min-width: 0;
flex: 0 1 auto;
white-space: normal;
overflow-wrap: anywhere;
word-break: break-word;
}
.column-permission-card .col-card-remove {
flex: 0 0 auto;
margin-left: 2px;
padding: 0 4px;
line-height: 1;
cursor: pointer;
color: #999;
border: none;
background: none;
font-size: 16px;
}
.column-permission-card .col-card-remove:hover {
color: #e74c3c;
}
.column-permission-select {
width: 100%;
max-width: 100%;
min-height: 80px;
max-height: 140px;
overflow-y: auto;
padding: 8px;
box-sizing: border-box;
}
.column-permission-select option {
padding: 4px 0;
}
</style>
</head>
<body>
<!-- <div class="nav"><a href="/home">返回首页</a></div> -->
<div class="request-loading-bar" id="requestLoadingBar"></div>
<div class="request-loading" id="requestLoading">
<span class="request-spinner"></span>
<span>请求处理中...</span>
</div>
<h1>管理后台</h1>
<div class="admin-user-box" style="position:absolute;top:24px;right:24px;z-index:10;">
<span class="admin-user-name" id="adminCurrentUsername">加载中...</span>
<span class="admin-user-role" id="adminCurrentUserRole" style="display:none;"></span>
<button class="btn btn-secondary admin-user-logout" id="btnAdminLogout" type="button">退出登录</button>
</div>
<div class="tabs" id="adminTabs">
<div class="tab active" data-tab="users">用户管理</div>
<div class="tab" data-tab="columns">栏目权限配置</div>
<div class="tab" data-tab="dedupe-total-data">数据去重总数据</div>
<div class="tab" data-tab="invalid-asin-data">不符合ASIN数据</div>
<div class="tab" data-tab="shop-keys">店铺密钥管理</div>
<div class="tab" data-tab="shop-manage">店铺管理</div>
<div class="tab" data-tab="skip-price-asin">跳过跟价 ASIN</div>
<div class="tab" data-tab="query-asin">查询 ASIN</div>
<div class="tab" data-tab="product-categories">商品类目</div>
<div class="tab" data-tab="history">查看生成记录</div>
<div class="tab" data-tab="version">版本管理</div>
</div>
<!-- 用户管理 -->
<div id="panel-users" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">创建用户</h3>
<p style="margin-bottom:16px;font-size:13px;color:#666;">
当前没有开放注册入口,仅管理员可在此创建用户。层级关系:超级管理员 -&gt; 管理员 -&gt; 普通账号。</p>
<div class="form-group">
<label>用户名</label>
<input type="text" id="username" placeholder="用户名(至少 2 个字符)">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" id="password" placeholder="密码(至少 6 个字符)">
</div>
<div class="form-group" id="formGroupRole">
<label>角色</label>
<select id="createRole">
<option value="normal">普通账号</option>
<option value="admin" id="optAdmin">管理员</option>
</select>
</div>
<div class="form-group" id="formGroupCreatedBy" style="display:none;">
<label>所属管理员</label>
<select id="createCreatedBy">
<option value="">请选择管理员</option>
</select>
</div>
<div class="form-group" id="formGroupCreateColumns">
<label>菜单权限可多选Ctrl/Shift 点选)</label>
<div id="createColumnCards" class="column-permission-cards"></div>
<select id="createColumnPermissionWrap" class="column-permission-select" multiple></select>
</div>
<button class="btn" id="btnCreate">创建用户</button>
<p class="msg" id="msgCreate"></p>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">用户列表</h3>
<div class="form-row" style="margin-bottom:16px;">
<div class="form-group" style="min-width:180px;">
<label>用户名(模糊搜索)</label>
<input type="text" id="searchUsername" placeholder="输入用户名关键字">
</div>
<div class="form-group" id="filterCreatedByGroup" style="min-width:160px;display:none;">
<label>所属管理员</label>
<select id="filterCreatedBy">
<option value="">全部</option>
</select>
</div>
<button class="btn" id="btnSearchUsers">查询</button>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>角色</th>
<th>所属管理员</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="userListBody"></tbody>
</table>
<div class="pagination" id="userPagination"></div>
</div>
</div>
<!-- 栏目权限配置 -->
<div id="panel-columns" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增菜单</h3>
<div class="form-row">
<div class="form-group" style="min-width:200px;">
<label>菜单名称</label>
<input type="text" id="columnName" placeholder="例如:店铺管理">
</div>
<div class=" form-group" style="min-width:200px;">
<label>栏目标识</label>
<input type="text" id="columnKey" placeholder="例如shop_manage">
</div>
<div class="form-group" style="min-width:220px;">
<label>菜单路由</label>
<input type="text" id="columnRoutePath" placeholder="例如dedupe-total-data">
</div>
<div class="form-group" style="min-width:140px;">
<label>排序</label>
<input type="number" id="columnSortOrder" placeholder="例如10">
</div>
<div class="form-group" style="min-width:160px;">
<label>菜单类型</label>
<select id="columnMenuType">
<option value="admin">后台(admin)</option>
<option value="app">软件(app)</option>
</select>
</div>
<button class="btn" id="btnAddColumn">新增菜单</button>
</div>
<p class="msg" id="msgColumn"></p>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">栏目列表</h3>
<table>
<thead>
<tr>
<th>ID</th>
<th>菜单名称</th>
<th>栏目标识</th>
<th>菜单类型</th>
<th>排序</th>
<th>菜单路由</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="columnListBody"></tbody>
</table>
</div>
</div>
<!-- 版本管理 -->
<div id="panel-version" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">发布新版本</h3>
<div class="form-group">
<label>版本号</label>
<input type="text" id="versionNumber" placeholder="例如1.0.0">
</div>
<div class="form-group">
<label>ZIP 压缩包</label>
<input type="file" id="versionZip" accept=".zip">
</div>
<button class="btn" id="btnUploadVersion">上传并发布</button>
<p class="msg" id="msgVersion"></p>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">版本列表</h3>
<table>
<thead>
<tr>
<th>版本号</th>
<th>下载链接</th>
<th>发布时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="versionListBody"></tbody>
</table>
</div>
</div>
<!-- 数据去重总数据 -->
<div id="panel-dedupe-total-data" class="tab-panel">
<div class="form-box">
<div class="form-row" style="align-items:flex-start;gap:16px;">
<div style="flex:1;min-width:320px;">
<h3 style="margin-bottom:16px;font-size:15px;">新增总数据</h3>
<div class="form-row">
<div class="form-group" style="min-width:320px;">
<label>上传 Excel 文件(读取 ASIN 列)</label>
<input type="file" id="dedupeTotalDataFile" accept=".xlsx,.xls">
</div>
<button class="btn" id="btnAddDedupeTotalData">上传并导入</button>
</div>
<p class="msg" id="msgDedupeTotalData"></p>
<div class="progress-wrap" id="dedupeTotalDataProgressWrap" style="display:none;">
<div class="progress-bar">
<div class="progress-fill" id="dedupeTotalDataProgressFill"></div>
</div>
<div class="progress-text" id="dedupeTotalDataProgressText"></div>
</div>
</div>
<div style="flex:1;min-width:320px;">
<h3 style="margin-bottom:16px;font-size:15px;">删除匹配总数据</h3>
<div class="form-row">
<div class="form-group" style="min-width:320px;">
<label>上传 Excel 文件(读取 ASIN 列)</label>
<input type="file" id="dedupeTotalDataDeleteFile" accept=".xlsx,.xls">
</div>
<button class="btn btn-danger" id="btnDeleteImportDedupeTotalData">上传并删除</button>
</div>
<p class="msg" id="msgDeleteDedupeTotalData"></p>
<div class="progress-wrap" id="dedupeTotalDataDeleteProgressWrap" style="display:none;">
<div class="progress-bar">
<div class="progress-fill" id="dedupeTotalDataDeleteProgressFill"></div>
</div>
<div class="progress-text" id="dedupeTotalDataDeleteProgressText"></div>
</div>
</div>
</div>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">总数据列表</h3>
<div class="form-row" style="margin-bottom:16px;">
<div class="form-group" style="min-width:220px;">
<label>数据值(模糊搜索)</label>
<input type="text" id="searchDedupeTotalData" placeholder="输入关键字">
</div>
<button class=" btn" id="btnSearchDedupeTotalData">查询</button>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>总数据值</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="dedupeTotalDataListBody"></tbody>
</table>
<div class="pagination" id="dedupeTotalDataPagination"></div>
</div>
</div>
<!-- 不符合ASIN数据 -->
<div id="panel-invalid-asin-data" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增不符合ASIN数据</h3>
<div class="form-row">
<div class="form-group" style="min-width:220px;">
<label>ASIN</label>
<input type="text" id="invalidAsinDataValue" placeholder="请输入 ASIN">
</div>
<div class="form-group" style="min-width:220px;">
<label>品牌</label>
<input type="text" id="invalidAsinDataBrand" placeholder="请输入品牌(可选)">
</div>
<button class="btn" id="btnAddInvalidAsinData">新增</button>
</div>
<p class="msg" id="msgInvalidAsinData"></p>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">不符合ASIN数据列表</h3>
<div class="form-row" style="margin-bottom:16px;">
<div class="form-group" style="min-width:220px;">
<label>ASIN / 品牌(模糊搜索)</label>
<input type="text" id="searchInvalidAsinData" placeholder="输入关键字">
</div>
<button class=" btn" id="btnSearchInvalidAsinData">查询</button>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>ASIN</th>
<th>品牌</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="invalidAsinDataListBody"></tbody>
</table>
<div class="pagination" id="invalidAsinDataPagination"></div>
</div>
</div>
<!-- 店铺密钥管理 -->
<div id="panel-shop-keys" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增店铺密钥</h3>
<div class="form-row">
<div class="form-group" style="min-width:220px;">
<label>紫鸟账号名称</label>
<input type="text" id="shopKeyZiniaoAccountName" placeholder="请输入紫鸟账号名称">
</div>
<div class=" form-group" style="min-width:260px;">
<label>紫鸟令牌</label>
<input type="text" id="shopKeyZiniaoToken" placeholder="请输入紫鸟令牌">
</div>
<button class=" btn" id="btnCreateShopKey">新增店铺密钥</button>
</div>
<p class="msg" id="msgShopKey"></p>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">店铺密钥列表</h3>
<table>
<thead>
<tr>
<th>序号</th>
<th>紫鸟账号名称</th>
<th>紫鸟令牌</th>
<th>创建时间</th>
<th>修改时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="shopKeyListBody"></tbody>
</table>
<div class="pagination" id="shopKeyPagination"></div>
</div>
</div>
<!-- 店铺管理 -->
<div id="panel-shop-manage" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增店铺</h3>
<div class="form-row">
<div class="form-group" style="min-width:220px;">
<label>分组</label>
<div style="display:flex;gap:8px;align-items:center;">
<select id="shopManageGroupSelect" style="min-width:150px;">
<option value="">请选择分组</option>
</select>
<button class="btn btn-secondary" id="btnManageShopGroups" type="button">管理分组</button>
</div>
</div>
<div class="form-group" style="min-width:160px;">
<label>店铺名</label>
<input type="text" id="shopManageShopName" placeholder="请输入店铺名称">
</div>
<div class=" form-group" style="min-width:180px;">
<label>店铺商城名</label>
<input type="text" id="shopManageMallName" placeholder="请输入店铺商城名">
</div>
<div class="form-group" style="min-width:180px;">
<label>账号</label>
<input type="text" id="shopManageAccount" placeholder="请输入账号">
</div>
<div class=" form-group" style="min-width:180px;">
<label>密码</label>
<input type="text" id="shopManagePassword" placeholder="请输入密码">
</div>
<button class=" btn" id="btnCreateShopManage">新增店铺</button>
</div>
<p class="msg" id="msgShopManage"></p>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">店铺列表</h3>
<div class="form-row" style="margin-bottom:12px;">
<div class="form-group" style="min-width:180px;">
<label>分组</label>
<select id="shopManageFilterGroupId">
<option value="">全部分组</option>
</select>
</div>
<div class="form-group" style="min-width:220px;">
<label>店铺名</label>
<input type="text" id="shopManageFilterShopName" placeholder="请输入店铺名">
</div>
<button class="btn" id="btnSearchShopManage">查询</button>
</div>
<table>
<thead>
<tr>
<th>序号</th>
<th>分组</th>
<th>店铺名</th>
<th>店铺商城名</th>
<th>账号</th>
<th>密码</th>
<th>创建时间</th>
<th>修改时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="shopManageListBody"></tbody>
</table>
<div class="pagination" id="shopManagePagination"></div>
</div>
</div>
<!-- 查看生成记录 -->
<div id="panel-skip-price-asin" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增 ASIN</h3>
<div class="form-row">
<div class="form-group" style="min-width:220px;">
<label>分组</label>
<div style="display:flex;gap:8px;align-items:center;">
<select id="skipPriceAsinGroupSelect" style="min-width:150px;">
<option value="">请选择分组</option>
</select>
<button class="btn btn-secondary" id="btnManageSkipPriceAsinGroups" type="button">管理分组</button>
</div>
</div>
<div class="form-group" style="min-width:180px;">
<label>店铺名</label>
<input type="text" id="skipPriceAsinShopName" placeholder="请输入店铺名称">
</div>
<div class=" form-group" style="min-width:220px;">
<label>国家</label>
<div style="margin-bottom:8px;">
<label>&nbsp;</label>
<button class="btn btn-secondary" id="btnChooseSkipPriceAsinShop" type="button">选择店铺</button>
</div>
<select id="skipPriceAsinCountries" class="js-dropdown-multi" multiple>
<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:320px;flex:1;">
<label>ASIN / 最低价</label>
<div id="skipPriceAsinInputs" style="display:flex;flex-direction:column;gap:8px;">
<div style="color:#999;font-size:13px;">请选择国家后输入对应 ASIN 和最低价</div>
</div>
</div>
<button class="btn" id="btnCreateSkipPriceAsin">新增 ASIN</button>
</div>
<p class="msg" id="msgSkipPriceAsin"></p>
<div class="form-row" style="align-items:flex-start;gap:16px;margin-top:18px;border-top:1px solid #f0f0f0;padding-top:16px;">
<div style="flex:1;min-width:320px;">
<h3 style="margin-bottom:12px;font-size:14px;">导入文件新增</h3>
<div class="form-row">
<div class="form-group" style="min-width:320px;">
<label>上传 Excel先选择分组文件名必须是该分组下的店铺名表头为 国家 / 删除ASIN / 最低价)</label>
<input type="file" id="skipPriceAsinImportFile" accept=".xlsx,.xls">
</div>
<button class="btn" id="btnImportSkipPriceAsin" type="button">上传并新增</button>
</div>
<p class="msg" id="msgSkipPriceAsinImport"></p>
<div class="progress-wrap" id="skipPriceAsinImportProgressWrap" style="display:none;">
<div class="progress-bar">
<div class="progress-fill" id="skipPriceAsinImportProgressFill"></div>
</div>
<div class="progress-text" id="skipPriceAsinImportProgressText"></div>
</div>
</div>
<div style="flex:1;min-width:320px;">
<h3 style="margin-bottom:12px;font-size:14px;">导入文件删除</h3>
<div class="form-row">
<div class="form-group" style="min-width:320px;">
<label>上传 Excel先选择分组文件名必须是该分组下的店铺名按各国家删除ASIN列匹配删除</label>
<input type="file" id="skipPriceAsinDeleteImportFile" accept=".xlsx,.xls">
</div>
<button class="btn btn-danger" id="btnDeleteImportSkipPriceAsin" type="button">上传并删除</button>
</div>
<p class="msg" id="msgSkipPriceAsinDeleteImport"></p>
<div class="progress-wrap" id="skipPriceAsinDeleteImportProgressWrap" style="display:none;">
<div class="progress-bar">
<div class="progress-fill" id="skipPriceAsinDeleteImportProgressFill"></div>
</div>
<div class="progress-text" id="skipPriceAsinDeleteImportProgressText"></div>
</div>
</div>
</div>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">店铺列表</h3>
<div class="form-row" style="margin-bottom:12px;">
<div class="form-group" style="min-width:180px;">
<label>分组</label>
<select id="skipPriceAsinFilterGroupId">
<option value="">全部分组</option>
</select>
</div>
<div class="form-group" style="min-width:220px;">
<label>店铺名</label>
<input type="text" id="skipPriceAsinFilterShopName" placeholder="请输入店铺名">
</div>
<div class="form-group" style="min-width:220px;">
<label>ASIN</label>
<input type="text" id="skipPriceAsinFilterAsin" placeholder="请输入 ASIN">
</div>
<button class="btn" id="btnSearchSkipPriceAsin">查询</button>
<button class="btn btn-secondary" id="btnExportSkipPriceAsin" type="button">导出 XLSX</button>
</div>
<table>
<thead>
<tr>
<th>序号</th>
<th>分组</th>
<th>店铺名</th>
<th>德国</th>
<th>英国</th>
<th>法国</th>
<th>意大利</th>
<th>西班牙</th>
</tr>
</thead>
<tbody id="skipPriceAsinListBody"></tbody>
</table>
<div class="pagination" id="skipPriceAsinPagination"></div>
</div>
</div>
<div id="panel-query-asin" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增查询 ASIN</h3>
<div class="form-row">
<div class="form-group" style="min-width:220px;">
<label>分组</label>
<div style="display:flex;gap:8px;align-items:center;">
<select id="queryAsinGroupSelect" style="min-width:150px;">
<option value="">请选择分组</option>
</select>
<button class="btn btn-secondary" id="btnManageQueryAsinGroups" type="button">管理分组</button>
</div>
</div>
<div class="form-group" style="min-width:340px;">
<label>店铺名</label>
<div style="display:flex;gap:8px;align-items:center;">
<input type="text" id="queryAsinShopName" placeholder="请输入店铺名称" style="flex:1;min-width:180px;">
<button class="btn btn-secondary" id="btnChooseQueryAsinShop" type="button">选择店铺</button>
</div>
</div>
<div class="form-group" style="min-width:220px;">
<label>国家</label>
<select id="queryAsinCountries" class="js-dropdown-multi" multiple>
<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:320px;flex:1;">
<label>ASIN</label>
<div id="queryAsinInputs" style="display:flex;flex-direction:column;gap:8px;">
<div style="color:#999;font-size:13px;">请选择国家后输入对应 ASIN</div>
</div>
</div>
<button class="btn" id="btnCreateQueryAsin" style="align-self:flex-end;margin-bottom:40px;">新增 ASIN</button>
</div>
<p class="msg" id="msgQueryAsin"></p>
<div class="form-row" style="align-items:flex-start;gap:16px;margin-top:18px;border-top:1px solid #f0f0f0;padding-top:16px;">
<div style="flex:1;min-width:320px;">
<h3 style="margin-bottom:12px;font-size:14px;">导入添加</h3>
<div class="form-row">
<div class="form-group" style="min-width:320px;">
<label>上传 Excel支持两种格式1. 分组/店铺名/德国-西班牙2. 店铺账号/ASIN/中文国家名。文件无分组列时取页面当前分组)</label>
<input type="file" id="queryAsinImportFile" accept=".xlsx,.xls">
</div>
<button class="btn" id="btnImportQueryAsin" type="button">上传并添加</button>
</div>
<p class="msg" id="msgQueryAsinImport"></p>
<div class="progress-wrap" id="queryAsinImportProgressWrap" style="display:none;">
<div class="progress-bar">
<div class="progress-fill" id="queryAsinImportProgressFill"></div>
</div>
<div class="progress-text" id="queryAsinImportProgressText"></div>
</div>
</div>
<div style="flex:1;min-width:320px;">
<h3 style="margin-bottom:12px;font-size:14px;">导入删除</h3>
<div class="form-row">
<div class="form-group" style="min-width:320px;">
<label>上传 Excel支持按 分组/店铺名/国家列 或 店铺账号/ASIN/中文国家名 删除;文件无分组列时取页面当前分组)</label>
<input type="file" id="queryAsinDeleteImportFile" accept=".xlsx,.xls">
</div>
<button class="btn btn-danger" id="btnDeleteImportQueryAsin" type="button">上传并删除</button>
</div>
<p class="msg" id="msgQueryAsinDeleteImport"></p>
<div class="progress-wrap" id="queryAsinDeleteImportProgressWrap" style="display:none;">
<div class="progress-bar">
<div class="progress-fill" id="queryAsinDeleteImportProgressFill"></div>
</div>
<div class="progress-text" id="queryAsinDeleteImportProgressText"></div>
</div>
</div>
</div>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">店铺列表</h3>
<div class="form-row" style="margin-bottom:12px;">
<div class="form-group" style="min-width:180px;">
<label>分组</label>
<select id="queryAsinFilterGroupId">
<option value="">全部分组</option>
</select>
</div>
<div class="form-group" style="min-width:220px;">
<label>店铺名</label>
<input type="text" id="queryAsinFilterShopName" placeholder="请输入店铺名">
</div>
<div class="form-group" style="min-width:220px;">
<label>ASIN</label>
<input type="text" id="queryAsinFilterAsin" placeholder="请输入 ASIN">
</div>
<button class="btn" id="btnSearchQueryAsin">查询</button>
<button class="btn btn-secondary" id="btnExportQueryAsin" type="button">导出 XLSX</button>
</div>
<table>
<thead>
<tr>
<th>序号</th>
<th>分组</th>
<th>店铺名</th>
<th>德国</th>
<th>英国</th>
<th>法国</th>
<th>意大利</th>
<th>西班牙</th>
</tr>
</thead>
<tbody id="queryAsinListBody"></tbody>
</table>
<div class="pagination" id="queryAsinPagination"></div>
</div>
</div>
<div id="panel-product-categories" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">新增商品类目</h3>
<div class="form-row">
<div class="form-group" style="min-width:220px;">
<label>上级类目</label>
<select id="productCategoryParentId">
<option value="">顶级类目</option>
</select>
</div>
<div class="form-group" style="min-width:220px;">
<label>类目名称</label>
<input type="text" id="productCategoryName" placeholder="例如:洁面">
</div>
<div class="form-group" style="min-width:120px;">
<label>排序</label>
<input type="number" id="productCategorySortOrder" placeholder="例如10">
</div>
<div class="form-group" style="min-width:280px;flex:1;">
<label>备注</label>
<input type="text" id="productCategoryDescription" placeholder="可填写风险说明或使用场景">
</div>
<button class="btn" id="btnCreateProductCategory">新增类目</button>
<button class="btn btn-secondary" id="btnCancelProductCategoryEdit" type="button" style="display:none;">取消编辑</button>
</div>
<p class="msg" id="msgProductCategory"></p>
</div>
<div class="panel-box">
<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;">
<h3 style="font-size:15px;">类目树</h3>
<div class="form-row" style="gap:8px;margin:0;flex:0 1 420px;">
<div class="form-group" style="min-width:220px;flex:1;margin:0;">
<input type="text" id="productCategoryKeyword" placeholder="搜索类目名称、编码或备注">
</div>
<button class="btn btn-sm" id="btnSearchProductCategory" type="button">搜索</button>
<button class="btn btn-sm btn-secondary" id="btnClearProductCategorySearch" type="button">清空</button>
</div>
</div>
<table>
<thead>
<tr>
<th style="width:34%;">类目</th>
<th>层级路径</th>
<th style="width:90px;">排序</th>
<th style="width:120px;">来源</th>
<th>备注</th>
<th style="width:150px;">操作</th>
</tr>
</thead>
<tbody id="productCategoryListBody"></tbody>
</table>
</div>
</div>
<div id="panel-history" class="tab-panel">
<div class="form-box">
<h3 style="margin-bottom:16px;font-size:15px;">筛选条件</h3>
<div class="form-row">
<div class="form-group" style="min-width:140px;">
<label>指定用户</label>
<select id="filterUser">
<option value="">全部用户</option>
</select>
</div>
<div class="form-group" style="min-width:140px;">
<label>开始时间</label>
<input type="datetime-local" id="filterTimeStart">
</div>
<div class="form-group" style="min-width:140px;">
<label>结束时间</label>
<input type="datetime-local" id="filterTimeEnd">
</div>
<button class="btn" id="btnFilterHistory">查询</button>
</div>
</div>
<div class="panel-box">
<h3 style="margin-bottom:16px;font-size:15px;">生成记录</h3>
<table>
<thead>
<tr>
<th>ID</th>
<th>用户</th>
<th>类型</th>
<th>创建时间</th>
<th>结果预览</th>
</tr>
</thead>
<tbody id="historyListBody"></tbody>
</table>
<div class="pagination" id="historyPagination"></div>
</div>
</div>
<!-- 编辑用户弹窗 -->
<div class="modal-mask" id="editUserModal">
<div class="modal">
<h3>编辑用户</h3>
<input type="hidden" id="editUserId">
<div class="form-group">
<label>用户名</label>
<input type="text" id="editUsername" readonly style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>新密码(不修改可留空)</label>
<input type="password" id="editPassword" placeholder="留空则不修改密码">
</div>
<div class="form-group" id="editFormGroupRole" style="display:none;">
<label>角色</label>
<select id="editRole">
<option value="normal">普通账号</option>
<option value="admin">管理员</option>
</select>
</div>
<div class="form-group" id="editFormGroupCreator" style="display:none;">
<label>所属管理员</label>
<input type="text" id="editCreatorName" readonly style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>菜单权限可多选Ctrl/Shift 点选)</label>
<div id="editColumnCards" class="column-permission-cards"></div>
<select id="editColumnPermissionWrap" class="column-permission-select" multiple></select>
</div>
<p class="msg" id="msgEdit"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveUser">保存</button>
<button class="btn btn-secondary" id="btnCloseEdit">取消</button>
</div>
</div>
</div>
<!-- 编辑总数据弹窗 -->
<div class="modal-mask" id="editDedupeTotalDataModal">
<div class="modal">
<h3>编辑总数据</h3>
<input type="hidden" id="editDedupeTotalDataId">
<div class="form-group">
<label>总数据值</label>
<input type="text" id="editDedupeTotalDataValue" placeholder="请输入总数据值">
</div>
<p class=" msg" id="msgEditDedupeTotalData"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveDedupeTotalData">保存</button>
<button class="btn btn-secondary" id="btnCloseEditDedupeTotalData">取消</button>
</div>
</div>
</div>
<!-- 编辑不符合ASIN数据弹窗 -->
<div class="modal-mask" id="editInvalidAsinDataModal">
<div class="modal">
<h3>编辑不符合ASIN数据</h3>
<input type="hidden" id="editInvalidAsinDataId">
<div class="form-group">
<label>ASIN</label>
<input type="text" id="editInvalidAsinDataValue" placeholder="请输入 ASIN">
</div>
<div class="form-group">
<label>品牌</label>
<input type="text" id="editInvalidAsinDataBrand" placeholder="请输入品牌(可选)">
</div>
<p class=" msg" id="msgEditInvalidAsinData"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveInvalidAsinData">保存</button>
<button class="btn btn-secondary" id="btnCloseEditInvalidAsinData">取消</button>
</div>
</div>
</div>
<!-- 编辑栏目弹窗 -->
<div class="modal-mask" id="editColumnModal">
<div class="modal">
<h3>编辑栏目</h3>
<input type="hidden" id="editColumnId">
<div class="form-group">
<label>菜单名称</label>
<input type="text" id="editColumnName" placeholder="菜单名称">
</div>
<div class=" form-group">
<label>栏目标识</label>
<input type="text" id="editColumnKey" placeholder="栏目标识">
</div>
<div class="form-group">
<label>菜单路由</label>
<input type="text" id="editColumnRoutePath" placeholder="菜单路由">
</div>
<div class="form-group">
<label>排序</label>
<input type="number" id="editColumnSortOrder" placeholder="排序">
</div>
<div class="form-group">
<label>菜单类型</label>
<select id="editColumnMenuType">
<option value="admin">后台(admin)</option>
<option value="app">软件(app)</option>
</select>
</div>
<p class="msg" id="msgEditColumn"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveColumn">保存</button>
<button class="btn btn-secondary" id="btnCloseEditColumn">取消</button>
</div>
</div>
</div>
<!-- 分组管理弹窗 -->
<div class="modal-mask" id="shopManageGroupModal">
<div class="modal shop-group-modal">
<div class="shop-group-modal-header">
<h3>分组管理</h3>
</div>
<div class="shop-group-editor">
<input type="hidden" id="shopManageGroupEditId">
<input type="hidden" id="shopManageGroupLeaderUserId">
<div class="form-group">
<label>组长</label>
<input type="text" id="shopManageGroupLeaderName" placeholder="当前登录用户" readonly
style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>分组名称</label>
<input type="text" id="shopManageGroupInput" placeholder="请输入分组名称">
</div>
<div class="form-group">
<label>组员</label>
<select id="shopManageGroupMemberSelect" class="shop-group-member-select" multiple size="6">
</select>
<div id="shopManageGroupMemberHelp" class="shop-group-help">可添加当前组长创建的普通员工账号,按住 Ctrl 或 Command 可多选。</div>
</div>
</div>
<div class="shop-group-action-bar">
<button class="btn" id="btnSaveShopManageGroup" type="button">保存分组</button>
<button class="btn btn-secondary" id="btnCancelShopManageGroupEdit" type="button">取消编辑</button>
</div>
<p class="msg" id="msgShopManageGroup"></p>
<div class="shop-group-table-wrap">
<table class="shop-group-table">
<colgroup>
<col class="col-index">
<col class="col-name">
<col class="col-leader">
<col class="col-count">
<col class="col-members">
<col class="col-time">
<col class="col-time">
<col class="col-action">
</colgroup>
<thead>
<tr>
<th>序号</th>
<th>分组名称</th>
<th>组长</th>
<th>组员数量</th>
<th>组员</th>
<th>创建时间</th>
<th>修改时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="shopManageGroupListBody"></tbody>
</table>
</div>
<div class="shop-group-modal-footer">
<button class="btn btn-secondary" id="btnCloseShopManageGroupModal" type="button">关闭</button>
</div>
</div>
</div>
<!-- 编辑店铺管理弹窗 -->
<div class="modal-mask" id="chooseSkipPriceAsinShopModal">
<div class="modal" style="max-width:900px;width:90%;max-height:80vh;display:flex;flex-direction:column;">
<h3>选择店铺</h3>
<div class="form-row">
<div class="form-group" style="min-width:180px;">
<label>分组</label>
<select id="chooseSkipPriceAsinShopGroupId">
<option value="">全部分组</option>
</select>
</div>
<div class="form-group" style="min-width:220px;">
<label>店铺名</label>
<input type="text" id="chooseSkipPriceAsinShopKeyword" placeholder="请输入店铺名">
</div>
<button class="btn" id="btnSearchChooseSkipPriceAsinShop" type="button">查询</button>
</div>
<div style="flex:1;min-height:0;overflow:auto;">
<table>
<thead>
<tr>
<th>序号</th>
<th>分组</th>
<th>店铺名</th>
<th>店铺商城名</th>
<th>账号</th>
<th>操作</th>
</tr>
</thead>
<tbody id="chooseSkipPriceAsinShopListBody"></tbody>
</table>
</div>
<div class="pagination" id="chooseSkipPriceAsinShopPagination"></div>
<div style="margin-top:16px;display:flex;gap:8px;justify-content:flex-end;">
<button class="btn btn-secondary" id="btnCloseChooseSkipPriceAsinShopModal" type="button">关闭</button>
</div>
</div>
</div>
<div class="modal-mask" id="editSkipPriceAsinModal">
<div class="modal">
<h3>编辑跳过跟价 ASIN</h3>
<input type="hidden" id="editSkipPriceAsinId">
<input type="hidden" id="editSkipPriceAsinCountry">
<div class="form-group">
<label>店铺名</label>
<input type="text" id="editSkipPriceAsinShopName" readonly style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>国家</label>
<input type="text" id="editSkipPriceAsinCountryLabel" readonly style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>ASIN</label>
<input type="text" id="editSkipPriceAsinValue" placeholder="请输入 ASIN">
</div>
<div class="form-group">
<label>最低价</label>
<input type="number" id="editSkipPriceMinimumPrice" min="0" step="0.01" placeholder="请输入最低价,可留空">
</div>
<p class="msg" id="msgEditSkipPriceAsin"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveSkipPriceAsin">保存</button>
<button class="btn btn-secondary" id="btnCloseEditSkipPriceAsin">取消</button>
</div>
</div>
</div>
<div class="modal-mask" id="chooseQueryAsinShopModal">
<div class="modal" style="max-width:900px;width:90%;max-height:80vh;display:flex;flex-direction:column;">
<h3>选择店铺</h3>
<div class="form-row">
<div class="form-group" style="min-width:180px;">
<label>分组</label>
<select id="chooseQueryAsinShopGroupId">
<option value="">全部分组</option>
</select>
</div>
<div class="form-group" style="min-width:220px;">
<label>店铺名</label>
<input type="text" id="chooseQueryAsinShopKeyword" placeholder="请输入店铺名">
</div>
<button class="btn" id="btnSearchChooseQueryAsinShop" type="button">查询</button>
</div>
<div style="flex:1;min-height:0;overflow:auto;">
<table>
<thead>
<tr>
<th>序号</th>
<th>分组</th>
<th>店铺名</th>
<th>店铺商城名</th>
<th>账号</th>
<th>操作</th>
</tr>
</thead>
<tbody id="chooseQueryAsinShopListBody"></tbody>
</table>
</div>
<div class="pagination" id="chooseQueryAsinShopPagination"></div>
<div style="margin-top:16px;display:flex;gap:8px;justify-content:flex-end;">
<button class="btn btn-secondary" id="btnCloseChooseQueryAsinShopModal" type="button">关闭</button>
</div>
</div>
</div>
<div class="modal-mask" id="editQueryAsinModal">
<div class="modal">
<h3>编辑查询 ASIN</h3>
<input type="hidden" id="editQueryAsinId">
<input type="hidden" id="editQueryAsinCountry">
<div class="form-group">
<label>店铺名</label>
<input type="text" id="editQueryAsinShopName" readonly style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>国家</label>
<input type="text" id="editQueryAsinCountryLabel" readonly style="background:#f5f5f5;">
</div>
<div class="form-group">
<label>ASIN</label>
<input type="text" id="editQueryAsinValue" placeholder="请输入 ASIN">
</div>
<p class="msg" id="msgEditQueryAsin"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveQueryAsin">保存</button>
<button class="btn btn-secondary" id="btnCloseEditQueryAsin">取消</button>
</div>
</div>
</div>
<div class="modal-mask" id="editShopManageModal">
<div class="modal">
<h3>编辑店铺</h3>
<input type="hidden" id="editShopManageId">
<div class="form-group">
<label>分组</label>
<div style="display:flex;gap:8px;align-items:center;">
<select id="editShopManageGroupSelect" style="min-width:200px;">
<option value="">请选择分组</option>
</select>
<button class="btn btn-secondary" id="btnManageShopGroupsFromEdit" type="button">管理分组</button>
</div>
</div>
<div class="form-group">
<label>店铺名</label>
<input type="text" id="editShopManageShopName" placeholder="店铺名">
</div>
<div class=" form-group">
<label>店铺商城名</label>
<input type="text" id="editShopManageMallName" placeholder="店铺商城名">
</div>
<div class=" form-group">
<label>账号</label>
<input type="text" id="editShopManageAccount" placeholder="账号">
</div>
<div class="form-group">
<label>密码</label>
<input type="text" id="editShopManagePassword" placeholder="密码">
</div>
<p class="msg" id="msgEditShopManage"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveShopManage">保存</button>
<button class="btn btn-secondary" id="btnCloseEditShopManage">取消</button>
</div>
</div>
</div>
<!-- 编辑店铺密钥弹窗 -->
<div class="modal-mask" id="editShopKeyModal">
<div class="modal">
<h3>编辑店铺密钥</h3>
<input type="hidden" id="editShopKeyId">
<div class="form-group">
<label>紫鸟账号名称</label>
<input type="text" id="editShopKeyZiniaoAccountName" placeholder="紫鸟账号名称">
</div>
<div class="form-group">
<label>紫鸟令牌</label>
<input type="text" id="editShopKeyZiniaoToken" placeholder="紫鸟令牌">
</div>
<p class="msg" id="msgEditShopKey"></p>
<div style="margin-top:16px;display:flex;gap:8px;">
<button class="btn" id="btnSaveShopKey">保存</button>
<button class="btn btn-secondary" id="btnCloseEditShopKey">取消</button>
</div>
</div>
</div>
<script src="/static/admin.js"></script>
</body>
</html>