Files
makemd/server/src/services/MerchantDataStatisticsService.ts
wurenzhi 15ee1758f5 refactor: 重构项目结构并优化类型定义
- 移除extension模块,将功能迁移至node-agent
- 修复类型导出问题,使用export type明确类型导出
- 统一数据库连接方式,从直接导入改为使用config/database
- 更新文档中的项目结构描述
- 添加多个服务的实用方法,如getForecast、getBalances等
- 修复类型错误和TS1205警告
- 优化RedisService调用方式
- 添加新的实体类型定义
- 更新审计日志格式,统一字段命名
2026-03-21 15:04:06 +08:00

205 lines
5.8 KiB
TypeScript

import { Knex } from 'knex';
import db from '../config/database';
export class MerchantDataStatisticsService {
/**
* 统计多商户数据
* @param params 统计参数
* @param traceInfo 追踪信息
* @returns 统计数据
*/
public static async statisticsMerchantData(
params: {
merchantId?: string;
timeRange?: { start: string; end: string };
metrics?: string[];
},
traceInfo: {
tenantId: string;
shopId: string;
taskId: string;
traceId: string;
businessType: 'TOC' | 'TOB';
}
): Promise<{
merchantId: string;
timestamp: string;
metrics: Record<string, any>;
details: Array<{
metric: string;
value: number;
unit: string;
trend: 'up' | 'down' | 'stable';
}>;
}> {
try {
// 模拟数据库查询
const merchantId = params.merchantId || 'all';
const timestamp = new Date().toISOString();
// 构建统计指标
const metrics = {
totalOrders: Math.floor(Math.random() * 1000) + 100,
totalSales: (Math.random() * 100000 + 10000).toFixed(2),
averageOrderValue: (Math.random() * 500 + 100).toFixed(2),
orderCompletionRate: (Math.random() * 30 + 70).toFixed(2),
activeCustomers: Math.floor(Math.random() * 500) + 100,
newCustomers: Math.floor(Math.random() * 100) + 20,
};
const details = Object.entries(metrics).map(([metric, value]) => ({
metric,
value: typeof value === 'string' ? parseFloat(value) : value,
unit: metric.includes('Rate') ? '%' : metric.includes('Sales') || metric.includes('Value') ? '¥' : '',
trend: ['up', 'down', 'stable'][Math.floor(Math.random() * 3)] as 'up' | 'down' | 'stable',
}));
return {
merchantId,
timestamp,
metrics,
details,
};
} catch (error) {
console.error('Error statistics merchant data:', error);
throw new Error('Failed to statistics merchant data');
}
}
/**
* 生成商户数据统计报告
* @param params 报告参数
* @param traceInfo 追踪信息
* @returns 报告数据
*/
public static async generateStatisticsReport(
params: {
merchantId?: string;
timeRange: { start: string; end: string };
reportType: 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly';
},
traceInfo: {
tenantId: string;
shopId: string;
taskId: string;
traceId: string;
businessType: 'TOC' | 'TOB';
}
): Promise<{
reportId: string;
merchantId: string;
reportType: string;
timeRange: { start: string; end: string };
timestamp: string;
summary: string;
metrics: Record<string, any>;
recommendations: string[];
}> {
try {
const reportId = `REPORT-${Date.now()}`;
const merchantId = params.merchantId || 'all';
const timestamp = new Date().toISOString();
// 生成统计数据
const statistics = await this.statisticsMerchantData(params, traceInfo);
// 生成摘要
const summary = `商户 ${merchantId}${params.timeRange.start}${params.timeRange.end} 期间的${this.getReportTypeName(params.reportType)}统计报告`;
// 生成建议
const recommendations = [
'建议优化产品定价策略,提高平均订单价值',
'建议增加促销活动,吸引更多新客户',
'建议改进客户服务,提高订单完成率',
'建议分析销售数据,优化产品结构',
];
return {
reportId,
merchantId,
reportType: params.reportType,
timeRange: params.timeRange,
timestamp,
summary,
metrics: statistics.metrics,
recommendations,
};
} catch (error) {
console.error('Error generating statistics report:', error);
throw new Error('Failed to generate statistics report');
}
}
/**
* 获取商户排名
* @param params 排名参数
* @param traceInfo 追踪信息
* @returns 排名数据
*/
public static async getMerchantRanking(
params: {
metric: 'sales' | 'orders' | 'customers' | 'completionRate';
limit?: number;
timeRange: { start: string; end: string };
},
traceInfo: {
tenantId: string;
shopId: string;
taskId: string;
traceId: string;
businessType: 'TOC' | 'TOB';
}
): Promise<{
metric: string;
timeRange: { start: string; end: string };
timestamp: string;
rankings: Array<{
rank: number;
merchantId: string;
merchantName: string;
value: number;
unit: string;
}>;
}> {
try {
const limit = params.limit || 10;
const timestamp = new Date().toISOString();
// 模拟排名数据
const rankings = Array.from({ length: limit }, (_, index) => ({
rank: index + 1,
merchantId: `MERCHANT-${index + 1}`,
merchantName: `商户${index + 1}`,
value: Math.floor(Math.random() * 100000) + 1000,
unit: params.metric === 'completionRate' ? '%' : params.metric === 'customers' || params.metric === 'orders' ? '' : '¥',
})).sort((a, b) => b.value - a.value);
return {
metric: params.metric,
timeRange: params.timeRange,
timestamp,
rankings,
};
} catch (error) {
console.error('Error getting merchant ranking:', error);
throw new Error('Failed to get merchant ranking');
}
}
/**
* 获取报告类型名称
* @param reportType 报告类型
* @returns 报告类型名称
*/
private static getReportTypeName(reportType: string): string {
const typeNames = {
daily: '每日',
weekly: '每周',
monthly: '每月',
quarterly: '季度',
yearly: '年度',
};
return typeNames[reportType as keyof typeof typeNames] || '';
}
}