feat(invite): 重构邀请关系建立流程并优化相关功能

- 新增 bindRefereeRelation 接口替换原有的 createInviteRelation 接口
- 优化邀请参数解析逻辑,支持 uid_xxx 格式的邀请码
- 重构 handleInviteRelation 函数,使用新的绑定推荐关系接口
- 新增 checkAndHandleInviteRelation 和 manualHandleInviteRelation 函数
- 优化首页和订单列表的相关逻辑,以支持新的邀请关系建立流程
- 更新文档中的相关描述,如将"下级成员"改为"团队成员"
This commit is contained in:
2025-08-23 12:18:32 +08:00
parent 0b83e67ac1
commit 7708968f53
9 changed files with 343 additions and 50 deletions

View File

@@ -1,5 +1,5 @@
import Taro from '@tarojs/taro'
import { createInviteRelation } from '@/api/invite'
import { bindRefereeRelation } from '@/api/invite'
/**
* 邀请参数接口
@@ -19,7 +19,22 @@ export function parseInviteParams(options: any): InviteParams | null {
if (options.scene) {
// 确保 scene 是字符串类型
const sceneStr = typeof options.scene === 'string' ? options.scene : String(options.scene)
console.log('解析scene参数:', sceneStr)
// 处理 uid_xxx 格式的邀请码
if (sceneStr.startsWith('uid_')) {
const inviterId = sceneStr.replace('uid_', '')
if (inviterId && !isNaN(parseInt(inviterId))) {
console.log('检测到uid格式邀请码:', inviterId)
return {
inviter: inviterId,
source: 'qrcode',
t: Date.now().toString()
}
}
}
// 处理传统的 key=value&key=value 格式
const params: InviteParams = {}
const pairs = sceneStr.split('&')
@@ -40,7 +55,10 @@ export function parseInviteParams(options: any): InviteParams | null {
}
})
return params.inviter ? params : null
if (params.inviter) {
console.log('检测到传统格式邀请码:', params)
return params
}
}
// 从 query 参数中解析邀请信息(兼容旧版本)
@@ -119,34 +137,61 @@ export function clearInviteParams() {
*/
export async function handleInviteRelation(userId: number): Promise<boolean> {
try {
console.log('开始处理邀请关系当前用户ID:', userId)
const inviteParams = getStoredInviteParams()
if (!inviteParams || !inviteParams.inviter) {
console.log('没有找到邀请参数,跳过邀请关系建立')
return false
}
console.log('找到邀请参数:', inviteParams)
const inviterId = parseInt(inviteParams.inviter)
if (isNaN(inviterId) || inviterId === userId) {
// 邀请人ID无效或自己邀请自己
console.log('邀请人ID无效或自己邀请自己清除邀请参数')
clearInviteParams()
return false
}
// 建立邀请关系
await createInviteRelation({
inviterId: inviterId,
inviteeId: userId,
source: inviteParams.source || 'unknown',
scene: `inviter=${inviterId}&source=${inviteParams.source}&t=${inviteParams.t}`,
inviteTime: new Date().toISOString()
console.log(`准备建立邀请关系: ${inviterId} -> ${userId}`)
// 使用新的绑定推荐关系接口
await bindRefereeRelation({
refereeId: inviterId,
userId: userId,
source: inviteParams.source || 'qrcode',
scene: inviteParams.source === 'qrcode' ? `uid_${inviterId}` : `inviter=${inviterId}&source=${inviteParams.source}&t=${inviteParams.t}`
})
// 清除本地存储的邀请参数
clearInviteParams()
console.log(`邀请关系建立成功: ${inviterId} -> ${userId}`)
// 显示成功提示
setTimeout(() => {
Taro.showToast({
title: '邀请关系建立成功',
icon: 'success',
duration: 2000
})
}, 500)
return true
} catch (error) {
console.error('建立邀请关系失败:', error)
// 显示错误提示
setTimeout(() => {
Taro.showToast({
title: '邀请关系建立失败',
icon: 'error',
duration: 2000
})
}, 500)
return false
}
}
@@ -229,3 +274,111 @@ export function trackInviteSource(source: string, inviterId?: number) {
console.error('统计邀请来源失败:', error)
}
}
/**
* 检查并处理当前用户的邀请关系
* 用于在用户登录后立即检查是否需要建立邀请关系
*/
export async function checkAndHandleInviteRelation(): Promise<boolean> {
try {
// 获取当前用户信息
const userInfo = Taro.getStorageSync('userInfo')
if (!userInfo || !userInfo.userId) {
console.log('用户未登录,无法处理邀请关系')
return false
}
return await handleInviteRelation(userInfo.userId)
} catch (error) {
console.error('检查邀请关系失败:', error)
return false
}
}
/**
* 手动触发邀请关系建立
* 用于在特定页面或时机手动建立邀请关系
*/
export async function manualHandleInviteRelation(userId: number): Promise<boolean> {
try {
console.log('手动触发邀请关系建立用户ID:', userId)
const inviteParams = getStoredInviteParams()
if (!inviteParams || !inviteParams.inviter) {
console.log('没有待处理的邀请参数')
return false
}
const result = await handleInviteRelation(userId)
if (result) {
// 显示成功提示
Taro.showModal({
title: '邀请成功',
content: '您已成功加入邀请人的团队!',
showCancel: false,
confirmText: '知道了'
})
}
return result
} catch (error) {
console.error('手动处理邀请关系失败:', error)
return false
}
}
/**
* 直接绑定推荐关系
* 用于直接调用绑定推荐关系接口
*/
export async function bindReferee(refereeId: number, userId?: number, source: string = 'qrcode'): Promise<boolean> {
try {
console.log('直接绑定推荐关系:', { refereeId, userId, source })
// 如果没有传入userId尝试从本地存储获取
let targetUserId = userId
if (!targetUserId) {
const userInfo = Taro.getStorageSync('userInfo')
if (userInfo && userInfo.userId) {
targetUserId = userInfo.userId
} else {
throw new Error('无法获取用户ID')
}
}
// 防止自己推荐自己
if (refereeId === targetUserId) {
throw new Error('不能推荐自己')
}
await bindRefereeRelation({
refereeId: refereeId,
userId: targetUserId,
source: source,
scene: source === 'qrcode' ? `uid_${refereeId}` : undefined
})
console.log(`推荐关系绑定成功: ${refereeId} -> ${targetUserId}`)
// 显示成功提示
Taro.showToast({
title: '推荐关系绑定成功',
icon: 'success',
duration: 2000
})
return true
} catch (error: any) {
console.error('绑定推荐关系失败:', error)
// 显示错误提示
Taro.showToast({
title: error.message || '绑定推荐关系失败',
icon: 'error',
duration: 2000
})
return false
}
}