import Taro from '@tarojs/taro' import {bindRefereeRelation} from "@/api/invite"; /** * 邀请参数接口 */ export interface InviteParams { inviter?: string; source?: string; t?: string; } /** * 解析小程序启动参数中的邀请信息 */ export function parseInviteParams(options: any): InviteParams | null { try { console.log('解析邀请参数:', options) // 优先从 query.scene 中解析邀请信息 if (options.query && options.query.scene) { const sceneStr = typeof options.query.scene === 'string' ? options.query.scene : String(options.query.scene) console.log('从 query.scene 解析:', sceneStr) // 处理 uid_xxxxx 格式的参数 if (sceneStr.startsWith('uid_')) { const uid = sceneStr.replace('uid_', '') if (uid) { return { inviter: uid, source: 'qrcode', t: String(Date.now()) } } } // 处理 key=value&key=value 格式的参数 if (sceneStr.includes('=')) { const params: InviteParams = {} const pairs = sceneStr.split('&') pairs.forEach((pair: string) => { const [key, value] = pair.split('=') if (key && value) { switch (key) { case 'inviter': case 'uid': params.inviter = decodeURIComponent(value) break case 'source': params.source = decodeURIComponent(value) break case 't': params.t = decodeURIComponent(value) break } } }) if (params.inviter) { return params } } } // 从 scene 参数中解析邀请信息(兼容旧版本) if (options.scene) { const sceneStr = typeof options.scene === 'string' ? options.scene : String(options.scene) console.log('从 scene 解析:', sceneStr) // 处理 uid_xxxxx 格式的参数 if (sceneStr.startsWith('uid_')) { const uid = sceneStr.replace('uid_', '') if (uid) { return { inviter: uid, source: 'qrcode', t: String(Date.now()) } } } // 处理 key=value&key=value 格式的参数 if (sceneStr.includes('=')) { const params: InviteParams = {} const pairs = sceneStr.split('&') pairs.forEach((pair: string) => { const [key, value] = pair.split('=') if (key && value) { switch (key) { case 'inviter': case 'uid': params.inviter = decodeURIComponent(value) break case 'source': params.source = decodeURIComponent(value) break case 't': params.t = decodeURIComponent(value) break } } }) if (params.inviter) { return params } } } // 从 query 参数中解析邀请信息(兼容旧版本) if (options.referrer) { return { inviter: options.referrer, source: 'link' } } return null } catch (error) { console.error('解析邀请参数失败:', error) return null } } /** * 保存邀请信息到本地存储 */ export function saveInviteParams(params: InviteParams) { try { Taro.setStorageSync('invite_params', { ...params, timestamp: Date.now() }) console.log('邀请参数已保存:', params) } catch (error) { console.error('保存邀请参数失败:', error) } } /** * 获取本地存储的邀请信息 */ export function getStoredInviteParams(): InviteParams | null { try { const stored = Taro.getStorageSync('invite_params') if (stored && stored.inviter) { // 检查是否过期(24小时) const now = Date.now() const expireTime = 24 * 60 * 60 * 1000 // 24小时 if (now - stored.timestamp < expireTime) { return { inviter: stored.inviter, source: stored.source || 'unknown', t: stored.t } } else { // 过期则清除 clearInviteParams() } } return null } catch (error) { console.error('获取邀请参数失败:', error) return null } } /** * 清除本地存储的邀请信息 */ export function clearInviteParams() { try { Taro.removeStorageSync('invite_params') console.log('邀请参数已清除') } catch (error) { console.error('清除邀请参数失败:', error) } } /** * 处理邀请关系建立 */ export async function handleInviteRelation(userId: number): Promise { try { const inviteParams = getStoredInviteParams() if (!inviteParams || !inviteParams.inviter) { return false } const inviterId = parseInt(inviteParams.inviter) if (isNaN(inviterId) || inviterId === userId) { // 邀请人ID无效或自己邀请自己 clearInviteParams() return false } // 建立邀请关系 await bindRefereeRelation({ dealerId: inviterId, userId: userId, source: inviteParams.source || 'unknown', scene: `inviter=${inviterId}&source=${inviteParams.source}&t=${inviteParams.t}` }) // 清除本地存储的邀请参数 clearInviteParams() console.log(`邀请关系建立成功: ${inviterId} -> ${userId}`) return true } catch (error) { console.error('建立邀请关系失败:', error) return false } } /** * 检查是否有待处理的邀请 */ export function hasPendingInvite(): boolean { const params = getStoredInviteParams() return !!(params && params.inviter) } /** * 获取邀请来源的显示名称 */ export function getSourceDisplayName(source: string): string { const sourceMap: Record = { 'qrcode': '小程序码', 'link': '分享链接', 'share': '好友分享', 'poster': '海报分享', 'unknown': '未知来源' } return sourceMap[source] || source } /** * 验证邀请码格式 */ export function validateInviteCode(scene: string): boolean { try { if (!scene) return false // 检查是否包含必要的参数 const hasInviter = scene.includes('inviter=') const hasSource = scene.includes('source=') return hasInviter && hasSource } catch (error) { return false } } /** * 生成邀请场景值 */ export function generateInviteScene(inviterId: number, source: string): string { const timestamp = Date.now() return `inviter=${inviterId}&source=${source}&t=${timestamp}` } /** * 统计邀请来源 */ export function trackInviteSource(source: string, inviterId?: number) { try { // 记录邀请来源统计 const trackData = { source, inviterId, timestamp: Date.now(), userAgent: Taro.getSystemInfoSync() } // 可以发送到统计服务 console.log('邀请来源统计:', trackData) // 暂存到本地,后续可批量上报 const existingTracks = Taro.getStorageSync('invite_tracks') || [] existingTracks.push(trackData) // 只保留最近100条记录 if (existingTracks.length > 100) { existingTracks.splice(0, existingTracks.length - 100) } Taro.setStorageSync('invite_tracks', existingTracks) } catch (error) { console.error('统计邀请来源失败:', error) } }