feat: improve application access and money precision

This commit is contained in:
hectorzhao
2026-07-16 17:54:05 +08:00
parent 9d5c507007
commit faa716b8d0
49 changed files with 1699 additions and 489 deletions
+11 -10
View File
@@ -1,5 +1,6 @@
import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { moneyUnitsToFixedYuan } from '../common/money';
import { PrismaService } from '../prisma/prisma.service';
const SHANGHAI_OFFSET_MS = 8 * 60 * 60 * 1000;
@@ -79,7 +80,7 @@ export class ReportsService implements OnModuleInit, OnModuleDestroy {
async exportProfit(query: ReportListQuery) {
const { dimensionType, where } = profitWhere(query);
const items = await this.prisma.dailyProfitReport.findMany({ where, orderBy: [{ reportDate: 'desc' }, { dimensionName: 'asc' }] });
return csvExport(`利润报表-${dimensionType === 'channel' ? '通道' : '企业应用'}`, ['发送日期', '统计维度', '企业', '发送条数', '成功条数', '消费金额()', '成本金额()', '利润()', '利润率(%)', '生成时间'], items.map((item) => [dateKey(item.reportDate), item.dimensionName, item.tenantName ?? '', item.sentUnits, item.successUnits, item.revenueCents, item.costCents, item.profitCents, (item.profitRateBps / 100).toFixed(2), formatCsvDate(item.generatedAt)]));
return csvExport(`利润报表-${dimensionType === 'channel' ? '通道' : '企业应用'}`, ['发送日期', '统计维度', '企业', '发送条数', '成功条数', '消费金额()', '成本金额()', '利润()', '利润率(%)', '生成时间'], items.map((item) => [dateKey(item.reportDate), item.dimensionName, item.tenantName ?? '', item.sentUnits, item.successUnits, moneyUnitsToFixedYuan(item.revenueCents), moneyUnitsToFixedYuan(item.costCents), moneyUnitsToFixedYuan(item.profitCents), (item.profitRateBps / 100).toFixed(2), formatCsvDate(item.generatedAt)]));
}
async exportQuality(query: ReportListQuery) {
@@ -141,11 +142,11 @@ export class ReportsService implements OnModuleInit, OnModuleDestroy {
await tx.$executeRaw(Prisma.sql`
WITH billing AS (
SELECT "messageId", SUM(CASE WHEN "billingStatus" = 'charged' THEN "amountCents" ELSE 0 END)::integer AS revenue
SELECT "messageId", SUM(CASE WHEN "billingStatus" = 'charged' THEN "amountCents" ELSE 0 END)::bigint AS revenue
FROM "SmsBillingRecord"
GROUP BY "messageId"
), costs AS (
SELECT submit."messageRecordId", SUM(submit."costAmountCents")::integer AS cost
SELECT submit."messageRecordId", SUM(submit."costAmountCents")::bigint AS cost
FROM "SmsSubmitRecord" submit
WHERE submit."submitStatus" = 'accepted'
GROUP BY submit."messageRecordId"
@@ -168,9 +169,9 @@ export class ReportsService implements OnModuleInit, OnModuleDestroy {
NULL,
COALESCE(SUM(message."billingUnits"), 0)::integer,
COALESCE(SUM(CASE WHEN message.status = 'delivered' OR message."receiptStatus" = 'delivered' THEN message."billingUnits" ELSE 0 END), 0)::integer,
COALESCE(SUM(billing.revenue), 0)::integer,
COALESCE(SUM(costs.cost), 0)::integer,
(COALESCE(SUM(billing.revenue), 0) - COALESCE(SUM(costs.cost), 0))::integer,
COALESCE(SUM(billing.revenue), 0)::bigint,
COALESCE(SUM(costs.cost), 0)::bigint,
(COALESCE(SUM(billing.revenue), 0) - COALESCE(SUM(costs.cost), 0))::bigint,
CASE WHEN COALESCE(SUM(billing.revenue), 0) = 0 THEN 0
ELSE ROUND((COALESCE(SUM(billing.revenue), 0) - COALESCE(SUM(costs.cost), 0)) * 10000.0 / SUM(billing.revenue))::integer END,
CURRENT_TIMESTAMP,
@@ -187,7 +188,7 @@ export class ReportsService implements OnModuleInit, OnModuleDestroy {
await tx.$executeRaw(Prisma.sql`
WITH billing AS (
SELECT "messageId", SUM(CASE WHEN "billingStatus" = 'charged' THEN "amountCents" ELSE 0 END)::integer AS revenue
SELECT "messageId", SUM(CASE WHEN "billingStatus" = 'charged' THEN "amountCents" ELSE 0 END)::bigint AS revenue
FROM "SmsBillingRecord"
GROUP BY "messageId"
)
@@ -214,9 +215,9 @@ export class ReportsService implements OnModuleInit, OnModuleDestroy {
AND receipt."channelId" = submit."channelId"
AND receipt."receiptStatus" = 'delivered'
) THEN message."billingUnits" ELSE 0 END), 0)::integer,
COALESCE(SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END), 0)::integer,
COALESCE(SUM(submit."costAmountCents"), 0)::integer,
(COALESCE(SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END), 0) - COALESCE(SUM(submit."costAmountCents"), 0))::integer,
COALESCE(SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END), 0)::bigint,
COALESCE(SUM(submit."costAmountCents"), 0)::bigint,
(COALESCE(SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END), 0) - COALESCE(SUM(submit."costAmountCents"), 0))::bigint,
CASE WHEN COALESCE(SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END), 0) = 0 THEN 0
ELSE ROUND((COALESCE(SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END), 0) - COALESCE(SUM(submit."costAmountCents"), 0)) * 10000.0 /
SUM(CASE WHEN message."submitId" = submit."submitId" THEN billing.revenue ELSE 0 END))::integer END,