// 全局状态变量(供 app.js 引用) var orderPage = 1, orderHasMore = true, orderLoading = false; var otherIncomePage = 1, otherIncomeHasMore = true, otherIncomeLoading = false; var dispatchPage = 1, dispatchHasMore = true, dispatchLoading = false; var redEnvelopePage = 1, redEnvelopeHasMore = true, redEnvelopeLoading = false; var milkTeaPage = 1, milkTeaHasMore = true, milkTeaLoading = false; // 通用分页状态管理 const listConfig = { orderList: { getPage: () => orderPage, setPage: (v) => orderPage = v, getHasMore: () => orderHasMore, setHasMore: (v) => orderHasMore = v, getLoading: () => orderLoading, setLoading: (v) => orderLoading = v, emptyMsg: '暂无接单记录', endpoint: '/api/records/orders', renderItem: renderOrderItem }, otherIncomeList: { getPage: () => otherIncomePage, setPage: (v) => otherIncomePage = v, getHasMore: () => otherIncomeHasMore, setHasMore: (v) => otherIncomeHasMore = v, getLoading: () => otherIncomeLoading, setLoading: (v) => otherIncomeLoading = v, emptyMsg: '暂无红包及其他收入记录', endpoint: '/api/records/other-income', renderItem: renderOtherIncomeItem }, dispatchList: { getPage: () => dispatchPage, setPage: (v) => dispatchPage = v, getHasMore: () => dispatchHasMore, setHasMore: (v) => dispatchHasMore = v, getLoading: () => dispatchLoading, setLoading: (v) => dispatchLoading = v, emptyMsg: '暂无派单记录', endpoint: '/api/records/dispatches', renderItem: renderDispatchItem }, redEnvelopeList: { getPage: () => redEnvelopePage, setPage: (v) => redEnvelopePage = v, getHasMore: () => redEnvelopeHasMore, setHasMore: (v) => redEnvelopeHasMore = v, getLoading: () => redEnvelopeLoading, setLoading: (v) => redEnvelopeLoading = v, emptyMsg: '暂无红包收入记录', endpoint: '/api/records/red-envelope', renderItem: renderRedEnvelopeItem }, milkTeaList: { getPage: () => milkTeaPage, setPage: (v) => milkTeaPage = v, getHasMore: () => milkTeaHasMore, setHasMore: (v) => milkTeaHasMore = v, getLoading: () => milkTeaLoading, setLoading: (v) => milkTeaLoading = v, emptyMsg: '暂无奶茶收入记录', endpoint: '/api/records/milk-tea', renderItem: renderMilkTeaItem } }; // 通用列表加载函数 async function loadList(listId, append) { const config = listConfig[listId]; if (!config) return; if (config.getLoading() || (!append && !config.getHasMore())) return; config.setLoading(true); document.getElementById(listId.replace('List', 'Loading')).style.display = 'block'; try { const res = await fetch(API + config.endpoint + '?page=' + config.getPage() + '&limit=20&year=' + currentYear + '&month=' + currentMonth, { headers: headers() }); if (!res.ok) return; const data = await res.json(); const container = document.getElementById(listId); if (!append) container.innerHTML = ''; if (data.records.length === 0) { if (config.getPage() === 1) container.innerHTML = '
' + config.emptyMsg + '
'; config.setHasMore(false); } else { const grouped = {}; data.records.forEach(r => { const date = formatLocalDate(r.created_at); if (!grouped[date]) grouped[date] = []; grouped[date].push(r); }); let html = ''; for (const [date, records] of Object.entries(grouped)) { html += '
' + date + '
'; records.forEach(r => { html += config.renderItem(r); }); html += '
'; } container.insertAdjacentHTML('beforeend', html); config.setHasMore(data.records.length >= 20); config.setPage(config.getPage() + 1); } } catch (e) { console.error(e); } config.setLoading(false); document.getElementById(listId.replace('List', 'Loading')).style.display = 'none'; } // 通用渲染函数 function renderOrderItem(r) { const time = formatLocalTime(r.created_at); return '
' + '
' + (r.boss || '-') + '' + (r.amount || 0).toFixed(2) + '
' + '
' + (r.quantity || 0) + '单 × ' + (r.unit_price || 0).toFixed(2) + '' + time + (r.partner ? ' · ' + r.partner : '') + '
'; } function renderOtherIncomeItem(r) { const time = formatLocalTime(r.created_at); const displayCategory = r.category === '红包收入' ? '红包' : (r.category || '-'); return '
' + '
' + displayCategory + (r.boss ? ' · ' + r.boss : '') + '' + (r.amount || 0).toFixed(2) + '
' + '
' + (r.source || '') + '' + time + '
'; } function renderDispatchItem(r) { const time = formatLocalTime(r.created_at); const unitPrice = r.unit_price || (r.quantity ? r.amount / r.quantity : 0); return '
' + '
' + (r.boss || '-') + '' + (r.amount || 0).toFixed(2) + '
' + '
' + (r.quantity || 0) + '单 × ' + (r.rebate || 0).toFixed(2) + '(单价' + unitPrice.toFixed(2) + ')' + time + (r.partner ? ' · ' + r.partner : '') + '
'; } function renderRedEnvelopeItem(r) { const time = formatLocalTime(r.created_at); return '
' + '
红包' + (r.amount || 0).toFixed(2) + '
' + '
' + (r.source || '') + '' + time + '
'; } function renderMilkTeaItem(r) { const time = formatLocalTime(r.created_at); return '
' + '
奶茶' + (r.amount || 0).toFixed(2) + '
' + '
' + (r.source || '') + '' + time + '
'; } // 滚动加载 window.addEventListener('scroll', () => { const pageListMap = [ { page: 'orderListPage', list: 'orderList' }, { page: 'dispatchListPage', list: 'dispatchList' }, { page: 'otherIncomeListPage', list: 'otherIncomeList' }, { page: 'redEnvelopeListPage', list: 'redEnvelopeList' }, { page: 'milkTeaListPage', list: 'milkTeaList' } ]; for (const m of pageListMap) { if (document.getElementById(m.page).classList.contains('active')) { if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) { const config = listConfig[m.list]; if (config && config.getHasMore() && !config.getLoading()) { loadList(m.list, true); } } break; } } }); // 兼容旧接口 async function loadOrders(append) { return loadList('orderList', append); } async function loadOtherIncome(append) { return loadList('otherIncomeList', append); } async function loadDispatches(append) { return loadList('dispatchList', append); } async function loadRedEnvelope(append) { return loadList('redEnvelopeList', append); } async function loadMilkTea(append) { return loadList('milkTeaList', append); }