feat: 实现多商户管理模块与前端服务
refactor: 优化服务层代码并修复类型问题 docs: 更新开发进度文档 feat(merchant): 新增商户监控与数据统计服务 feat(dashboard): 添加商户管理前端页面与服务 fix: 修复类型转换与可选参数处理 feat: 实现商户订单、店铺与结算管理功能 refactor: 重构审计日志格式与服务调用 feat: 新增商户入驻与身份注册功能 fix(controller): 修复路由参数类型问题 feat: 添加商户排名与统计报告功能 chore: 更新模拟数据与服务配置
This commit is contained in:
259
server/src/services/MerchantBehaviorAnalysisService.ts
Normal file
259
server/src/services/MerchantBehaviorAnalysisService.ts
Normal file
@@ -0,0 +1,259 @@
|
||||
import { Knex } from 'knex';
|
||||
import { db } from '../database';
|
||||
|
||||
export class MerchantBehaviorAnalysisService {
|
||||
/**
|
||||
* 分析商户行为数据
|
||||
* @param params 分析参数
|
||||
* @param traceInfo 追踪信息
|
||||
* @returns 分析结果
|
||||
*/
|
||||
public static async analyzeMerchantBehavior(
|
||||
params: {
|
||||
merchantId: string;
|
||||
timeRange?: { start: string; end: string };
|
||||
behaviors?: string[];
|
||||
},
|
||||
traceInfo: {
|
||||
tenantId: string;
|
||||
shopId: string;
|
||||
taskId: string;
|
||||
traceId: string;
|
||||
businessType: 'TOC' | 'TOB';
|
||||
}
|
||||
): Promise<{
|
||||
merchantId: string;
|
||||
timestamp: string;
|
||||
behaviorPatterns: Array<{
|
||||
behavior: string;
|
||||
frequency: number;
|
||||
averageDuration: number;
|
||||
peakTime: string;
|
||||
trend: 'increasing' | 'decreasing' | 'stable';
|
||||
}>;
|
||||
insights: string[];
|
||||
}> {
|
||||
try {
|
||||
const merchantId = params.merchantId;
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// 模拟行为数据
|
||||
const behaviorPatterns = [
|
||||
{
|
||||
behavior: 'login',
|
||||
frequency: Math.floor(Math.random() * 50) + 10,
|
||||
averageDuration: Math.floor(Math.random() * 30) + 5,
|
||||
peakTime: '10:00-12:00',
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
},
|
||||
{
|
||||
behavior: 'product_management',
|
||||
frequency: Math.floor(Math.random() * 30) + 5,
|
||||
averageDuration: Math.floor(Math.random() * 60) + 15,
|
||||
peakTime: '14:00-16:00',
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
},
|
||||
{
|
||||
behavior: 'order_processing',
|
||||
frequency: Math.floor(Math.random() * 40) + 8,
|
||||
averageDuration: Math.floor(Math.random() * 45) + 10,
|
||||
peakTime: '9:00-11:00',
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
},
|
||||
{
|
||||
behavior: 'inventory_management',
|
||||
frequency: Math.floor(Math.random() * 25) + 3,
|
||||
averageDuration: Math.floor(Math.random() * 50) + 12,
|
||||
peakTime: '15:00-17:00',
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
},
|
||||
{
|
||||
behavior: 'financial_operations',
|
||||
frequency: Math.floor(Math.random() * 15) + 2,
|
||||
averageDuration: Math.floor(Math.random() * 40) + 18,
|
||||
peakTime: '16:00-18:00',
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
},
|
||||
];
|
||||
|
||||
// 生成洞察
|
||||
const insights = [
|
||||
`商户 ${merchantId} 的登录频率为 ${behaviorPatterns[0].frequency} 次,呈 ${this.getTrendDescription(behaviorPatterns[0].trend)} 趋势`,
|
||||
`产品管理行为的平均持续时间为 ${behaviorPatterns[1].averageDuration} 分钟,峰值时间为 ${behaviorPatterns[1].peakTime}`,
|
||||
`订单处理行为的频率为 ${behaviorPatterns[2].frequency} 次,呈 ${this.getTrendDescription(behaviorPatterns[2].trend)} 趋势`,
|
||||
`库存管理行为的平均持续时间为 ${behaviorPatterns[3].averageDuration} 分钟,峰值时间为 ${behaviorPatterns[3].peakTime}`,
|
||||
`财务操作行为的频率为 ${behaviorPatterns[4].frequency} 次,呈 ${this.getTrendDescription(behaviorPatterns[4].trend)} 趋势`,
|
||||
];
|
||||
|
||||
return {
|
||||
merchantId,
|
||||
timestamp,
|
||||
behaviorPatterns,
|
||||
insights,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error analyzing merchant behavior:', error);
|
||||
throw new Error('Failed to analyze merchant behavior');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成商户行为分析报告
|
||||
* @param params 报告参数
|
||||
* @param traceInfo 追踪信息
|
||||
* @returns 分析报告
|
||||
*/
|
||||
public static async generateBehaviorAnalysisReport(
|
||||
params: {
|
||||
merchantId: string;
|
||||
timeRange: { start: string; end: string };
|
||||
reportType: 'detailed' | 'summary';
|
||||
},
|
||||
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;
|
||||
behaviorPatterns: Array<{
|
||||
behavior: string;
|
||||
frequency: number;
|
||||
averageDuration: number;
|
||||
peakTime: string;
|
||||
trend: 'increasing' | 'decreasing' | 'stable';
|
||||
}>;
|
||||
insights: string[];
|
||||
recommendations: string[];
|
||||
}> {
|
||||
try {
|
||||
const reportId = `BEHAVIOR-REPORT-${Date.now()}`;
|
||||
const merchantId = params.merchantId;
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// 分析商户行为
|
||||
const analysis = await this.analyzeMerchantBehavior(params, traceInfo);
|
||||
|
||||
// 生成摘要
|
||||
const summary = `商户 ${merchantId} 在 ${params.timeRange.start} 至 ${params.timeRange.end} 期间的行为分析报告`;
|
||||
|
||||
// 生成建议
|
||||
const recommendations = [
|
||||
'建议优化登录流程,提高商户使用体验',
|
||||
'建议在峰值时间提供额外的系统资源,确保服务稳定性',
|
||||
'建议简化产品管理操作,减少平均处理时间',
|
||||
'建议优化订单处理流程,提高处理效率',
|
||||
'建议提供库存管理自动化工具,减少手动操作',
|
||||
'建议优化财务操作界面,提高操作便捷性',
|
||||
];
|
||||
|
||||
return {
|
||||
reportId,
|
||||
merchantId,
|
||||
reportType: params.reportType,
|
||||
timeRange: params.timeRange,
|
||||
timestamp,
|
||||
summary,
|
||||
behaviorPatterns: analysis.behaviorPatterns,
|
||||
insights: analysis.insights,
|
||||
recommendations,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error generating behavior analysis report:', error);
|
||||
throw new Error('Failed to generate behavior analysis report');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预测商户行为趋势
|
||||
* @param params 预测参数
|
||||
* @param traceInfo 追踪信息
|
||||
* @returns 预测结果
|
||||
*/
|
||||
public static async predictMerchantBehaviorTrend(
|
||||
params: {
|
||||
merchantId: string;
|
||||
timeRange: { start: string; end: string };
|
||||
predictionDays: number;
|
||||
},
|
||||
traceInfo: {
|
||||
tenantId: string;
|
||||
shopId: string;
|
||||
taskId: string;
|
||||
traceId: string;
|
||||
businessType: 'TOC' | 'TOB';
|
||||
}
|
||||
): Promise<{
|
||||
merchantId: string;
|
||||
timestamp: string;
|
||||
predictionDays: number;
|
||||
predictions: Array<{
|
||||
behavior: string;
|
||||
currentFrequency: number;
|
||||
predictedFrequency: number;
|
||||
trend: 'increasing' | 'decreasing' | 'stable';
|
||||
confidence: number;
|
||||
}>;
|
||||
}> {
|
||||
try {
|
||||
const merchantId = params.merchantId;
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// 模拟预测数据
|
||||
const predictions = [
|
||||
{
|
||||
behavior: 'login',
|
||||
currentFrequency: Math.floor(Math.random() * 50) + 10,
|
||||
predictedFrequency: Math.floor(Math.random() * 20) + 10,
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
confidence: Math.floor(Math.random() * 30) + 70,
|
||||
},
|
||||
{
|
||||
behavior: 'product_management',
|
||||
currentFrequency: Math.floor(Math.random() * 30) + 5,
|
||||
predictedFrequency: Math.floor(Math.random() * 15) + 5,
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
confidence: Math.floor(Math.random() * 30) + 70,
|
||||
},
|
||||
{
|
||||
behavior: 'order_processing',
|
||||
currentFrequency: Math.floor(Math.random() * 40) + 8,
|
||||
predictedFrequency: Math.floor(Math.random() * 20) + 8,
|
||||
trend: ['increasing', 'decreasing', 'stable'][Math.floor(Math.random() * 3)] as 'increasing' | 'decreasing' | 'stable',
|
||||
confidence: Math.floor(Math.random() * 30) + 70,
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
merchantId,
|
||||
timestamp,
|
||||
predictionDays: params.predictionDays,
|
||||
predictions,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error predicting merchant behavior trend:', error);
|
||||
throw new Error('Failed to predict merchant behavior trend');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取趋势描述
|
||||
* @param trend 趋势
|
||||
* @returns 趋势描述
|
||||
*/
|
||||
private static getTrendDescription(trend: string): string {
|
||||
const trendDescriptions = {
|
||||
increasing: '上升',
|
||||
decreasing: '下降',
|
||||
stable: '稳定',
|
||||
};
|
||||
return trendDescriptions[trend as keyof typeof trendDescriptions] || '';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user