feat(invite): 添加邀请统计功能

- 新增邀请统计页面,包含统计概览、邀请记录和排行榜三个标签页
- 实现邀请统计数据的获取和展示,包括总邀请数、成功注册数、转化率等
- 添加邀请记录的查询和展示功能
- 实现邀请排行榜的查询和展示功能
- 新增生成小程序码和处理邀请场景值的接口
This commit is contained in:
2025-08-19 01:38:37 +08:00
parent 9d9762ef17
commit f928264e2c
23 changed files with 2406 additions and 261 deletions

239
src/api/invite/index.ts Normal file
View File

@@ -0,0 +1,239 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api/index';
import { SERVER_API_URL } from '@/utils/server';
/**
* 小程序码生成参数
*/
export interface MiniProgramCodeParam {
// 小程序页面路径
page?: string;
// 场景值最大32个可见字符
scene: string;
// 二维码宽度,单位 px最小 280px最大 1280px
width?: number;
// 是否检查页面是否存在
checkPath?: boolean;
// 环境版本
envVersion?: 'release' | 'trial' | 'develop';
}
/**
* 邀请关系参数
*/
export interface InviteRelationParam {
// 邀请人ID
inviterId: number;
// 被邀请人ID
inviteeId: number;
// 邀请来源
source: string;
// 场景值
scene?: string;
// 邀请时间
inviteTime?: string;
}
/**
* 邀请统计数据
*/
export interface InviteStats {
// 总邀请数
totalInvites: number;
// 成功注册数
successfulRegistrations: number;
// 转化率
conversionRate: number;
// 今日邀请数
todayInvites: number;
// 本月邀请数
monthlyInvites: number;
// 邀请来源统计
sourceStats: InviteSourceStat[];
}
/**
* 邀请来源统计
*/
export interface InviteSourceStat {
source: string;
count: number;
successCount: number;
conversionRate: number;
}
/**
* 邀请记录
*/
export interface InviteRecord {
id?: number;
inviterId?: number;
inviteeId?: number;
inviterName?: string;
inviteeName?: string;
source?: string;
scene?: string;
status?: 'pending' | 'registered' | 'activated';
inviteTime?: string;
registerTime?: string;
activateTime?: string;
}
/**
* 邀请记录查询参数
*/
export interface InviteRecordParam {
page?: number;
limit?: number;
inviterId?: number;
status?: string;
source?: string;
startTime?: string;
endTime?: string;
}
/**
* 生成小程序码
*/
export async function generateMiniProgramCode(data: MiniProgramCodeParam) {
const res = await request.post<ApiResult<string>>(
SERVER_API_URL + '/invite/generate-miniprogram-code',
data
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 生成邀请小程序码
*/
export async function generateInviteCode(inviterId: number, source: string = 'qrcode') {
const scene = `inviter=${inviterId}&source=${source}&t=${Date.now()}`;
return generateMiniProgramCode({
page: 'pages/index/index',
scene: scene,
width: 430,
checkPath: true,
envVersion: 'release'
});
}
/**
* 建立邀请关系
*/
export async function createInviteRelation(data: InviteRelationParam) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/invite/create-relation',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 处理邀请场景值
*/
export async function processInviteScene(scene: string, userId: number) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/invite/process-scene',
{ scene, userId }
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取邀请统计数据
*/
export async function getInviteStats(inviterId: number) {
const res = await request.get<ApiResult<InviteStats>>(
SERVER_API_URL + `/invite/stats/${inviterId}`
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 分页查询邀请记录
*/
export async function pageInviteRecords(params: InviteRecordParam) {
const res = await request.get<ApiResult<PageResult<InviteRecord>>>(
SERVER_API_URL + '/invite/records/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取我的邀请记录
*/
export async function getMyInviteRecords(params: InviteRecordParam) {
const res = await request.get<ApiResult<PageResult<InviteRecord>>>(
SERVER_API_URL + '/invite/my-records',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 验证邀请码有效性
*/
export async function validateInviteCode(scene: string) {
const res = await request.post<ApiResult<{ valid: boolean; inviterId?: number; source?: string }>>(
SERVER_API_URL + '/invite/validate-code',
{ scene }
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 更新邀请状态
*/
export async function updateInviteStatus(inviteId: number, status: 'registered' | 'activated') {
const res = await request.put<ApiResult<unknown>>(
SERVER_API_URL + `/invite/update-status/${inviteId}`,
{ status }
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取邀请排行榜
*/
export async function getInviteRanking(params?: { limit?: number; period?: 'day' | 'week' | 'month' }) {
const res = await request.get<ApiResult<Array<{
inviterId: number;
inviterName: string;
inviteCount: number;
successCount: number;
conversionRate: number;
}>>>(
SERVER_API_URL + '/invite/ranking',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}