feat(list): 订单/通知/组局列表分页,生产 NODE_ENV 切换 production
- 仓储层 getOrders/getOrdersForUser/getActivities/getUserNotifications 支持 LIMIT/OFFSET,新增 countOrders/countOrdersForUser/countActivities/getUserNotificationTotal - 接口支持 page/pageSize/status/keyword/payType/creatorId/category,返回 list/total/hasMore;未传 page 保持旧数组格式,兼容后台与工作台 - 小程序订单/通知/组局三页触底加载,筛选与搜索下推服务端,避免只过滤当前页 - 新增 116 套件/758 用例,全绿;线上实测分页与筛选接口正常
这个提交包含在:
@@ -898,8 +898,25 @@ app.get('/api/notifications', async (req: Request, res: Response) => {
|
||||
Number(req.query.userId || req.headers['x-user-id'] || 0),
|
||||
'查看消息通知'
|
||||
);
|
||||
const list = await repo.getUserNotifications(uid, Number(req.query.limit) || 50);
|
||||
const unread = await repo.getUserUnreadNotificationCount(uid);
|
||||
if (Number(req.query.page) > 0) {
|
||||
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
|
||||
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(req.query.pageSize) || 20)));
|
||||
const total = await repo.getUserNotificationTotal(uid);
|
||||
const list = await repo.getUserNotifications(uid, pageSize, (page - 1) * pageSize);
|
||||
return res.json({
|
||||
code: 20000,
|
||||
data: {
|
||||
list,
|
||||
unread,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
hasMore: (page - 1) * pageSize + list.length < total,
|
||||
},
|
||||
});
|
||||
}
|
||||
const list = await repo.getUserNotifications(uid, Number(req.query.limit) || 50);
|
||||
res.json({ code: 20000, data: { list, unread } });
|
||||
} catch (err: any) {
|
||||
const statusCode = err.status || 400;
|
||||
@@ -952,12 +969,33 @@ app.get('/api/dashboard/todos', async (_req: Request, res: Response) => {
|
||||
});
|
||||
|
||||
// 3. 活动与4位核销码相关接口 (MySQL 持久化)
|
||||
app.get('/api/activities', async (_req: Request, res: Response) => {
|
||||
app.get('/api/activities', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const acts = await repo.getActivities();
|
||||
const filters = {
|
||||
keyword: String(req.query.keyword || '').trim(),
|
||||
payType: String(req.query.payType || '').trim(),
|
||||
creatorId: Number(req.query.creatorId) || 0,
|
||||
category: String(req.query.category || '').trim(),
|
||||
categoryName: String(req.query.categoryName || '').trim(),
|
||||
};
|
||||
const paged = Number(req.query.page) > 0;
|
||||
if (!paged) {
|
||||
const acts = await repo.getActivities(filters);
|
||||
return res.json({ code: 20000, data: acts });
|
||||
}
|
||||
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
|
||||
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(req.query.pageSize) || 20)));
|
||||
const acts = await repo.getActivities({ ...filters, page, pageSize });
|
||||
const total = await repo.countActivities(filters);
|
||||
res.json({
|
||||
code: 20000,
|
||||
data: acts
|
||||
data: {
|
||||
list: acts,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
hasMore: (page - 1) * pageSize + acts.length < total,
|
||||
},
|
||||
});
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ code: 50000, message: err.message });
|
||||
@@ -1458,12 +1496,31 @@ app.put('/api/companions/:id/profile', async (req: Request, res: Response) => {
|
||||
// 5. 订单与仲裁接口 (落盘 MySQL)
|
||||
app.get('/api/orders', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const status = String(req.query.status || '').trim();
|
||||
const paged = Number(req.query.page) > 0;
|
||||
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
|
||||
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(req.query.pageSize) || 20)));
|
||||
const queryOpts = paged ? { page, pageSize, status } : { status };
|
||||
|
||||
// 管理端(服务端签名 admin token)可取全量;普通用户仅能取与自己相关的订单
|
||||
if (isVerifiedAdminRequest(req)) {
|
||||
const orders = await repo.getOrders();
|
||||
const orders = await repo.getOrders(queryOpts);
|
||||
if (!paged) {
|
||||
return res.json({
|
||||
code: 20000,
|
||||
data: orders
|
||||
});
|
||||
}
|
||||
const total = await repo.countOrders({ status });
|
||||
return res.json({
|
||||
code: 20000,
|
||||
data: orders
|
||||
data: {
|
||||
list: orders,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
hasMore: (page - 1) * pageSize + orders.length < total,
|
||||
}
|
||||
});
|
||||
}
|
||||
const uid = resolveSecureUserId(
|
||||
@@ -1471,10 +1528,23 @@ app.get('/api/orders', async (req: Request, res: Response) => {
|
||||
Number(req.query.userId || req.headers['x-user-id'] || 0),
|
||||
'查看订单列表'
|
||||
);
|
||||
const orders = await repo.getOrdersForUser(uid);
|
||||
const orders = await repo.getOrdersForUser(uid, queryOpts);
|
||||
if (!paged) {
|
||||
return res.json({
|
||||
code: 20000,
|
||||
data: orders
|
||||
});
|
||||
}
|
||||
const total = await repo.countOrdersForUser(uid, { status });
|
||||
res.json({
|
||||
code: 20000,
|
||||
data: orders
|
||||
data: {
|
||||
list: orders,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
hasMore: (page - 1) * pageSize + orders.length < total,
|
||||
}
|
||||
});
|
||||
} catch (err: any) {
|
||||
const statusCode = err.status || 500;
|
||||
|
||||
在新工单中引用
屏蔽一个用户