提交
This commit is contained in:
@@ -12,6 +12,48 @@ const dayjs = require('dayjs');
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
// router.get('/tmp', async (req, res) => {
|
||||
// const db = getDB();
|
||||
// // 1. 查询所有转账记录,按 id 升序
|
||||
// let [transfers] = await db.execute(`
|
||||
// SELECT *
|
||||
// FROM transfers
|
||||
// WHERE status='received' or status='confirmed'
|
||||
// ORDER BY id ASC`);
|
||||
//
|
||||
// // 2. 用对象维护每个用户的最新余额
|
||||
// const userBalances = {};
|
||||
//
|
||||
// // 3. 遍历每条转账记录,计算余额
|
||||
// for (const trx of transfers) {
|
||||
// const fromId = trx.from_user_id;
|
||||
// const toId = trx.to_user_id;
|
||||
// const amount = Number(trx.amount);
|
||||
//
|
||||
// if (!(fromId in userBalances)) userBalances[fromId] = 0;
|
||||
// if (!(toId in userBalances)) userBalances[toId] = 0;
|
||||
//
|
||||
// const fromBalance = userBalances[fromId] - amount;
|
||||
// const toBalance = userBalances[toId] + amount;
|
||||
//
|
||||
// userBalances[fromId] = fromBalance;
|
||||
// userBalances[toId] = toBalance;
|
||||
//
|
||||
// const balanceDiff = toBalance - fromBalance;
|
||||
//
|
||||
// // 4. 更新当前行的字段
|
||||
// await db.execute(
|
||||
// `UPDATE transfers
|
||||
// SET from_user_balance = ?,
|
||||
// to_user_balance = ?,
|
||||
// balance_diff = ?
|
||||
// WHERE id = ?`,
|
||||
// [fromBalance, toBalance, amount, trx.id]
|
||||
// );
|
||||
//
|
||||
// }
|
||||
// res.json('更新成功')
|
||||
// })
|
||||
router.get('/',
|
||||
authenticateToken,
|
||||
validateQuery(transferSchemas.query),
|
||||
@@ -342,7 +384,6 @@ router.post('/confirm-not-received',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 获取用户转账记录
|
||||
router.get('/user/:userId', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
@@ -386,8 +427,9 @@ router.get('/user/:userId', authenticateToken, async (req, res) => {
|
||||
LEFT JOIN users to_user ON t.to_user_id = to_user.id
|
||||
${whereClause}
|
||||
ORDER BY t.created_at
|
||||
DESC
|
||||
LIMIT ${limitNum} OFFSET ${offset}
|
||||
DESC
|
||||
LIMIT ${limitNum}
|
||||
OFFSET ${offset}
|
||||
`, countParams);
|
||||
|
||||
const [countResult] = await db.execute(`
|
||||
@@ -425,37 +467,37 @@ router.get('/stats', authenticateToken, async (req, res) => {
|
||||
if (isAdmin) {
|
||||
// 管理员可以查看全局统计
|
||||
const [totalStats] = await db.execute(`
|
||||
SELECT COUNT(*) as total_transfers,
|
||||
SUM(amount) as total_flow_amount,
|
||||
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_count,
|
||||
SUM(CASE WHEN status = 'confirmed' THEN 1 ELSE 0 END) as confirmed_count,
|
||||
SUM(CASE WHEN status = 'received' THEN 1 ELSE 0 END) as received_count,
|
||||
SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected_count,
|
||||
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_count,
|
||||
SUM(CASE WHEN status = 'not_received' THEN 1 ELSE 0 END) as not_received_count,
|
||||
SUM(CASE WHEN is_overdue = 1 THEN 1 ELSE 0 END) as overdue_count,
|
||||
SUM(CASE WHEN is_bad_debt = 1 THEN 1 ELSE 0 END) as bad_debt_count,
|
||||
SUM(CASE WHEN status = 'confirmed' THEN amount ELSE 0 END) as total_amount,
|
||||
SUM(CASE WHEN is_bad_debt = 1 THEN amount ELSE 0 END) as bad_debt_amount,
|
||||
SELECT COUNT(*) as total_transfers,
|
||||
SUM(amount) as total_flow_amount,
|
||||
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_count,
|
||||
SUM(CASE WHEN status = 'confirmed' THEN 1 ELSE 0 END) as confirmed_count,
|
||||
SUM(CASE WHEN status = 'received' THEN 1 ELSE 0 END) as received_count,
|
||||
SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected_count,
|
||||
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_count,
|
||||
SUM(CASE WHEN status = 'not_received' THEN 1 ELSE 0 END) as not_received_count,
|
||||
SUM(CASE WHEN is_overdue = 1 THEN 1 ELSE 0 END) as overdue_count,
|
||||
SUM(CASE WHEN is_bad_debt = 1 THEN 1 ELSE 0 END) as bad_debt_count,
|
||||
SUM(CASE WHEN status = 'confirmed' THEN amount ELSE 0 END) as total_amount,
|
||||
SUM(CASE WHEN is_bad_debt = 1 THEN amount ELSE 0 END) as bad_debt_amount,
|
||||
SUM(CASE
|
||||
WHEN transfer_type = 'initial' AND status = 'confirmed' THEN amount
|
||||
ELSE 0 END) as initial_amount,
|
||||
ELSE 0 END) as initial_amount,
|
||||
SUM(CASE
|
||||
WHEN transfer_type = 'return' AND status = 'confirmed' THEN amount
|
||||
ELSE 0 END) as return_amount,
|
||||
ELSE 0 END) as return_amount,
|
||||
SUM(CASE
|
||||
WHEN transfer_type = 'user_to_user' AND status = 'confirmed' THEN amount
|
||||
ELSE 0 END) as user_to_user_amount,
|
||||
ELSE 0 END) as user_to_user_amount,
|
||||
(SELECT SUM(balance)
|
||||
FROM users
|
||||
WHERE role = 'user'
|
||||
AND is_system_account = 1) as total_merchant_balance,
|
||||
AND is_system_account = 1) as total_merchant_balance,
|
||||
(SELECT SUM(balance)
|
||||
FROM users
|
||||
WHERE role = 'user'
|
||||
AND is_system_account != 1) as total_user_balance,
|
||||
SUM(CASE WHEN source_type IN ('system') THEN amount END) as participated_transfers,
|
||||
SUM(CASE WHEN source_type IN ('agent') THEN amount END) as agent_total,
|
||||
SUM(CASE WHEN source_type IN ('system') THEN amount END) as participated_transfers,
|
||||
SUM(CASE WHEN source_type IN ('agent') THEN amount END) as agent_total,
|
||||
SUM(CASE WHEN source_type IN ('operated_agent') THEN amount END) as operated_agent_total
|
||||
FROM transfers
|
||||
`);
|
||||
@@ -470,26 +512,26 @@ router.get('/stats', authenticateToken, async (req, res) => {
|
||||
(
|
||||
COALESCE((SELECT SUM(amount)
|
||||
FROM transfers
|
||||
WHERE DATE(created_at) = ?
|
||||
AND to_user_id IN (SELECT id FROM users WHERE is_system_account = 1)
|
||||
AND status = 'received'), 0) -
|
||||
WHERE DATE (created_at) = ?
|
||||
AND to_user_id IN (SELECT id FROM users WHERE is_system_account = 1)
|
||||
AND status = 'received'), 0) -
|
||||
COALESCE((SELECT SUM(amount)
|
||||
FROM transfers
|
||||
WHERE DATE(created_at) = ?
|
||||
AND from_user_id IN (SELECT id FROM users WHERE is_system_account = 1)
|
||||
AND status = 'received'), 0)
|
||||
WHERE DATE (created_at) = ?
|
||||
AND from_user_id IN (SELECT id FROM users WHERE is_system_account = 1)
|
||||
AND status = 'received'), 0)
|
||||
) as today_amount
|
||||
FROM transfers
|
||||
WHERE DATE(created_at) = ?
|
||||
WHERE DATE (created_at) = ?
|
||||
`, [todayStr, todayStr, todayStr]);
|
||||
|
||||
const [monthlyStats] = await db.execute(`
|
||||
SELECT COUNT(*) as monthly_transfers,
|
||||
SUM(CASE WHEN status = 'received' THEN amount ELSE 0 END) as monthly_amount,
|
||||
SUM(CASE WHEN source_type IN ('system') THEN amount END) as monthly_participated_transfers
|
||||
SELECT COUNT(*) as monthly_transfers,
|
||||
SUM(CASE WHEN status = 'received' THEN amount ELSE 0 END) as monthly_amount,
|
||||
SUM(CASE WHEN source_type IN ('system') THEN amount END) as monthly_participated_transfers
|
||||
FROM transfers
|
||||
WHERE YEAR(created_at) = ?
|
||||
AND MONTH(created_at) = ?
|
||||
WHERE YEAR (created_at) = ?
|
||||
AND MONTH (created_at) = ?
|
||||
`, [currentYear, currentMonth]);
|
||||
|
||||
// 获取上月统计数据用于对比
|
||||
@@ -497,12 +539,12 @@ router.get('/stats', authenticateToken, async (req, res) => {
|
||||
const lastMonthYear = currentMonth === 1 ? currentYear - 1 : currentYear;
|
||||
|
||||
const [lastMonthStats] = await db.execute(`
|
||||
SELECT COUNT(*) as last_monthly_transfers,
|
||||
SUM(CASE WHEN status = 'confirmed' THEN amount ELSE 0 END) as last_monthly_amount,
|
||||
SUM(CASE WHEN source_type IN ('system') THEN amount END) as last_monthly_participated_transfers
|
||||
SELECT COUNT(*) as last_monthly_transfers,
|
||||
SUM(CASE WHEN status = 'confirmed' THEN amount ELSE 0 END) as last_monthly_amount,
|
||||
SUM(CASE WHEN source_type IN ('system') THEN amount END) as last_monthly_participated_transfers
|
||||
FROM transfers
|
||||
WHERE YEAR(created_at) = ?
|
||||
AND MONTH(created_at) = ?
|
||||
WHERE YEAR (created_at) = ?
|
||||
AND MONTH (created_at) = ?
|
||||
`, [lastMonthYear, lastMonth]);
|
||||
|
||||
stats = {
|
||||
@@ -524,9 +566,9 @@ router.get('/stats', authenticateToken, async (req, res) => {
|
||||
return_amount: parseFloat(totalStats[0].return_amount || 0),
|
||||
user_to_user_amount: parseFloat(totalStats[0].user_to_user_amount || 0),
|
||||
participated_transfers: totalStats[0].participated_transfers || 0,
|
||||
total_user_balance:totalStats[0].total_user_balance || 0,
|
||||
agent_total:totalStats[0].agent_total || 0,//代理收入
|
||||
operated_agent_total:totalStats[0].operated_agent_total || 0,//直营代理收入
|
||||
total_user_balance: totalStats[0].total_user_balance || 0,
|
||||
agent_total: totalStats[0].agent_total || 0,//代理收入
|
||||
operated_agent_total: totalStats[0].operated_agent_total || 0,//直营代理收入
|
||||
},
|
||||
today: {
|
||||
transfers: todayStats[0].today_transfers || 0,
|
||||
@@ -565,7 +607,7 @@ router.get('/stats', authenticateToken, async (req, res) => {
|
||||
SUM(CASE WHEN status = 'confirmed' AND to_user_id = ? THEN amount ELSE 0 END) as today_received
|
||||
FROM transfers
|
||||
WHERE (from_user_id = ? OR to_user_id = ?)
|
||||
AND DATE(created_at) = ?
|
||||
AND DATE (created_at) = ?
|
||||
`, [userId, userId, userId, userId, todayStr]);
|
||||
|
||||
stats = {
|
||||
@@ -706,9 +748,9 @@ router.get('/trend', authenticateToken, async (req, res) => {
|
||||
|
||||
// 首先获取数据库中最早和最晚的转账日期
|
||||
const [dateRange] = await db.execute(`
|
||||
SELECT MIN(DATE(created_at)) as min_date,
|
||||
MAX(DATE(created_at)) as max_date,
|
||||
COUNT(*) as total_count
|
||||
SELECT MIN(DATE (created_at)) as min_date,
|
||||
MAX(DATE (created_at)) as max_date,
|
||||
COUNT(*) as total_count
|
||||
FROM transfers
|
||||
`);
|
||||
|
||||
@@ -737,13 +779,13 @@ router.get('/trend', authenticateToken, async (req, res) => {
|
||||
|
||||
// 获取指定天数内的转账趋势(从最大日期往前推)
|
||||
const [trendData] = await db.execute(`
|
||||
SELECT DATE(created_at) as date,
|
||||
COUNT(*) as count,
|
||||
SUM(amount) as amount
|
||||
SELECT DATE (created_at) as date, COUNT (*) as count, SUM (amount) as amount
|
||||
FROM transfers
|
||||
WHERE DATE(created_at) >= DATE_SUB(?, INTERVAL ? DAY)
|
||||
AND status IN ('confirmed', 'received')
|
||||
GROUP BY DATE(created_at)
|
||||
WHERE DATE (created_at) >= DATE_SUB(?
|
||||
, INTERVAL ? DAY)
|
||||
AND status IN ('confirmed'
|
||||
, 'received')
|
||||
GROUP BY DATE (created_at)
|
||||
ORDER BY date ASC
|
||||
`, [dateRange[0].max_date, daysNum - 1]);
|
||||
|
||||
@@ -1024,7 +1066,8 @@ router.get('/pending-allocations',
|
||||
JOIN matching_orders mo ON oa.id = mo.id
|
||||
${whereClause}
|
||||
ORDER BY oa.${sortField} ${sortOrder}
|
||||
LIMIT ${parseInt(limit)} OFFSET ${parseInt(offset)}
|
||||
LIMIT ${parseInt(limit)}
|
||||
OFFSET ${parseInt(offset)}
|
||||
`;
|
||||
|
||||
const [allocations] = queryParams.length > 0
|
||||
@@ -1140,19 +1183,16 @@ router.get('/daily-stats',
|
||||
|
||||
// 获取所有用户的昨日转出和今日入账统计
|
||||
let [userStats] = await db.execute(`
|
||||
SELECT u.id as user_id,
|
||||
SELECT u.id as user_id,
|
||||
u.username,
|
||||
u.real_name,
|
||||
u.phone,
|
||||
u.balance,
|
||||
COALESCE(yesterday_out.amount, 0) as yesterday_out_amount,
|
||||
COALESCE(today_in.amount, 0) as today_in_amount,
|
||||
COALESCE(confirmed_from.confirmed_amount, 0) as confirmed_from_amount,
|
||||
CASE
|
||||
WHEN (COALESCE(u.balance, 0) + COALESCE(confirmed_from.confirmed_amount, 0)) > ABS(u.balance)
|
||||
THEN ABS(u.balance)
|
||||
ELSE (COALESCE(u.balance, 0) + COALESCE(confirmed_from.confirmed_amount, 0))
|
||||
END as balance_needed
|
||||
COALESCE(yesterday_out.amount, 0) -
|
||||
COALESCE(yesterday_system_num.amount, 0) as yesterday_out_amount,
|
||||
COALESCE(today_in.amount, 0) as today_in_amount,
|
||||
COALESCE(confirmed_from.confirmed_amount, 0) as confirmed_from_amount,
|
||||
COALESCE(u.balance, 0) + COALESCE(confirmed_from.confirmed_amount, 0) as balance_needed
|
||||
FROM users u
|
||||
LEFT JOIN (SELECT from_user_id,
|
||||
SUM(amount) as amount
|
||||
@@ -1161,6 +1201,15 @@ router.get('/daily-stats',
|
||||
AND created_at <= ?
|
||||
AND status IN ('confirmed', 'received')
|
||||
GROUP BY from_user_id) yesterday_out ON u.id = yesterday_out.from_user_id
|
||||
LEFT JOIN (SELECT to_user_id,
|
||||
SUM(amount) as amount
|
||||
FROM transfers
|
||||
WHERE created_at >= ?
|
||||
AND created_at <= ?
|
||||
AND transfer_type != 'user_to_user'
|
||||
AND status IN ('received')
|
||||
GROUP BY to_user_id) yesterday_system_num
|
||||
ON u.id = yesterday_system_num.to_user_id
|
||||
LEFT JOIN (SELECT to_user_id,
|
||||
SUM(amount) as amount
|
||||
FROM transfers
|
||||
@@ -1171,17 +1220,17 @@ router.get('/daily-stats',
|
||||
left join (select from_user_id,
|
||||
sum(amount) as confirmed_amount
|
||||
from transfers
|
||||
where status = 'received'
|
||||
and created_at >= ?
|
||||
and created_at <= ?
|
||||
group by from_user_id) as confirmed_from on u.id = confirmed_from.from_user_id
|
||||
WHERE u.role != 'admin'
|
||||
WHERE status IN ('confirmed', 'received')
|
||||
AND created_at >= ?
|
||||
AND created_at <= ?
|
||||
GROUP BY from_user_id) as confirmed_from on u.id = confirmed_from.from_user_id
|
||||
WHERE u.role != 'admin' AND u.user_type !='directly_operated'
|
||||
AND u.is_system_account != 1
|
||||
AND yesterday_out.amount > 0
|
||||
AND u.balance < 0
|
||||
ORDER BY balance_needed DESC, yesterday_out_amount DESC
|
||||
`, [yesterdayStartStr, yesterdayEndStr, todayStartStr, todayEndStr, todayStartStr, todayEndStr]);
|
||||
// userStats = userStats.filter(item=>item.balance_needed >= 100)
|
||||
`, [yesterdayStartStr, yesterdayEndStr, yesterdayStartStr, yesterdayEndStr,todayStartStr, todayEndStr, todayStartStr, todayEndStr]);
|
||||
// userStats = userStats.filter(item=>item.balance_needed > 100)
|
||||
userStats.forEach(item => {
|
||||
item.balance_needed = Math.abs(item.balance_needed)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user