fix: 修复分销数据不显示和用户ID唯一性问题

1. 分销数据修复:
   - 添加访问记录API,即使未登录也记录访问
   - 登录成功后自动绑定推荐码
   - 在链接访问时立即记录访问统计

2. 支付商品名称修复:
   - 支付时显示完整章节名称而非仅ID
   - 格式:章节9.12-美业整合:一个人的公司如何月入十万

3. 用户ID唯一性修复:
   - 移除mockLogin,必须使用真实微信登录
   - 用户ID使用openId作为唯一标识
   - 同一微信用户每次登录都是同一ID
This commit is contained in:
卡若
2026-01-29 11:11:58 +08:00
parent 6989ade3e2
commit 395501e961
3 changed files with 172 additions and 48 deletions

View File

@@ -78,21 +78,48 @@ App({
if (refCode) {
console.log('[App] 检测到推荐码:', refCode)
// 立即记录访问(不需要登录,用于统计"通过链接进的人数"
this.recordReferralVisit(refCode)
// 检查是否已经绑定过
const boundRef = wx.getStorageSync('boundReferralCode')
if (boundRef && boundRef !== refCode) {
console.log('[App] 已绑定过其他推荐码,跳过')
return
console.log('[App] 已绑定过其他推荐码,不更换绑定关系')
// 但仍然记录访问,不return
} else {
// 保存待绑定的推荐码
this.globalData.pendingReferralCode = refCode
wx.setStorageSync('pendingReferralCode', refCode)
// 如果已登录,立即绑定
if (this.globalData.isLoggedIn && this.globalData.userInfo) {
this.bindReferralCode(refCode)
}
}
}
},
// 记录推荐访问(不需要登录,用于统计)
async recordReferralVisit(refCode) {
try {
// 获取openId如果有
const openId = this.globalData.openId || wx.getStorageSync('openId') || ''
const userId = this.globalData.userInfo?.id || ''
// 保存待绑定的推荐码
this.globalData.pendingReferralCode = refCode
wx.setStorageSync('pendingReferralCode', refCode)
// 如果已登录,立即绑定
if (this.globalData.isLoggedIn && this.globalData.userInfo) {
this.bindReferralCode(refCode)
}
await this.request('/api/referral/visit', {
method: 'POST',
data: {
referralCode: refCode,
visitorOpenId: openId,
visitorId: userId,
source: 'miniprogram',
page: getCurrentPages()[getCurrentPages().length - 1]?.route || ''
}
})
console.log('[App] 记录推荐访问成功')
} catch (e) {
console.log('[App] 记录推荐访问失败:', e.message)
// 忽略错误,不影响用户体验
}
},
@@ -286,20 +313,29 @@ App({
wx.setStorageSync('userInfo', res.data.user)
wx.setStorageSync('token', res.data.token || '')
// 登录成功后,检查待绑定的推荐码并执行绑定
const pendingRef = wx.getStorageSync('pendingReferralCode') || this.globalData.pendingReferralCode
if (pendingRef) {
console.log('[App] 登录后自动绑定推荐码:', pendingRef)
this.bindReferralCode(pendingRef)
}
}
return res.data
}
} catch (apiError) {
console.log('[App] API登录失败,使用模拟登录:', apiError.message)
console.log('[App] API登录失败:', apiError.message)
// 不使用模拟登录,提示用户网络问题
wx.showToast({ title: '网络异常,请重试', icon: 'none' })
return null
}
// API不可用时使用模拟登录
return this.mockLogin()
return null
} catch (e) {
console.error('[App] 登录失败:', e)
// 最后尝试模拟登录
return this.mockLogin()
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
return null
}
},
@@ -335,36 +371,11 @@ App({
return null
},
// 模拟登录(后端不可用时使用
// 模拟登录已废弃 - 不再使用
// 现在必须使用真实的微信登录获取openId作为唯一标识
mockLogin() {
const mockUser = {
id: 'user_' + Date.now(),
nickname: '访客用户',
phone: '',
avatar: '',
referralCode: 'SOUL' + Date.now().toString(36).toUpperCase().slice(-6),
purchasedSections: [],
hasFullBook: false,
earnings: 0,
pendingEarnings: 0,
referralCount: 0,
createdAt: new Date().toISOString()
}
const mockToken = 'mock_token_' + Date.now()
// 保存用户信息
this.globalData.userInfo = mockUser
this.globalData.isLoggedIn = true
this.globalData.purchasedSections = mockUser.purchasedSections
this.globalData.hasFullBook = mockUser.hasFullBook
wx.setStorageSync('userInfo', mockUser)
wx.setStorageSync('token', mockToken)
console.log('模拟登录成功:', mockUser)
return { user: mockUser, token: mockToken }
console.warn('[App] mockLogin已废弃请使用真实登录')
return null
},
// 手机号登录
@@ -385,14 +396,21 @@ App({
wx.setStorageSync('userInfo', res.data.user)
wx.setStorageSync('token', res.data.token)
// 登录成功后绑定推荐码
const pendingRef = wx.getStorageSync('pendingReferralCode') || this.globalData.pendingReferralCode
if (pendingRef) {
console.log('[App] 手机号登录后自动绑定推荐码:', pendingRef)
this.bindReferralCode(pendingRef)
}
return res.data
}
} catch (e) {
console.log('手机号API登录失败使用模拟登录:', e)
console.log('[App] 手机号登录失败:', e)
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
}
// 回退到模拟登录
return this.mockLogin()
return null
},
// 退出登录

View File

@@ -550,6 +550,12 @@ Page({
let paymentData = null
try {
// 获取章节完整名称用于支付描述
const sectionTitle = this.data.section?.title || sectionId
const description = type === 'fullbook'
? '《一场Soul的创业实验》全书'
: `章节${sectionId}-${sectionTitle.length > 20 ? sectionTitle.slice(0, 20) + '...' : sectionTitle}`
const res = await app.request('/api/miniprogram/pay', {
method: 'POST',
data: {
@@ -557,7 +563,7 @@ Page({
productType: type,
productId: sectionId,
amount,
description: type === 'fullbook' ? '《一场Soul的创业实验》全书' : `章节-${sectionId}`,
description,
userId: app.globalData.userInfo?.id || ''
}
})