@@ -292,6 +292,9 @@ INDEX_TEMPLATE = '''
<!-- 列表 -->
<div id= " itemList " ></div>
<!-- 分页 -->
<div id= " pagination " class= " d-flex justify-content-center mt-3 " ></div>
</div>
</div>
</div>
@@ -506,9 +509,9 @@ const API_BASE = '/api';
let currentFilter = { type: ' ' , status: ' ' };
// 初始化
document.addEventListener( ' DOMContentLoaded ' , () => {
document.addEventListener( ' DOMContentLoaded ' , async () => {
await loadStats(); // 先加载统计,确保总数可用
loadItems();
loadStats();
loadTags();
// 标签输入自动提示
@@ -554,9 +557,13 @@ document.addEventListener('DOMContentLoaded', () => {
});
// 加载列表
async function loadItems() {
let currentPage = 1;
const pageSize = 20;
async function loadItems(page = 1) {
currentPage = page;
const keyword = document.getElementById( ' searchInput ' ).value;
let url = `$ {API_BASE} /items?limit=100 `;
let url = `$ {API_BASE} /items?limit=$ {pageSize} &offset=$ { (page-1)*pageSize} `;
if (currentFilter.type) url += `&type=$ {currentFilter.type} `;
if (currentFilter.status) url += `&status=$ {currentFilter.status} `;
if (keyword) url += `&keyword=$ { encodeURIComponent(keyword)}`;
@@ -566,6 +573,7 @@ async function loadItems() {
if (data.success) {
renderItems(data.data);
renderPagination(data.data.length, page);
}
}
@@ -602,6 +610,53 @@ function renderItems(items) {
`).join( ' ' );
}
// 渲染分页
function renderPagination(itemCount, page) {
const container = document.getElementById( ' pagination ' );
const total = parseInt(document.getElementById( ' statTotal ' ).textContent);
const totalPages = Math.ceil(total / pageSize);
if (totalPages <= 1) {
container.innerHTML = ' ' ;
return;
}
let html = ' <nav><ul class= " pagination " > ' ;
// 上一页
html += `<li class= " page-item $ { page === 1 ? ' disabled ' : ' ' } " >
<a class= " page-link " href= " # " onclick= " loadItems($ { page-1}); return false; " >«</a>
</li>`;
// 页码( 最多显示5个)
const startPage = Math.max(1, page - 2);
const endPage = Math.min(totalPages, page + 2);
if (startPage > 1) {
html += `<li class= " page-item " ><a class= " page-link " href= " # " onclick= " loadItems(1); return false; " >1</a></li>`;
if (startPage > 2) html += `<li class= " page-item disabled " ><span class= " page-link " >...</span></li>`;
}
for (let p = startPage; p <= endPage; p++) {
html += `<li class= " page-item $ { p === page ? ' active ' : ' ' } " >
<a class= " page-link " href= " # " onclick= " loadItems($ {p} ); return false; " >$ {p} </a>
</li>`;
}
if (endPage < totalPages) {
if (endPage < totalPages - 1) html += `<li class= " page-item disabled " ><span class= " page-link " >...</span></li>`;
html += `<li class= " page-item " ><a class= " page-link " href= " # " onclick= " loadItems($ {totalPages} ); return false; " >$ {totalPages} </a></li>`;
}
// 下一页
html += `<li class= " page-item $ { page === totalPages ? ' disabled ' : ' ' } " >
<a class= " page-link " href= " # " onclick= " loadItems($ { page+1}); return false; " >»</a>
</li>`;
html += ' </ul></nav> ' ;
container.innerHTML = html;
}
// 加载统计
async function loadStats() {
const res = await fetch(`$ {API_BASE} /stats`);
@@ -614,6 +669,12 @@ async function loadStats() {
}
}
// 刷新数据(统计+列表)
async function refreshData() {
await loadStats();
loadItems(currentPage);
}
// 添加条目
async function addItem() {
const type = document.getElementById( ' addType ' ).value;
@@ -639,24 +700,21 @@ async function addItem() {
if (res.ok) {
bootstrap.Modal.getInstance(document.getElementById( ' addModal ' )).hide();
document.getElementById( ' addForm ' ).reset();
loadItems ();
loadStats();
refreshData ();
}
}
// 完成待办
async function completeItem(id) {
await fetch(`$ {API_BASE} /items/$ {id} /done`, { method: ' POST ' });
loadItems ();
loadStats();
refreshData ();
}
// 删除条目
async function deleteItem(id) {
if (!confirm( ' 确认删除? ' )) return;
await fetch(`$ {API_BASE} /items/$ {id} `, { method: ' DELETE ' });
loadItems ();
loadStats();
refreshData ();
}
// 当前查看的条目ID
@@ -782,8 +840,7 @@ async function saveEdit() {
if (res.ok) {
bootstrap.Modal.getInstance(document.getElementById( ' editModal ' )).hide();
loadItems ();
loadStats();
refreshData ();
}
}