2026-03-12 11:23:10 +08:00
const express = require ( 'express' );
const db = require ( '../db' );
const { getMonthRange } = require ( '../utils/helpers' );
const router = express . Router ();
// 格式化本地日期为 YYYY-MM-DD
function formatLocalDate ( date ) {
const y = date . getFullYear ();
const m = String ( date . getMonth () + 1 ). padStart ( 2 , '0' );
const d = String ( date . getDate ()). padStart ( 2 , '0' );
return ` ${ y } - ${ m } - ${ d } ` ;
}
// 本月统计
router . get ( '/monthly' , ( req , res ) => {
const { startDate , endDate } = getMonthRange ( req . query . year , req . query . month );
const stats = db . prepare ( `
SELECT
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_order_count,
COALESCE(SUM(CASE WHEN category = '接单' THEN amount ELSE 0 END), 0) as take_order_income,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_order_count,
COALESCE(SUM(CASE WHEN category = '派单' THEN amount ELSE 0 END), 0) as dispatch_order_income,
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_income,
COALESCE(SUM(CASE WHEN category = '红包收入' THEN 1 ELSE 0 END), 0) as redEnvelope_count,
COALESCE(SUM(CASE WHEN category = '奶茶' THEN amount ELSE 0 END), 0) as milkTea_income,
COALESCE(SUM(CASE WHEN category = '奶茶' THEN 1 ELSE 0 END), 0) as milkTea_count,
COALESCE(SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END), 0) as total_income,
COALESCE(SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END), 0) as total_expense
FROM records
WHERE user_id = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , startDate , endDate );
res . json ( stats );
});
// 月收入/支出记录列表
router . get ( '/monthly-records' , ( req , res ) => {
2026-03-18 09:53:48 +08:00
const { type , page = 1 , limit = 20 } = req . query ;
2026-03-12 11:23:10 +08:00
if ( ! type || ! [ 'income' , 'expense' ]. includes ( type )) return res . status ( 400 ). json ({ error : '缺少类型参数' });
const { startDate , endDate } = getMonthRange ( req . query . year , req . query . month );
2026-03-18 09:53:48 +08:00
const offset = ( Number ( page ) - 1 ) * Number ( limit );
2026-03-12 11:23:10 +08:00
const summary = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total
FROM records WHERE user_id = ? AND type = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , type , startDate , endDate );
2026-03-18 09:53:48 +08:00
const total = db . prepare ( `
SELECT COUNT(*) as count FROM records
WHERE user_id = ? AND type = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , type , startDate , endDate ). count ;
2026-03-12 11:23:10 +08:00
const records = db . prepare ( `
SELECT * FROM records
WHERE user_id = ? AND type = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
2026-03-18 09:53:48 +08:00
ORDER BY created_at DESC LIMIT ? OFFSET ?
` ). all ( req . user . id , type , startDate , endDate , Number ( limit ), offset );
2026-03-12 11:23:10 +08:00
2026-03-18 09:53:48 +08:00
res . json ({ total : summary . total , records , page : Number ( page ), limit : Number ( limit ), totalCount : total });
2026-03-12 11:23:10 +08:00
});
// 年度净收入按年统计
router . get ( '/yearly-net-income' , ( req , res ) => {
// 获取所有年份数据
const yearlyStats = db . prepare ( `
SELECT
strftime('%Y', created_at) as year,
COALESCE(SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END), 0) as total_income,
COALESCE(SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END), 0) as total_expense
FROM records
WHERE user_id = ?
GROUP BY year ORDER BY year DESC
` ). all ( req . user . id );
// 获取所有年份的每月数据
const monthlyByYear = db . prepare ( `
SELECT
strftime('%Y', created_at) as year,
strftime('%m', created_at) as month,
COALESCE(SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END), 0) as total_income,
COALESCE(SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END), 0) as total_expense
FROM records
WHERE user_id = ?
GROUP BY year, month ORDER BY year DESC, month
` ). all ( req . user . id );
// 按年份分组每月数据
const monthlyData = {};
monthlyByYear . forEach ( m => {
if ( ! monthlyData [ m . year ]) monthlyData [ m . year ] = [];
monthlyData [ m . year ]. push ({
month : m . month ,
total_income : m . total_income ,
total_expense : m . total_expense
});
});
const grandTotal = db . prepare ( `
SELECT
COALESCE(SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END), 0) as total_income,
COALESCE(SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END), 0) as total_expense
FROM records WHERE user_id = ?
` ). get ( req . user . id );
res . json ({ yearlyStats , monthlyData , grandTotal });
});
// 陪玩派单榜预览
router . get ( '/partner-ranking/preview' , ( req , res ) => {
const { startDate , endDate } = getMonthRange ( req . query . year , req . query . month );
const rows = db . prepare ( `
SELECT partner, COALESCE(SUM(quantity), 0) as dispatch_count, COALESCE(SUM(amount), 0) as dispatch_income
FROM records
WHERE user_id = ? AND category = '派单' AND partner IS NOT NULL AND partner != ''
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
GROUP BY partner ORDER BY dispatch_count DESC LIMIT 10
` ). all ( req . user . id , startDate , endDate );
res . json ( rows );
});
// 陪玩派单榜详情
router . get ( '/partner-ranking' , ( req , res ) => {
const { startDate , endDate } = req . query ;
let start , end ;
if ( startDate && endDate ) {
start = startDate ;
end = endDate ;
} else {
const now = new Date ();
const year = now . getFullYear ();
const month = String ( now . getMonth () + 1 ). padStart ( 2 , '0' );
start = ` ${ year } - ${ month } -01` ;
const endMonth = now . getMonth () + 2 > 12 ? 1 : now . getMonth () + 2 ;
const endYear = endMonth === 1 ? year + 1 : year ;
end = ` ${ endYear } - ${ String ( endMonth ). padStart ( 2 , '0' ) } -01` ;
}
const rows = db . prepare ( `
SELECT partner, COALESCE(SUM(quantity), 0) as dispatch_count, COALESCE(SUM(quantity * COALESCE(unit_price, 0)), 0) as dispatch_income, COALESCE(SUM(amount), 0) as rebate_income
FROM records
WHERE user_id = ? AND category = '派单' AND partner IS NOT NULL AND partner != ''
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
GROUP BY partner ORDER BY dispatch_count DESC
` ). all ( req . user . id , start , end );
// 计算每个陪玩的陪玩总收入:(单价-返点)*单数 = 单价*单数 - 返点
rows . forEach ( row => {
row . partner_income = ( row . dispatch_income || 0 ) - ( row . rebate_income || 0 );
});
const summary = db . prepare ( `
SELECT
COALESCE(SUM(quantity), 0) as total_dispatch_count,
COALESCE(SUM(quantity * COALESCE(unit_price, 0)), 0) as total_dispatch_income,
COALESCE(SUM(amount), 0) as total_rebate_income,
COALESCE(SUM(quantity * COALESCE(unit_price, 0)), 0) - COALESCE(SUM(amount), 0) as total_partner_income
FROM records
WHERE user_id = ? AND category = '派单' AND partner IS NOT NULL AND partner != ''
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , start , end );
// 获取奶茶收入
const milkTeaStats = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total_milkTea_income
FROM records
WHERE user_id = ? AND type = 'income' AND category = '奶茶'
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , start , end );
summary . total_milkTea_income = milkTeaStats . total_milkTea_income ;
res . json ({ rows , summary });
});
// 总接单数按老板排行
router . get ( '/take-ranking' , ( req , res ) => {
const rows = db . prepare ( `
SELECT boss as name, COALESCE(SUM(quantity), 0) as count, COALESCE(SUM(amount), 0) as income
FROM records WHERE user_id = ? AND category = '接单' AND boss IS NOT NULL AND boss != ''
GROUP BY boss ORDER BY count DESC
` ). all ( req . user . id );
// 获取接单总收入和红包收入
const stats = db . prepare ( `
SELECT
COALESCE(SUM(quantity), 0) as total_take_count,
COALESCE(SUM(amount), 0) as total_take_income
FROM records WHERE user_id = ? AND category = '接单'
` ). get ( req . user . id );
const redEnvelopeStats = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total_redEnvelope_income
FROM records WHERE user_id = ? AND type = 'income' AND category = '红包收入'
` ). get ( req . user . id );
const result = {
rows : rows ,
total_take_count : stats . total_take_count ,
total_take_income : stats . total_take_income ,
total_redEnvelope_income : redEnvelopeStats . total_redEnvelope_income
};
res . json ( result );
});
// 总派单数按陪玩排行
router . get ( '/dispatch-ranking' , ( req , res ) => {
const rows = db . prepare ( `
SELECT
partner as name,
COALESCE(SUM(quantity), 0) as dispatch_count,
COALESCE(SUM(quantity * COALESCE(unit_price, 0)), 0) as dispatch_income,
COALESCE(SUM(amount), 0) as rebate_income
FROM records WHERE user_id = ? AND category = '派单' AND partner IS NOT NULL AND partner != ''
GROUP BY partner ORDER BY dispatch_count DESC
` ). all ( req . user . id );
// 计算每个陪玩的陪玩总收入:(单价-返点)*单数 = 单价*单数 - 返点
rows . forEach ( row => {
row . partner_income = ( row . dispatch_income || 0 ) - ( row . rebate_income || 0 );
});
// 获取派单总数和奶茶收入
const dispatchTotal = db . prepare ( `
SELECT COALESCE(SUM(quantity), 0) as total_dispatch_count
FROM records WHERE user_id = ? AND category = '派单'
` ). get ( req . user . id );
const milkTeaStats = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total_milkTea_income
FROM records WHERE user_id = ? AND type = 'income' AND category = '奶茶'
` ). get ( req . user . id );
const result = {
rows : rows ,
total_dispatch_count : dispatchTotal . total_dispatch_count ,
total_milkTea_income : milkTeaStats . total_milkTea_income
};
res . json ( result );
});
// 用户总统计
router . get ( '/total' , ( req , res ) => {
const stats = db . prepare ( `
SELECT
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
COALESCE(SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END), 0) as total_income,
COALESCE(SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END), 0) as total_expense
FROM records WHERE user_id = ?
` ). get ( req . user . id );
stats . net_income = stats . total_income - stats . total_expense ;
res . json ( stats );
});
// 老板交易记录
router . get ( '/boss-records' , ( req , res ) => {
const boss = req . query . boss ;
2026-03-19 10:13:02 +08:00
const { page = 1 , limit = 20 , year , month } = req . query ;
2026-03-12 11:23:10 +08:00
if ( ! boss ) return res . status ( 400 ). json ({ error : '缺少老板参数' });
2026-03-18 09:53:48 +08:00
const offset = ( Number ( page ) - 1 ) * Number ( limit );
2026-03-12 11:23:10 +08:00
2026-03-19 10:13:02 +08:00
// 日期过滤条件
let dateFilter = '' ;
let dateParams = [];
if ( year && month ) {
const startDate = ` ${ year } - ${ String ( month ). padStart ( 2 , '0' ) } -01` ;
const endDate = ` ${ year } - ${ String ( month ). padStart ( 2 , '0' ) } -31` ;
dateFilter = ` AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') <= ?` ;
dateParams = [ startDate , endDate ];
}
2026-03-12 11:23:10 +08:00
const myIncomeSummary = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total
2026-03-19 10:13:02 +08:00
FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? AND type = 'income' ${ dateFilter }
` ). get ( req . user . id , boss , ... dateParams );
2026-03-12 11:23:10 +08:00
const expenseSummary = db . prepare ( `
SELECT
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity * COALESCE(unit_price, 0) ELSE 0 END), 0) as dispatch_expense,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity * COALESCE(unit_price, 0) ELSE 0 END), 0) as order_expense,
2026-03-19 10:13:02 +08:00
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_expense,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count
FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? ${ dateFilter }
` ). get ( req . user . id , boss , ... dateParams );
2026-03-12 11:23:10 +08:00
const boss_total_expense = expenseSummary . dispatch_expense + expenseSummary . order_expense + expenseSummary . redEnvelope_expense ;
2026-03-18 09:53:48 +08:00
const total = db . prepare ( `
2026-03-19 10:13:02 +08:00
SELECT COUNT(*) as count FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? ${ dateFilter }
` ). get ( req . user . id , boss , ... dateParams ). count ;
2026-03-18 09:53:48 +08:00
2026-03-12 11:23:10 +08:00
const records = db . prepare ( `
2026-03-19 10:13:02 +08:00
SELECT * FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? ${ dateFilter } ORDER BY created_at DESC LIMIT ? OFFSET ?
` ). all ( req . user . id , boss , ... dateParams , Number ( limit ), offset );
2026-03-12 11:23:10 +08:00
res . json ({
my_income : myIncomeSummary . total ,
boss_total_expense : boss_total_expense ,
2026-03-19 10:13:02 +08:00
take_count : expenseSummary . take_count ,
dispatch_count : expenseSummary . dispatch_count ,
2026-03-18 09:53:48 +08:00
records ,
page : Number ( page ),
limit : Number ( limit ),
totalCount : total
2026-03-12 11:23:10 +08:00
});
});
// 陪玩交易记录
router . get ( '/partner-records' , ( req , res ) => {
const partner = req . query . partner ;
2026-03-19 10:13:02 +08:00
const { page = 1 , limit = 20 , year , month } = req . query ;
2026-03-12 11:23:10 +08:00
if ( ! partner ) return res . status ( 400 ). json ({ error : '缺少陪玩参数' });
2026-03-18 09:53:48 +08:00
const offset = ( Number ( page ) - 1 ) * Number ( limit );
2026-03-12 11:23:10 +08:00
2026-03-19 10:13:02 +08:00
// 日期过滤条件
let dateFilter = '' ;
let dateParams = [];
if ( year && month ) {
const startDate = ` ${ year } - ${ String ( month ). padStart ( 2 , '0' ) } -01` ;
const endDate = ` ${ year } - ${ String ( month ). padStart ( 2 , '0' ) } -31` ;
dateFilter = ` AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') <= ?` ;
dateParams = [ startDate , endDate ];
}
2026-03-12 11:23:10 +08:00
const dispatchStats = db . prepare ( `
SELECT
COALESCE(SUM(quantity), 0) as dispatch_count,
COALESCE(SUM(quantity * (COALESCE(unit_price, 0) - COALESCE(rebate, amount * 1.0 / CASE WHEN quantity > 0 THEN quantity ELSE 1 END))), 0) as spread_income,
COALESCE(SUM(amount), 0) as rebate_income
2026-03-19 10:13:02 +08:00
FROM records WHERE user_id = ? AND category = '派单' AND partner = ? ${ dateFilter }
` ). get ( req . user . id , partner , ... dateParams );
2026-03-12 11:23:10 +08:00
const otherIncome = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total
2026-03-19 10:13:02 +08:00
FROM records WHERE user_id = ? AND type = 'income' AND category != '派单' AND category != '接单' AND source = ? ${ dateFilter }
` ). get ( req . user . id , partner , ... dateParams );
2026-03-12 11:23:10 +08:00
2026-03-18 09:53:48 +08:00
const total = db . prepare ( `
SELECT COUNT(*) as count FROM records
WHERE user_id = ? AND (
(category = '派单' AND partner = ?) OR
(type = 'income' AND category != '派单' AND category != '接单' AND source = ?)
2026-03-19 10:13:02 +08:00
) ${ dateFilter }
` ). get ( req . user . id , partner , partner , ... dateParams ). count ;
2026-03-18 09:53:48 +08:00
2026-03-12 11:23:10 +08:00
const records = db . prepare ( `
SELECT * FROM records
WHERE user_id = ? AND (
(category = '派单' AND partner = ?) OR
(type = 'income' AND category != '派单' AND category != '接单' AND source = ?)
2026-03-19 10:13:02 +08:00
) ${ dateFilter } ORDER BY created_at DESC LIMIT ? OFFSET ?
` ). all ( req . user . id , partner , partner , ... dateParams , Number ( limit ), offset );
2026-03-12 11:23:10 +08:00
res . json ({
dispatch_count : dispatchStats . dispatch_count ,
spread_income : dispatchStats . spread_income ,
rebate_income : dispatchStats . rebate_income ,
other_income : otherIncome . total ,
2026-03-18 09:53:48 +08:00
records ,
page : Number ( page ),
limit : Number ( limit ),
totalCount : total
2026-03-12 11:23:10 +08:00
});
});
// 最近7天每日收入
router . get ( '/daily-income' , ( req , res ) => {
const today = new Date ();
const days = [];
for ( let i = 6 ; i >= 0 ; i -- ) {
const d = new Date ( today );
d . setDate ( d . getDate () - i );
days . push ( formatLocalDate ( d ));
}
const startDate = days [ 0 ];
const endDay = new Date ( today );
endDay . setDate ( endDay . getDate () + 1 );
const endDate = formatLocalDate ( endDay );
const rows = db . prepare ( `
SELECT DATE(created_at, 'localtime') as date, COALESCE(SUM(amount), 0) as income
FROM records WHERE user_id = ? AND type = 'income' AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
GROUP BY DATE(created_at, 'localtime')
` ). all ( req . user . id , startDate , endDate );
const map = {};
rows . forEach ( r => { map [ r . date ] = r . income ; });
res . json ( days . map ( d => ({ date : d , income : map [ d ] || 0 })));
});
// 某天收入记录详情
router . get ( '/daily-detail' , ( req , res ) => {
2026-03-18 09:53:48 +08:00
const { date , page = 1 , limit = 20 } = req . query ;
2026-03-12 11:23:10 +08:00
if ( ! date ) return res . status ( 400 ). json ({ error : '缺少日期参数' });
2026-03-18 09:53:48 +08:00
const offset = ( Number ( page ) - 1 ) * Number ( limit );
2026-03-12 11:23:10 +08:00
const nextDay = new Date ( date );
nextDay . setDate ( nextDay . getDate () + 1 );
const endDate = formatLocalDate ( nextDay );
const summary = db . prepare ( `
SELECT COALESCE(SUM(amount), 0) as total_income
FROM records WHERE user_id = ? AND type = 'income' AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , date , endDate );
2026-03-18 09:53:48 +08:00
const total = db . prepare ( `
SELECT COUNT(*) as count FROM records WHERE user_id = ? AND type = 'income' AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
` ). get ( req . user . id , date , endDate ). count ;
2026-03-12 11:23:10 +08:00
const records = db . prepare ( `
SELECT * FROM records WHERE user_id = ? AND type = 'income' AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
2026-03-18 09:53:48 +08:00
ORDER BY created_at DESC LIMIT ? OFFSET ?
` ). all ( req . user . id , date , endDate , Number ( limit ), offset );
2026-03-12 11:23:10 +08:00
2026-03-18 09:53:48 +08:00
res . json ({ total_income : summary . total_income , records , page : Number ( page ), limit : Number ( limit ), totalCount : total });
2026-03-12 11:23:10 +08:00
});
// 老板收入排行 - 首页预览
router . get ( '/boss-ranking/preview' , ( req , res ) => {
const { startDate , endDate } = getMonthRange ( req . query . year , req . query . month );
const rows = db . prepare ( `
SELECT COALESCE(boss, source) as boss, SUM(amount) as total_income,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_income
FROM records
WHERE user_id = ? AND type = 'income' AND (boss IS NOT NULL AND boss != '' OR source IS NOT NULL AND source != '')
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
GROUP BY COALESCE(boss, source) ORDER BY total_income DESC LIMIT 10
` ). all ( req . user . id , startDate , endDate );
res . json ( rows );
});
// 老板收入排行 - 详情页(支持筛选)
router . get ( '/boss-ranking' , ( req , res ) => {
const { startDate , endDate , sortBy = 'total_income' } = req . query ;
let start , end ;
if ( startDate && endDate ) {
start = startDate ;
end = endDate ;
} else {
const now = new Date ();
const year = now . getFullYear ();
const month = String ( now . getMonth () + 1 ). padStart ( 2 , '0' );
start = ` ${ year } - ${ month } -01` ;
const endMonth = now . getMonth () + 2 > 12 ? 1 : now . getMonth () + 2 ;
const endYear = endMonth === 1 ? year + 1 : year ;
end = ` ${ endYear } - ${ String ( endMonth ). padStart ( 2 , '0' ) } -01` ;
}
const allowedSorts = [ 'total_income' , 'take_count' , 'dispatch_count' ];
const orderCol = allowedSorts . includes ( sortBy ) ? sortBy : 'total_income' ;
if ( sortBy === 'dispatch_count' ) {
const rows = db . prepare ( `
SELECT COALESCE(boss, source) as boss,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
COALESCE(SUM(CASE WHEN category = '派单' THEN amount ELSE 0 END), 0) as dispatch_income,
SUM(amount) as total_income,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count,
COALESCE(SUM(CASE WHEN category = '接单' THEN amount ELSE 0 END), 0) as take_income,
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_income
FROM records
WHERE user_id = ? AND type = 'income' AND (boss IS NOT NULL AND boss != '' OR source IS NOT NULL AND source != '')
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
GROUP BY COALESCE(boss, source) ORDER BY dispatch_count DESC
` ). all ( req . user . id , start , end );
return res . json ( rows . filter ( r => r . dispatch_count > 0 ));
}
const rows = db . prepare ( `
SELECT COALESCE(boss, source) as boss, SUM(amount) as total_income,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count,
COALESCE(SUM(CASE WHEN category = '接单' THEN amount ELSE 0 END), 0) as take_income,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
COALESCE(SUM(CASE WHEN category = '派单' THEN amount ELSE 0 END), 0) as dispatch_income,
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_income
FROM records
WHERE user_id = ? AND type = 'income' AND (boss IS NOT NULL AND boss != '' OR source IS NOT NULL AND source != '')
AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
GROUP BY COALESCE(boss, source) ORDER BY ${ orderCol } DESC
` ). all ( req . user . id , start , end );
if ( sortBy === 'take_count' ) {
return res . json ( rows . filter ( r => r . take_count > 0 ));
}
res . json ( rows );
});
module . exports = router ;