增加搜索

This commit is contained in:
yml2213
2026-06-19 11:35:04 +08:00
parent 4a5669963f
commit 1805edc63a
+64 -10
View File
@@ -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 记录当前选择的商品,提交时会应用到所有已勾选账号。