fix: 修复分页和缓存相关bug
- 前端: 移除无限滚动,改为一次性加载全部数据 - 前端: monthly-records接口添加limit=1000参数 - 前端: 修复edit-modal.js中loadListData调用参数 - 后端: 修复stats.js中getCached函数Promise处理 - 后端: 修复records.js各接口正确传递limit参数 - 后端: 修复partner-records SQL参数数量问题 - 统一版本号强制浏览器刷新缓存 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
df3a9daa65
commit
9126348d1b
+2
-2
@@ -460,9 +460,9 @@
|
|||||||
<script src="js/auth.js"></script>
|
<script src="js/auth.js"></script>
|
||||||
<script src="js/autocomplete.js"></script>
|
<script src="js/autocomplete.js"></script>
|
||||||
<script src="js/month-picker.js"></script>
|
<script src="js/month-picker.js"></script>
|
||||||
<script src="js/stats.js?v=2026022401"></script>
|
<script src="js/stats.js?v=2026032522"></script>
|
||||||
<script src="js/ranking.js"></script>
|
<script src="js/ranking.js"></script>
|
||||||
<script src="js/order-list.js"></script>
|
<script src="js/order-list.js?v=2026032521"></script>
|
||||||
<script src="js/edit-modal.js"></script>
|
<script src="js/edit-modal.js"></script>
|
||||||
<script src="js/record-form.js"></script>
|
<script src="js/record-form.js"></script>
|
||||||
<script src="js/import-export.js"></script>
|
<script src="js/import-export.js"></script>
|
||||||
|
|||||||
+10
-15
@@ -175,31 +175,26 @@ function showPage(pageId) {
|
|||||||
}
|
}
|
||||||
if (pageId === 'orderListPage') {
|
if (pageId === 'orderListPage') {
|
||||||
document.getElementById('orderListTitle').textContent = `${currentYear}年${currentMonth}月接单列表`;
|
document.getElementById('orderListTitle').textContent = `${currentYear}年${currentMonth}月接单列表`;
|
||||||
orderPage = 1; orderHasMore = true;
|
initList('orderList');
|
||||||
document.getElementById('orderList').innerHTML = '';
|
loadListData('orderList');
|
||||||
loadOrders();
|
|
||||||
}
|
}
|
||||||
if (pageId === 'otherIncomeListPage') {
|
if (pageId === 'otherIncomeListPage') {
|
||||||
document.getElementById('otherIncomeListTitle').textContent = `${currentYear}年${currentMonth}月红包及其他收入`;
|
document.getElementById('otherIncomeListTitle').textContent = `${currentYear}年${currentMonth}月红包及其他收入`;
|
||||||
otherIncomePage = 1; otherIncomeHasMore = true;
|
initList('otherIncomeList');
|
||||||
document.getElementById('otherIncomeList').innerHTML = '';
|
loadListData('otherIncomeList');
|
||||||
loadOtherIncome();
|
|
||||||
}
|
}
|
||||||
if (pageId === 'dispatchListPage') {
|
if (pageId === 'dispatchListPage') {
|
||||||
document.getElementById('dispatchListTitle').textContent = `${currentYear}年${currentMonth}月派单列表`;
|
document.getElementById('dispatchListTitle').textContent = `${currentYear}年${currentMonth}月派单列表`;
|
||||||
dispatchPage = 1; dispatchHasMore = true;
|
initList('dispatchList');
|
||||||
document.getElementById('dispatchList').innerHTML = '';
|
loadListData('dispatchList');
|
||||||
loadDispatches();
|
|
||||||
}
|
}
|
||||||
if (pageId === 'redEnvelopeListPage') {
|
if (pageId === 'redEnvelopeListPage') {
|
||||||
redEnvelopePage = 1; redEnvelopeHasMore = true;
|
initList('redEnvelopeList');
|
||||||
document.getElementById('redEnvelopeList').innerHTML = '';
|
loadListData('redEnvelopeList');
|
||||||
loadRedEnvelope();
|
|
||||||
}
|
}
|
||||||
if (pageId === 'milkTeaListPage') {
|
if (pageId === 'milkTeaListPage') {
|
||||||
milkTeaPage = 1; milkTeaHasMore = true;
|
initList('milkTeaList');
|
||||||
document.getElementById('milkTeaList').innerHTML = '';
|
loadListData('milkTeaList');
|
||||||
loadMilkTea();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,17 +74,14 @@ function closeEditModal() {
|
|||||||
function refreshCurrentList() {
|
function refreshCurrentList() {
|
||||||
const cat = document.getElementById('editCategory').value;
|
const cat = document.getElementById('editCategory').value;
|
||||||
if (cat === '派单') {
|
if (cat === '派单') {
|
||||||
dispatchPage = 1; dispatchHasMore = true;
|
initList('dispatchList');
|
||||||
document.getElementById('dispatchList').innerHTML = '';
|
loadListData('dispatchList');
|
||||||
loadDispatches();
|
|
||||||
} else if (cat === '接单') {
|
} else if (cat === '接单') {
|
||||||
orderPage = 1; orderHasMore = true;
|
initList('orderList');
|
||||||
document.getElementById('orderList').innerHTML = '';
|
loadListData('orderList');
|
||||||
loadOrders();
|
|
||||||
} else {
|
} else {
|
||||||
otherIncomePage = 1; otherIncomeHasMore = true;
|
initList('otherIncomeList');
|
||||||
document.getElementById('otherIncomeList').innerHTML = '';
|
loadListData('otherIncomeList');
|
||||||
loadOtherIncome();
|
|
||||||
}
|
}
|
||||||
// 如果在日详情页也刷新
|
// 如果在日详情页也刷新
|
||||||
if (document.getElementById('dailyDetailPage').classList.contains('active') && currentDailyDate) {
|
if (document.getElementById('dailyDetailPage').classList.contains('active') && currentDailyDate) {
|
||||||
|
|||||||
+126
-77
@@ -1,55 +1,121 @@
|
|||||||
// 防抖工具函数
|
// ============================================
|
||||||
function debounce(fn, delay) {
|
// 通用列表管理 - 一次性加载
|
||||||
let timeoutId;
|
// ============================================
|
||||||
return function(...args) {
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
timeoutId = setTimeout(() => fn.apply(this, args), delay);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全局状态变量(供 app.js 引用)
|
// 当前活动的列表状态
|
||||||
var orderPage = 1, orderHasMore = true, orderLoading = false;
|
let currentListId = null;
|
||||||
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 = {
|
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 },
|
orderList: { endpoint: '/api/records/orders', emptyMsg: '暂无接单记录', 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 },
|
otherIncomeList: { endpoint: '/api/records/other-income', emptyMsg: '暂无红包及其他收入记录', 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 },
|
dispatchList: { endpoint: '/api/records/dispatches', emptyMsg: '暂无派单记录', 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 },
|
redEnvelopeList: { endpoint: '/api/records/red-envelope', emptyMsg: '暂无红包收入记录', 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 }
|
milkTeaList: { endpoint: '/api/records/milk-tea', emptyMsg: '暂无奶茶收入记录', renderItem: renderMilkTeaItem }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 通用列表加载函数
|
// 通用列表加载状态(按 listId 存储)
|
||||||
async function loadList(listId, append) {
|
const listState = {
|
||||||
const config = listConfig[listId];
|
orderList: { loading: false, records: [] },
|
||||||
if (!config) return;
|
otherIncomeList: { loading: false, records: [] },
|
||||||
|
dispatchList: { loading: false, records: [] },
|
||||||
|
redEnvelopeList: { loading: false, records: [] },
|
||||||
|
milkTeaList: { loading: false, records: [] }
|
||||||
|
};
|
||||||
|
|
||||||
if (config.getLoading() || (!append && !config.getHasMore())) return;
|
// 初始化列表 - 清空状态
|
||||||
config.setLoading(true);
|
function initList(listId) {
|
||||||
document.getElementById(listId.replace('List', 'Loading')).style.display = 'block';
|
const state = listState[listId];
|
||||||
|
if (!state) return;
|
||||||
|
|
||||||
|
state.loading = false;
|
||||||
|
state.records = [];
|
||||||
|
|
||||||
|
const container = document.getElementById(listId);
|
||||||
|
if (container) {
|
||||||
|
container.innerHTML = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载列表数据
|
||||||
|
async function loadListData(listId) {
|
||||||
|
const config = listConfig[listId];
|
||||||
|
const state = listState[listId];
|
||||||
|
if (!config || !state) return;
|
||||||
|
|
||||||
|
// 防止重复加载
|
||||||
|
if (state.loading) {
|
||||||
|
console.log('[loadListData] already loading, skip');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.loading = true;
|
||||||
|
showLoading(listId, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(API + config.endpoint + '?page=' + config.getPage() + '&limit=20&year=' + currentYear + '&month=' + currentMonth, { headers: headers() });
|
console.log(`[loadListData] fetching ${listId}`);
|
||||||
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 = '<div class="ranking-empty">' + config.emptyMsg + '</div>';
|
const res = await fetch(API + config.endpoint + '?page=1&limit=1000&year=' + currentYear + '&month=' + currentMonth, { headers: headers() });
|
||||||
config.setHasMore(false);
|
|
||||||
} else {
|
if (!res.ok) {
|
||||||
|
console.error(`[loadListData] fetch failed: ${res.status}`);
|
||||||
|
state.loading = false;
|
||||||
|
showLoading(listId, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
console.log(`[loadListData] got ${data.records?.length || 0} records`);
|
||||||
|
|
||||||
|
state.records = data.records || [];
|
||||||
|
|
||||||
|
// 渲染
|
||||||
|
renderList(listId);
|
||||||
|
|
||||||
|
console.log(`[loadListData] ${listId} done, total records=${state.records.length}`);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`[loadListData] error:`, e);
|
||||||
|
} finally {
|
||||||
|
state.loading = false;
|
||||||
|
showLoading(listId, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示/隐藏加载指示器
|
||||||
|
function showLoading(listId, show) {
|
||||||
|
const loadingId = listId.replace('List', 'Loading');
|
||||||
|
const loadingEl = document.getElementById(loadingId);
|
||||||
|
if (loadingEl) {
|
||||||
|
loadingEl.style.display = show ? 'block' : 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染列表
|
||||||
|
function renderList(listId) {
|
||||||
|
const config = listConfig[listId];
|
||||||
|
const state = listState[listId];
|
||||||
|
if (!config || !state) return;
|
||||||
|
|
||||||
|
const container = document.getElementById(listId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
if (state.records.length === 0) {
|
||||||
|
container.innerHTML = '<div class="ranking-empty">' + config.emptyMsg + '</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按日期分组
|
||||||
const grouped = {};
|
const grouped = {};
|
||||||
data.records.forEach(r => {
|
state.records.forEach(r => {
|
||||||
const date = formatLocalDate(r.created_at);
|
const date = formatLocalDate(r.created_at);
|
||||||
if (!grouped[date]) grouped[date] = [];
|
if (!grouped[date]) grouped[date] = [];
|
||||||
grouped[date].push(r);
|
grouped[date].push(r);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
// 生成 HTML
|
||||||
let html = '';
|
let html = '';
|
||||||
for (const [date, records] of Object.entries(grouped)) {
|
for (const [date, records] of Object.entries(grouped)) {
|
||||||
html += '<div class="order-date-group" data-date="' + date + '"><div class="order-date-label">' + date + '</div>';
|
html += '<div class="order-date-group" data-date="' + date + '"><div class="order-date-label">' + date + '</div>';
|
||||||
@@ -58,17 +124,32 @@ async function loadList(listId, append) {
|
|||||||
});
|
});
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
container.insertAdjacentHTML('beforeend', html);
|
|
||||||
config.setHasMore(data.records.length >= 20);
|
|
||||||
config.setPage(config.getPage() + 1);
|
|
||||||
}
|
|
||||||
} catch (e) { console.error(e); }
|
|
||||||
|
|
||||||
config.setLoading(false);
|
container.innerHTML = html;
|
||||||
document.getElementById(listId.replace('List', 'Loading')).style.display = 'none';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通用渲染函数
|
// ============================================
|
||||||
|
// 列表滚动(已简化为一次性加载)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
function setupInfiniteScroll(listId) {
|
||||||
|
// 不再需要无限滚动,一次性加载全部数据
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 兼容接口
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
async function loadOrders() { return loadListData('orderList'); }
|
||||||
|
async function loadOtherIncome() { return loadListData('otherIncomeList'); }
|
||||||
|
async function loadDispatches() { return loadListData('dispatchList'); }
|
||||||
|
async function loadRedEnvelope() { return loadListData('redEnvelopeList'); }
|
||||||
|
async function loadMilkTea() { return loadListData('milkTeaList'); }
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 渲染函数
|
||||||
|
// ============================================
|
||||||
|
|
||||||
function renderOrderItem(r) {
|
function renderOrderItem(r) {
|
||||||
const time = formatLocalTime(r.created_at);
|
const time = formatLocalTime(r.created_at);
|
||||||
return '<div class="order-item" onclick=\'openEditModal(' + JSON.stringify(r).replace(/'/g, "'") + ')\'>' +
|
return '<div class="order-item" onclick=\'openEditModal(' + JSON.stringify(r).replace(/'/g, "'") + ')\'>' +
|
||||||
@@ -105,35 +186,3 @@ function renderMilkTeaItem(r) {
|
|||||||
'<div class="order-item-top"><span class="order-item-boss">奶茶</span><span class="order-item-amount">' + (r.amount || 0).toFixed(2) + '</span></div>' +
|
'<div class="order-item-top"><span class="order-item-boss">奶茶</span><span class="order-item-amount">' + (r.amount || 0).toFixed(2) + '</span></div>' +
|
||||||
'<div class="order-item-bottom"><span>' + (r.source || '') + '</span><span>' + time + '</span></div></div>';
|
'<div class="order-item-bottom"><span>' + (r.source || '') + '</span><span>' + time + '</span></div></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 滚动加载(带防抖)
|
|
||||||
const handleListScroll = debounce(() => {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
window.addEventListener('scroll', handleListScroll);
|
|
||||||
|
|
||||||
// 兼容旧接口
|
|
||||||
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); }
|
|
||||||
|
|||||||
@@ -123,11 +123,13 @@ async function submitRecord() {
|
|||||||
const partner = document.getElementById('fPartner')?.value.trim() || '';
|
const partner = document.getElementById('fPartner')?.value.trim() || '';
|
||||||
if (currentCategory === '派单') {
|
if (currentCategory === '派单') {
|
||||||
const rebate = parseFloat(document.getElementById('fRebate').value);
|
const rebate = parseFloat(document.getElementById('fRebate').value);
|
||||||
if (!quantity || !unit_price || !rebate || !boss) { showToast('请填写完整信息'); return; }
|
const partner = document.getElementById('fPartner')?.value.trim() || '';
|
||||||
|
if (!quantity || !unit_price || !rebate || !boss || !partner) { showToast('请填写完整信息(包括负责打单的陪玩)'); return; }
|
||||||
body.quantity = quantity;
|
body.quantity = quantity;
|
||||||
body.unit_price = unit_price;
|
body.unit_price = unit_price;
|
||||||
body.rebate = rebate;
|
body.rebate = rebate;
|
||||||
body.amount = quantity * rebate;
|
body.amount = quantity * rebate;
|
||||||
|
body.partner = partner;
|
||||||
} else {
|
} else {
|
||||||
if (!quantity || !unit_price || !boss) { showToast('请填写完整信息'); return; }
|
if (!quantity || !unit_price || !boss) { showToast('请填写完整信息'); return; }
|
||||||
body.quantity = quantity;
|
body.quantity = quantity;
|
||||||
@@ -135,7 +137,6 @@ async function submitRecord() {
|
|||||||
body.amount = quantity * unit_price;
|
body.amount = quantity * unit_price;
|
||||||
}
|
}
|
||||||
body.boss = boss;
|
body.boss = boss;
|
||||||
body.partner = partner;
|
|
||||||
} else if (currentCategory === '红包收入' || currentCategory === '奶茶') {
|
} else if (currentCategory === '红包收入' || currentCategory === '奶茶') {
|
||||||
const amount = parseFloat(document.getElementById('fAmount').value);
|
const amount = parseFloat(document.getElementById('fAmount').value);
|
||||||
const source = document.getElementById('fSource').value.trim();
|
const source = document.getElementById('fSource').value.trim();
|
||||||
|
|||||||
+1
-1
@@ -214,7 +214,7 @@ async function loadMonthlyDetail(type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(API + '/api/stats/monthly-records?type=' + type + '&year=' + monthlyDetailYear + '&month=' + monthlyDetailMonth, { headers: headers() });
|
const res = await fetch(API + '/api/stats/monthly-records?type=' + type + '&year=' + monthlyDetailYear + '&month=' + monthlyDetailMonth + '&limit=1000', { headers: headers() });
|
||||||
if (!res.ok) return;
|
if (!res.ok) return;
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const color = type === 'income' ? '#27ae60' : '#e74c3c';
|
const color = type === 'income' ? '#27ae60' : '#e74c3c';
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ function queryPagedRecords(userId, year, month, options) {
|
|||||||
// 接单列表
|
// 接单列表
|
||||||
router.get('/orders', (req, res) => {
|
router.get('/orders', (req, res) => {
|
||||||
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
||||||
category: '接单'
|
category: '接单',
|
||||||
|
page: req.query.page,
|
||||||
|
limit: req.query.limit
|
||||||
});
|
});
|
||||||
res.json(result);
|
res.json(result);
|
||||||
});
|
});
|
||||||
@@ -60,7 +62,9 @@ router.get('/orders', (req, res) => {
|
|||||||
router.get('/other-income', (req, res) => {
|
router.get('/other-income', (req, res) => {
|
||||||
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
||||||
type: 'income',
|
type: 'income',
|
||||||
excludeCategories: ['接单', '派单']
|
excludeCategories: ['接单', '派单'],
|
||||||
|
page: req.query.page,
|
||||||
|
limit: req.query.limit
|
||||||
});
|
});
|
||||||
res.json(result);
|
res.json(result);
|
||||||
});
|
});
|
||||||
@@ -69,7 +73,9 @@ router.get('/other-income', (req, res) => {
|
|||||||
router.get('/red-envelope', (req, res) => {
|
router.get('/red-envelope', (req, res) => {
|
||||||
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
||||||
type: 'income',
|
type: 'income',
|
||||||
category: '红包收入'
|
category: '红包收入',
|
||||||
|
page: req.query.page,
|
||||||
|
limit: req.query.limit
|
||||||
});
|
});
|
||||||
res.json(result);
|
res.json(result);
|
||||||
});
|
});
|
||||||
@@ -78,7 +84,9 @@ router.get('/red-envelope', (req, res) => {
|
|||||||
router.get('/milk-tea', (req, res) => {
|
router.get('/milk-tea', (req, res) => {
|
||||||
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
||||||
type: 'income',
|
type: 'income',
|
||||||
category: '奶茶'
|
category: '奶茶',
|
||||||
|
page: req.query.page,
|
||||||
|
limit: req.query.limit
|
||||||
});
|
});
|
||||||
res.json(result);
|
res.json(result);
|
||||||
});
|
});
|
||||||
@@ -86,7 +94,9 @@ router.get('/milk-tea', (req, res) => {
|
|||||||
// 派单列表
|
// 派单列表
|
||||||
router.get('/dispatches', (req, res) => {
|
router.get('/dispatches', (req, res) => {
|
||||||
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
const result = queryPagedRecords(req.user.id, req.query.year, req.query.month, {
|
||||||
category: '派单'
|
category: '派单',
|
||||||
|
page: req.query.page,
|
||||||
|
limit: req.query.limit
|
||||||
});
|
});
|
||||||
res.json(result);
|
res.json(result);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ function getCached(key, fetchFn) {
|
|||||||
const firstKey = statsCache.keys().next().value;
|
const firstKey = statsCache.keys().next().value;
|
||||||
statsCache.delete(firstKey);
|
statsCache.delete(firstKey);
|
||||||
}
|
}
|
||||||
return fetchFn().then(data => {
|
return Promise.resolve(fetchFn()).then(data => {
|
||||||
statsCache.set(key, { data, ts: Date.now() });
|
statsCache.set(key, { data, ts: Date.now() });
|
||||||
return data;
|
return data;
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error('Cache fetch error:', err.message);
|
console.error('Cache fetch error:', err.message);
|
||||||
return fetchFn(); // fallback to direct fetch
|
throw err;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user