You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
3.3 KiB
94 lines
3.3 KiB
const express = require('express');
|
|
const router = express.Router();
|
|
|
|
// 优化的活跃客户排名路由
|
|
|
|
// 获取活跃客户排名(按活跃时长)
|
|
router.get('/api/active-customers-ranking', (req, res) => {
|
|
try {
|
|
const { startDate, endDate, page = 1, pageSize = 10 } = req.query;
|
|
const offset = (parseInt(page) - 1) * parseInt(pageSize);
|
|
|
|
// 获取数据库连接池
|
|
const pool = req.app.get('wechatPool');
|
|
if (!pool) {
|
|
return res.json({ success: false, message: '数据库连接失败' });
|
|
}
|
|
|
|
// 构建日期范围
|
|
const now = new Date();
|
|
const defaultEndStr = now.toISOString().slice(0, 19).replace('T', ' ');
|
|
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
const defaultStartStr = sevenDaysAgo.toISOString().slice(0, 19).replace('T', ' ');
|
|
|
|
const startDateStr = startDate ? `${startDate} 00:00:00` : defaultStartStr;
|
|
const endDateStr = endDate ? `${endDate} 23:59:59` : defaultEndStr;
|
|
|
|
// 查询活跃客户排名
|
|
const rankingSql = `
|
|
SELECT
|
|
u.userId,
|
|
u.phoneNumber,
|
|
SUM(ual.active_duration) as totalDuration,
|
|
COUNT(DISTINCT ual.active_date) as activeDays,
|
|
MAX(ual.last_active_time) as lastActiveTime,
|
|
u.created_at as registerTime
|
|
FROM users u
|
|
JOIN user_active_logs ual ON u.userId = ual.user_id
|
|
WHERE ual.active_date BETWEEN DATE(?) AND DATE(?)
|
|
AND u.phoneNumber IS NOT NULL AND u.phoneNumber != ''
|
|
GROUP BY u.userId, u.phoneNumber, u.created_at
|
|
ORDER BY totalDuration DESC, activeDays DESC
|
|
LIMIT ? OFFSET ?
|
|
`;
|
|
|
|
// 查询总数
|
|
const countSql = `
|
|
SELECT COUNT(DISTINCT u.userId) as total
|
|
FROM users u
|
|
JOIN user_active_logs ual ON u.userId = ual.user_id
|
|
WHERE ual.active_date BETWEEN DATE(?) AND DATE(?)
|
|
AND u.phoneNumber IS NOT NULL AND u.phoneNumber != ''
|
|
`;
|
|
|
|
// 执行总数查询
|
|
pool.query(countSql, [startDateStr, endDateStr], (countErr, countResults) => {
|
|
if (countErr) {
|
|
console.error('查询活跃客户总数失败:', countErr);
|
|
return res.json({ success: false, message: '查询失败,请稍后重试' });
|
|
}
|
|
|
|
const total = countResults[0].total;
|
|
|
|
// 执行排名查询
|
|
pool.query(rankingSql, [startDateStr, endDateStr, pageSize, offset], (rankingErr, rankingResults) => {
|
|
if (rankingErr) {
|
|
console.error('查询活跃客户排名失败:', rankingErr);
|
|
return res.json({ success: false, message: '查询失败,请稍后重试' });
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
ranking: rankingResults.map((item, index) => ({
|
|
rank: offset + index + 1,
|
|
userId: item.userId,
|
|
phoneNumber: item.phoneNumber,
|
|
totalDuration: item.totalDuration || 0,
|
|
activeDays: item.activeDays || 0,
|
|
lastActiveTime: item.lastActiveTime,
|
|
registerTime: item.registerTime
|
|
})),
|
|
total,
|
|
page: parseInt(page),
|
|
pageSize: parseInt(pageSize)
|
|
});
|
|
});
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('获取活跃客户排名失败:', error);
|
|
res.json({ success: false, message: '获取活跃客户排名失败,请稍后重试' });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|