增加搜索
This commit is contained in:
+64
-10
@@ -9,9 +9,15 @@
|
||||
body{font-family:'Microsoft YaHei',sans-serif;background:#0d1117;color:#c9d1d9;display:flex;height:100vh}
|
||||
|
||||
/* ========== 左侧商品列表 ========== */
|
||||
.left{width:280px;min-width:280px;background:#161b22;border-right:1px solid#30363d;display:flex;flex-direction:column}
|
||||
.left-header{padding:10px;border-bottom:1px solid#30363d}
|
||||
.left-list{flex:1;overflow-y:auto;padding:8px}
|
||||
.left{width:280px;min-width:280px;background:#161b22;border-right:1px solid#30363d;display:flex;flex-direction:column}
|
||||
.left-header{padding:10px;border-bottom:1px solid#30363d}
|
||||
.product-search{display:flex;align-items:center;gap:6px;margin-top:8px;background:#0d1117;border:1px solid#30363d;border-radius:5px;padding:0 6px}
|
||||
.product-search:focus-within{border-color:#58a6ff}
|
||||
.product-search input{flex:1;min-width:0;height:32px;border:0;outline:0;background:transparent;color:#c9d1d9;font-size:13px}
|
||||
.product-search input::placeholder{color:#6e7681}
|
||||
.product-search .search-clear{width:22px;height:22px;border:0;border-radius:4px;background:transparent;color:#8b949e;cursor:pointer;font-size:16px;line-height:20px;display:none}
|
||||
.product-search .search-clear:hover{background:#21262d;color:#c9d1d9}
|
||||
.left-list{flex:1;overflow-y:auto;padding:8px}
|
||||
.left-list .prod-item{display:flex;align-items:center;gap:8px;padding:8px;margin:4px 0;background:#21262d;border-radius:6px;cursor:pointer;border:2px solid transparent;transition:.2s}
|
||||
.left-list .prod-item:hover{border-color:#58a6ff}
|
||||
.left-list .prod-item.active{border-color:#f78166;background:#1a1f2b}
|
||||
@@ -95,6 +101,11 @@
|
||||
<div class="left">
|
||||
<div class="left-header">
|
||||
<button class="btn btn-blue" id="btnLoadProducts" onclick="loadProducts(true)" style="width:100%">🔄 刷新商品</button>
|
||||
<div class="product-search">
|
||||
<span style="color:#6e7681;font-size:13px">🔍</span>
|
||||
<input id="productSearch" type="search" placeholder="搜索商品名 / ID / 积分 / 库存" autocomplete="off" oninput="setProductSearch(this.value)">
|
||||
<button class="search-clear" id="btnClearProductSearch" type="button" onclick="clearProductSearch()" title="清空搜索">×</button>
|
||||
</div>
|
||||
<div class="product-meta" id="productMeta">库存未刷新</div>
|
||||
</div>
|
||||
<div class="left-list" id="prodList">
|
||||
@@ -154,6 +165,7 @@
|
||||
|
||||
<script>
|
||||
let accounts=[], products=[], productInfo=null, selProdId=null, selProdName='', selAccs=new Set();
|
||||
let productSearch='';
|
||||
let scheduleActive=false, countdownTimer=null, lastResults={};
|
||||
let lastLogId=0;
|
||||
let statusMap={}; // ← 加这行
|
||||
@@ -165,15 +177,20 @@
|
||||
let savedProd=localStorage.getItem('selProd');
|
||||
let savedProdName=localStorage.getItem('selProdName');
|
||||
let savedTime=localStorage.getItem('targetTime');
|
||||
let savedAdv=localStorage.getItem('advance');
|
||||
let savedAdv=localStorage.getItem('advance');
|
||||
let savedStatus=localStorage.getItem('statusMap'); // ← 提前读取
|
||||
let savedProductSearch=localStorage.getItem('productSearch');
|
||||
|
||||
clearLegacyProductBindings();
|
||||
if(savedAccs) selAccs=new Set(JSON.parse(savedAccs));
|
||||
if(savedProd){ selProdId=savedProd; selProdName=savedProdName||''; document.getElementById('selProd').textContent=selProdName; }
|
||||
if(savedTime) document.getElementById('targetTime').value=savedTime;
|
||||
if(savedAdv) document.getElementById('advance').value=savedAdv;
|
||||
if(savedStatus) statusMap=JSON.parse(savedStatus); // ← 提前恢复
|
||||
if(savedTime) document.getElementById('targetTime').value=savedTime;
|
||||
if(savedAdv) document.getElementById('advance').value=savedAdv;
|
||||
if(savedStatus) statusMap=JSON.parse(savedStatus); // ← 提前恢复
|
||||
if(savedProductSearch) {
|
||||
productSearch=savedProductSearch;
|
||||
document.getElementById('productSearch').value=productSearch;
|
||||
}
|
||||
|
||||
|
||||
await loadAccounts();
|
||||
@@ -196,6 +213,36 @@
|
||||
setInterval(fetchServerLogs,2000);
|
||||
fetchServerLogs();
|
||||
}
|
||||
|
||||
// setProductSearch 更新商品搜索词,并即时过滤左侧商品列表。
|
||||
function setProductSearch(value) {
|
||||
productSearch = String(value || '').trim();
|
||||
if (productSearch) localStorage.setItem('productSearch', productSearch);
|
||||
else localStorage.removeItem('productSearch');
|
||||
renderProducts();
|
||||
renderProductMeta();
|
||||
}
|
||||
|
||||
// clearProductSearch 清空商品搜索词。
|
||||
function clearProductSearch() {
|
||||
productSearch = '';
|
||||
localStorage.removeItem('productSearch');
|
||||
document.getElementById('productSearch').value = '';
|
||||
renderProducts();
|
||||
renderProductMeta();
|
||||
}
|
||||
|
||||
// filteredProducts 根据搜索词过滤商品,支持名称、ID、积分和库存。
|
||||
function filteredProducts() {
|
||||
let keyword = productSearch.toLowerCase();
|
||||
if (!keyword) return products;
|
||||
return products.filter(p => [
|
||||
p.commodityName,
|
||||
p.commodityId,
|
||||
p.score,
|
||||
p.count
|
||||
].some(v => String(v ?? '').toLowerCase().includes(keyword)));
|
||||
}
|
||||
|
||||
// updateTime 从后端获取斗鱼服务端时间,并刷新顶部时间展示。
|
||||
function updateTime(){
|
||||
@@ -308,15 +355,18 @@
|
||||
// renderProducts 根据当前商品数组绘制左侧商品列表,并标记已选商品。
|
||||
function renderProducts(){
|
||||
let h='';
|
||||
let list = filteredProducts();
|
||||
document.getElementById('btnClearProductSearch').style.display = productSearch ? 'block' : 'none';
|
||||
// 遍历商品缓存,生成每个商品的点击项和库存、积分信息。
|
||||
products.forEach(p=>{
|
||||
list.forEach(p=>{
|
||||
h+=`<div class="prod-item${selProdId==p.commodityId?' active':''}" onclick="selProduct('${jsAttr(p.commodityId)}','${jsAttr(p.commodityName)}')">
|
||||
<img src="${p.pic}" onerror="this.style.display='none'">
|
||||
<div class="pinfo"><div class="pname">${escHtml(p.commodityName)}</div>
|
||||
<div class="pmeta"><span class="pscore">💰${p.score}</span><span class="pstock${p.count<500?' low':''}">📦${p.count}</span></div></div>
|
||||
</div>`;
|
||||
});
|
||||
document.getElementById('prodList').innerHTML=h||'<div style="text-align:center;color:#8b949e;padding:40px 10px;font-size:13px">暂无实时商品数据</div>';
|
||||
let emptyText = productSearch ? `没有匹配“${escHtml(productSearch)}”的商品` : '暂无实时商品数据';
|
||||
document.getElementById('prodList').innerHTML=h||`<div style="text-align:center;color:#8b949e;padding:40px 10px;font-size:13px">${emptyText}</div>`;
|
||||
}
|
||||
// renderProductMeta 显示库存来源和刷新时间,避免把旧库存当实时库存。
|
||||
function renderProductMeta(errorMsg) {
|
||||
@@ -332,7 +382,11 @@
|
||||
return;
|
||||
}
|
||||
meta.className = 'product-meta ' + (productInfo.stale ? 'warn' : 'good');
|
||||
meta.textContent = `实时库存 ${productInfo.count} 个,刷新于 ${productInfo.fetchedAt}`;
|
||||
if (productSearch) {
|
||||
meta.textContent = `实时库存 ${filteredProducts().length}/${productInfo.count} 个,刷新于 ${productInfo.fetchedAt}`;
|
||||
} else {
|
||||
meta.textContent = `实时库存 ${productInfo.count} 个,刷新于 ${productInfo.fetchedAt}`;
|
||||
}
|
||||
}
|
||||
|
||||
// selProduct 记录当前选择的商品,提交时会应用到所有已勾选账号。
|
||||
|
||||
Reference in New Issue
Block a user