invite.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /**
  2. * 邀请有礼功能相关API
  3. */
  4. import { USE_MOCK } from '@/utils/config';
  5. import { mockInviteRecords, mockInviteStats, mockActivityInfo, mockInviteCode } from '@/mock/invite';
  6. export enum InviteStatus {
  7. PENDING = 'pending',
  8. ACTIVATED = 'activated',
  9. REWARDED = 'rewarded',
  10. FAILED = 'failed'
  11. }
  12. export enum InviteStatusLabel {
  13. PENDING = '待激活',
  14. ACTIVATED = '已激活',
  15. REWARDED = '奖励已发放',
  16. FAILED = '发放失败'
  17. }
  18. export interface InviteCodeResponse {
  19. code: string;
  20. inviteUrl: string;
  21. expireTime?: string;
  22. }
  23. export interface BindInviteParams {
  24. inviteCode: string;
  25. }
  26. export interface BindInviteResponse {
  27. success: boolean;
  28. message: string;
  29. // 双向奖励发放结果
  30. rewardResult?: {
  31. inviteeCouponGranted: boolean; // 是否已向被邀请人发券
  32. inviteeCouponName?: string; // 被邀请人获得的优惠券名称
  33. inviteeCouponAmount?: number; // 被邀请人获得的优惠券金额
  34. inviterCouponPending: boolean; // 邀请人奖励是否待发放(需满足条件)
  35. triggerCondition?: string; // 触发条件说明
  36. };
  37. }
  38. export interface InviteRecord {
  39. id: string;
  40. inviteePhone: string;
  41. inviteeName?: string;
  42. status: InviteStatus;
  43. inviteTime: string;
  44. activateTime?: string;
  45. rewardTime?: string;
  46. couponName?: string;
  47. couponAmount?: number;
  48. rewardType?: 'inviter' | 'invitee'; // 奖励类型:inviter=邀请人推荐奖励, invitee=被邀请人新人券
  49. }
  50. export interface InviteRecordListResponse {
  51. list: InviteRecord[];
  52. total: number;
  53. page: number;
  54. pageSize: number;
  55. }
  56. export interface InviteQueryParams {
  57. page?: number;
  58. pageSize?: number;
  59. status?: InviteStatus;
  60. }
  61. export interface InviteStatistics {
  62. totalInvite: number;
  63. validInvite: number;
  64. rewardCount: number;
  65. pendingCount: number;
  66. totalRewardAmount: number;
  67. // 双向奖励统计
  68. inviterRewardCount?: number; // 邀请人推荐奖励数量
  69. inviteeRewardCount?: number; // 被邀请人新人券发放数量
  70. inviterRewardAmount?: number; // 邀请人推荐奖励总金额
  71. inviteeRewardAmount?: number; // 被邀请人新人券总金额
  72. }
  73. export interface ActivityInfo {
  74. activityId: string;
  75. title: string;
  76. description: string;
  77. couponName: string;
  78. couponAmount: number;
  79. startTime: string;
  80. endTime: string;
  81. rules: string[];
  82. isActive: boolean;
  83. // 双向奖励配置
  84. dualRewardConfig?: {
  85. inviteeCouponName: string; // 被邀请人新人券名称
  86. inviteeCouponAmount: number; // 被邀请人新人券金额
  87. inviterCouponName: string; // 邀请人推荐奖励券名称
  88. inviterCouponAmount: number; // 邀请人推荐奖励券金额
  89. triggerCondition: string; // 触发条件描述(如"好友完成首单")
  90. };
  91. }
  92. export interface PosterResponse {
  93. posterUrl: string;
  94. expireTime: string;
  95. }
  96. export async function getInviteCode(): Promise<InviteCodeResponse> {
  97. if (USE_MOCK) {
  98. return Promise.resolve(mockInviteCode);
  99. }
  100. const { get } = await import('@/utils/request');
  101. return get('/invite/code');
  102. }
  103. export async function bindInviteRelation(params: BindInviteParams): Promise<BindInviteResponse> {
  104. if (USE_MOCK) {
  105. return Promise.resolve({
  106. success: true,
  107. message: '邀请关系绑定成功',
  108. rewardResult: {
  109. inviteeCouponGranted: true,
  110. inviteeCouponName: '新人专属优惠券',
  111. inviteeCouponAmount: 10,
  112. inviterCouponPending: true,
  113. triggerCondition: '好友完成首单后发放'
  114. }
  115. });
  116. }
  117. const { post } = await import('@/utils/request');
  118. return post('/invite/bind', params);
  119. }
  120. export async function getMyInviteRecords(params: InviteQueryParams = {}): Promise<InviteRecordListResponse> {
  121. if (USE_MOCK) {
  122. const { page = 1, pageSize = 10, status } = params;
  123. let list = [...mockInviteRecords];
  124. if (status) {
  125. list = list.filter(item => item.status === status);
  126. }
  127. const total = list.length;
  128. const startIndex = (page - 1) * pageSize;
  129. return Promise.resolve({
  130. list: list.slice(startIndex, startIndex + pageSize),
  131. total,
  132. page,
  133. pageSize
  134. });
  135. }
  136. const { get } = await import('@/utils/request');
  137. return get('/invite/my-records', params);
  138. }
  139. export async function getMyInviteStatistics(): Promise<InviteStatistics> {
  140. if (USE_MOCK) {
  141. return Promise.resolve(mockInviteStats);
  142. }
  143. const { get } = await import('@/utils/request');
  144. return get('/invite/my-statistics');
  145. }
  146. export async function getActivityInfo(): Promise<ActivityInfo> {
  147. if (USE_MOCK) {
  148. return Promise.resolve(mockActivityInfo);
  149. }
  150. const { get } = await import('@/utils/request');
  151. return get('/invite/activity-info');
  152. }
  153. export async function generatePoster(): Promise<PosterResponse> {
  154. if (USE_MOCK) {
  155. return Promise.resolve({
  156. posterUrl: 'https://example.com/poster/invite_' + Date.now() + '.png',
  157. expireTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
  158. });
  159. }
  160. const { get } = await import('@/utils/request');
  161. return get('/invite/poster');
  162. }