refactor: 前端JS拆分为8个模块(base/list/monitor/editor/tasks/tools/apps/admin,按依赖顺序加载)+ 删除废弃文件(start_web.bat/main.py/fix_web.bat/cleanup.py,web已全覆盖)+ 文档同步 + 修复/api/summary缺导入
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// 统一列表组件:setListPager 搜索 + 分页 + 排序(_lpSort)
|
||||
// ================== 通用列表:搜索 + 分页 + 排序 ==================
|
||||
// 用法:
|
||||
// setListPager(key,{data:()=>array, filter:(item,kw)=>bool, render:(item)=>html,
|
||||
// tbody:'tb-id', pager:'pager-id', pageSize:N,
|
||||
// sortValue:(item,colKey)=>值, // 可排序列的取值函数
|
||||
// empty:'<tr>...'});
|
||||
// applyListPager(key); // 数据变化后重渲染(含搜索/翻页/排序状态)
|
||||
// initListSearch(key,'search-id'); // 搜索框绑定
|
||||
// _lpSort(key,'colKey'); // 表头排序:th 加 data-sort="colKey" + onclick,
|
||||
// // 再点切换升降序,第三次取消;排序指示器自动更新
|
||||
var _LIST_PAGERS={};
|
||||
|
||||
function _lp(key){ return _LIST_PAGERS[key] || (_LIST_PAGERS[key]={page:1,kw:'',cfg:null,sort:null}); }
|
||||
|
||||
function setListPager(key,cfg){
|
||||
// 只更新配置,不重置 page/kw/sort —— 监控列表 5 秒自动刷新时保持用户当前状态
|
||||
var st=_lp(key); st.cfg=cfg;
|
||||
}
|
||||
function initListSearch(key,inputId){
|
||||
var input=document.getElementById(inputId);
|
||||
if(!input||input.dataset.bound)return;
|
||||
input.dataset.bound='1';
|
||||
input.addEventListener('input',function(){
|
||||
var st=_lp(key); st.kw=this.value.trim(); st.page=1; applyListPager(key);
|
||||
});
|
||||
}
|
||||
function _lpSort(key,colKey){
|
||||
var st=_lp(key);
|
||||
if(st.sort&&st.sort.key===colKey){
|
||||
if(st.sort.dir===1)st.sort.dir=-1; // 升序 → 降序
|
||||
else if(st.sort.dir===-1)st.sort=null; // 降序 → 取消排序
|
||||
else st.sort={key:colKey,dir:1};
|
||||
}else{
|
||||
st.sort={key:colKey,dir:1};
|
||||
}
|
||||
applyListPager(key);
|
||||
}
|
||||
function applyListPager(key){
|
||||
var st=_lp(key);
|
||||
if(!st.cfg)return;
|
||||
var cfg=st.cfg;
|
||||
var all=(cfg.data&&cfg.data())||[];
|
||||
var kw=st.kw.toLowerCase();
|
||||
var filtered=kw?all.filter(function(x){return cfg.filter(x,kw);}):all;
|
||||
// 排序:cfg.sortValue 取列值;空值/缺失恒排最后;字符串用中文数字感知比较(10 排在 9 后)
|
||||
if(st.sort&&cfg.sortValue){
|
||||
var sk=st.sort.key, dir=st.sort.dir;
|
||||
filtered=filtered.slice().sort(function(a,b){
|
||||
var va=cfg.sortValue(a,sk), vb=cfg.sortValue(b,sk);
|
||||
if(va===vb)return 0;
|
||||
if(va==null||va==='')return 1;
|
||||
if(vb==null||vb==='')return -1;
|
||||
if(typeof va==='number'&&typeof vb==='number')return (va-vb)*dir;
|
||||
return String(va).localeCompare(String(vb),'zh-Hans-CN',{numeric:true})*dir;
|
||||
});
|
||||
}
|
||||
var pageSize=cfg.pageSize||10;
|
||||
var pages=Math.max(1,Math.ceil(filtered.length/pageSize));
|
||||
if(st.page>pages)st.page=pages;
|
||||
if(st.page<1)st.page=1;
|
||||
var start=(st.page-1)*pageSize;
|
||||
var slice=filtered.slice(start,start+pageSize);
|
||||
var tb=document.getElementById(cfg.tbody);
|
||||
if(tb){
|
||||
tb.innerHTML=slice.map(cfg.render).join('')||(cfg.empty||'<tr><td colspan="20" class="empty">无数据</td></tr>');
|
||||
// 表头排序指示器(th[data-sort],所有表格统一)
|
||||
if(cfg.sortValue){
|
||||
var table=tb.closest('table');
|
||||
if(table)table.querySelectorAll('thead th[data-sort]').forEach(function(th){
|
||||
th.classList.add('sortable');
|
||||
th.classList.toggle('sort-asc',!!st.sort&&st.sort.key===th.dataset.sort&&st.sort.dir===1);
|
||||
th.classList.toggle('sort-desc',!!st.sort&&st.sort.key===th.dataset.sort&&st.sort.dir===-1);
|
||||
});
|
||||
}
|
||||
}
|
||||
var pg=document.getElementById(cfg.pager);
|
||||
if(pg)pg.innerHTML=_lpPagerHtml(key,pages,st.page,filtered.length,pageSize);
|
||||
}
|
||||
function _lpPagerHtml(key,pages,cur,total,pageSize){
|
||||
if(pages<=1)return total>0?'<div class="list-pager"><span class="lp-total">共 '+total+' 条</span></div>':'';
|
||||
var h='<div class="list-pager"><span class="lp-total">共 '+total+' 条</span>';
|
||||
h+='<button class="btn btn-xs" onclick="_lpGo(\''+key+'\','+(cur-1)+')"'+(cur<=1?' disabled':'')+'>‹ 上一页</button>';
|
||||
for(var p=Math.max(1,cur-2);p<=Math.min(pages,cur+2);p++){
|
||||
h+='<button class="btn btn-xs'+(p===cur?' btn-primary':'')+'" onclick="_lpGo(\''+key+'\','+p+')">'+p+'</button>';
|
||||
}
|
||||
h+='<button class="btn btn-xs" onclick="_lpGo(\''+key+'\','+(cur+1)+')"'+(cur>=pages?' disabled':'')+'>下一页 ›</button>';
|
||||
h+='</div>';
|
||||
return h;
|
||||
}
|
||||
function _lpGo(key,p){
|
||||
var st=_lp(key); st.page=p; applyListPager(key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user