diff --git a/admin/src/views/payment-orders/index.vue b/admin/src/views/payment-orders/index.vue index 3e69255..f15a530 100644 --- a/admin/src/views/payment-orders/index.vue +++ b/admin/src/views/payment-orders/index.vue @@ -57,6 +57,14 @@ 比索成本 ₱{{ statistics.totalCostPeso }} +
+ 人民币佣金 + ¥{{ statistics.totalCommissionRmb }} +
+
+ 比索佣金 + ₱{{ statistics.totalCommissionPeso }} +
人民币营利 ¥{{ statistics.profitRmb }} @@ -106,9 +114,9 @@ @@ -346,6 +354,8 @@ const statistics = reactive({ totalPeso: '0.00', totalCostRmb: '0.00', totalCostPeso: '0.00', + totalCommissionRmb: '0.00', + totalCommissionPeso: '0.00', profitRmb: '0.00', profitPeso: '0.00', }) @@ -403,6 +413,8 @@ async function fetchOrders() { statistics.totalPeso = response.data.data.statistics.totalPeso || '0.00' statistics.totalCostRmb = response.data.data.statistics.totalCostRmb || '0.00' statistics.totalCostPeso = response.data.data.statistics.totalCostPeso || '0.00' + statistics.totalCommissionRmb = response.data.data.statistics.totalCommissionRmb || '0.00' + statistics.totalCommissionPeso = response.data.data.statistics.totalCommissionPeso || '0.00' statistics.profitRmb = response.data.data.statistics.profitRmb || '0.00' statistics.profitPeso = response.data.data.statistics.profitPeso || '0.00' } else { @@ -410,6 +422,8 @@ async function fetchOrders() { statistics.totalPeso = '0.00' statistics.totalCostRmb = '0.00' statistics.totalCostPeso = '0.00' + statistics.totalCommissionRmb = '0.00' + statistics.totalCommissionPeso = '0.00' statistics.profitRmb = '0.00' statistics.profitPeso = '0.00' } @@ -622,6 +636,26 @@ async function handleCancel(row) { } } +function calcProfit(row, type) { + let amount = 0, cost = 0, commission = 0 + if (type === 'peso') { + amount = parseFloat(row.amountPeso || 0) + cost = parseFloat(row.costPeso || 0) + if (row.commissions) { + row.commissions.filter(c => c.currency === 'PHP').forEach(c => { commission += parseFloat(c.amount || 0) }) + } + } else if (type === 'rmb') { + amount = parseFloat(row.amountRmb || 0) + cost = parseFloat(row.costRmb || 0) + if (row.commissions) { + row.commissions.filter(c => c.currency !== 'PHP').forEach(c => { commission += parseFloat(c.amount || 0) }) + } + } else { + amount = parseFloat(row.amount || 0) + } + return (amount - cost - commission).toFixed(2) +} + function formatDate(date) { if (!date) return '-' return new Date(date).toLocaleString('zh-CN') @@ -675,6 +709,10 @@ onMounted(() => { color: #f56c6c; } + &.commission { + color: #e6a23c; + } + &.profit { color: #67c23a; } diff --git a/backend/src/services/commissionService.js b/backend/src/services/commissionService.js index 83890ec..b83e008 100644 --- a/backend/src/services/commissionService.js +++ b/backend/src/services/commissionService.js @@ -398,11 +398,11 @@ const getAllCommissions = async (options = {}) => { if (currency === 'PHP') { costAmount = parseFloat(po.costPeso || 0); const payAmt = parseFloat(po.amountPeso || 0); - profitAmount = payAmt - costAmount; + profitAmount = payAmt - costAmount - parseFloat(commission.commissionAmount || 0); } else { costAmount = parseFloat(po.costRmb || 0); const payAmt = parseFloat(po.amountRmb || 0) || parseFloat(po.amount || 0); - profitAmount = payAmt - costAmount; + profitAmount = payAmt - costAmount - parseFloat(commission.commissionAmount || 0); } } diff --git a/backend/src/services/paymentOrderService.js b/backend/src/services/paymentOrderService.js index 71e4dd1..fd384ce 100644 --- a/backend/src/services/paymentOrderService.js +++ b/backend/src/services/paymentOrderService.js @@ -250,6 +250,39 @@ const getPaymentOrders = async (options = {}) => { const { count, rows } = ordersResult; + // Get all commissions for active orders to calculate total commission amounts + const Commission = require('../models/Commission'); + const Op2 = require('sequelize').Op; + + // Query total commissions for active orders (for statistics) + const activeOrderIds = await PaymentOrder.findAll({ + where: { ...where, status: 'active' }, + attributes: ['id'], + raw: true, + }); + const activeIds = activeOrderIds.map(o => o.id); + + let totalCommissionRmb = 0; + let totalCommissionPeso = 0; + if (activeIds.length > 0) { + const commissionStats = await Commission.findAll({ + where: { + paymentOrderId: activeIds, + status: 'credited', + }, + attributes: ['currency', [sequelize.fn('SUM', sequelize.col('commission_amount')), 'total']], + group: ['currency'], + raw: true, + }); + commissionStats.forEach(cs => { + if (cs.currency === 'PHP') { + totalCommissionPeso = parseFloat(cs.total || 0); + } else { + totalCommissionRmb = parseFloat(cs.total || 0); + } + }); + } + // Format statistics with two decimal places const totalRmb = parseFloat(statisticsResult?.totalRmb || 0); const totalPeso = parseFloat(statisticsResult?.totalPeso || 0); @@ -261,12 +294,13 @@ const getPaymentOrders = async (options = {}) => { totalPeso: totalPeso.toFixed(2), totalCostRmb: totalCostRmb.toFixed(2), totalCostPeso: totalCostPeso.toFixed(2), - profitRmb: (totalRmb - totalCostRmb).toFixed(2), - profitPeso: (totalPeso - totalCostPeso).toFixed(2), + totalCommissionRmb: totalCommissionRmb.toFixed(2), + totalCommissionPeso: totalCommissionPeso.toFixed(2), + profitRmb: (totalRmb - totalCostRmb - totalCommissionRmb).toFixed(2), + profitPeso: (totalPeso - totalCostPeso - totalCommissionPeso).toFixed(2), }; - // Get all commissions for each order (dual-currency support) - const Commission = require('../models/Commission'); + // Get commissions for current page orders const orderIds = rows.map(o => o.id); const commissions = await Commission.findAll({ where: { paymentOrderId: orderIds },