Compare commits
2 Commits
f918bfc81a
...
662a31dac8
| Author | SHA1 | Date | |
|---|---|---|---|
| 662a31dac8 | |||
| cdfe233ea8 |
@ -271,6 +271,10 @@ export function getUserInvites(user_id, page = 1, page_size = 20) {
|
||||
// 兼容性适配接口 (适配 pages/mine/index.vue)
|
||||
// ============================================
|
||||
|
||||
export function bindInviter(invite_code) {
|
||||
return authRequest({ url: '/api/app/users/inviter/bind', method: 'POST', data: { invite_code } })
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 用户信息修改 API
|
||||
// ============================================
|
||||
|
||||
@ -157,6 +157,12 @@
|
||||
</view>
|
||||
<text class="menu-label">任务中心</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="showBindInviterPopup" v-if="!inviterId">
|
||||
<view class="menu-icon-box">
|
||||
<image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMCAxMyxhNSw1IDAgMCwwIDcuNTQsLjU0bDMtM2E1LDUgMCAwLDAgLTcuMDctNy4wN2wtMS43MiwxLjcxIiAvPjxwYXRoIGQ9Ik0xNCAxMSxhNSw1IDAgMCwwIC03LjU0LC0uNTRsLTMsM2E1LDUgMCAwLDAgNy4wNyw3LjA3bDEuNzIsLTEuNzEiIC8+PC9zdmc+" mode="aspectFit"></image>
|
||||
</view>
|
||||
<text class="menu-label">填写邀请码</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="toInvitesPage">
|
||||
<view class="menu-icon-box">
|
||||
<image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xNyAyMXYtMmE0IDQgMCAwIDAtNC00SDdhNCA0IDAgMCAwLTQgNHYyIj48L3BhdGg+PGNpcmNsZSBjeD0iMTAiIGN5PSI3IiByPSI0Ij48L2NpcmNsZT48cGF0aCBkPSJNMjMgMjF2LTJhNCA0IDAgMCAwLTMtMy4yNyI+PC9wYXRoPjxwYXRoIGQ9Ik0xNiAzLjEzYTQgNCAwIDAgMSAwIDcuNzUiPjwvcGF0aD48L3N2Zz4=" mode="aspectFit"></image>
|
||||
@ -492,13 +498,31 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 绑定邀请码弹窗 -->
|
||||
<view class="popup-mask" v-if="bindInviterVisible" @tap="closeBindInviterPopup">
|
||||
<view class="popup-content bind-inviter-popup" @tap.stop>
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">填写邀请码</text>
|
||||
<text class="close-btn" @tap="closeBindInviterPopup">×</text>
|
||||
</view>
|
||||
<view class="bind-inviter-body">
|
||||
<view class="bind-desc">请输入好友的邀请码,绑定后双方可获得奖励</view>
|
||||
<view class="input-wrapper">
|
||||
<input type="text" v-model="bindInviteCode" class="invite-code-input" placeholder="请输入邀请码" placeholder-class="input-placeholder" />
|
||||
</view>
|
||||
<button class="bind-btn" @tap="handleBindInviter">确认绑定</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserInfo, getUserStats, getPointsBalance, getUserPoints, getUserCoupons, getItemCards,
|
||||
getUserTasks, getTaskProgress, getInviteRecords, modifyUser, getUserProfile, bindDouyinID, getPublicConfig
|
||||
getUserTasks, getTaskProgress, getInviteRecords, modifyUser, getUserProfile, bindDouyinID, getPublicConfig,
|
||||
bindInviter
|
||||
} from '../../api/appUser.js'
|
||||
import { checkPhoneBoundSync } from '../../utils/checkPhone.js'
|
||||
// #ifdef MP-TOUTIAO
|
||||
@ -511,7 +535,7 @@ import customTabBar from '@/components/app-tab-bar.vue'
|
||||
export default {
|
||||
components: {
|
||||
// #ifdef MP-TOUTIAO
|
||||
customTabBarToutiao
|
||||
customTabBarToutiao,
|
||||
// #endif
|
||||
// #ifndef MP-TOUTIAO
|
||||
customTabBar
|
||||
@ -524,9 +548,16 @@ export default {
|
||||
avatar: '',
|
||||
title: '', // 用户头衔
|
||||
inviteCode: '',
|
||||
inviterId: 0,
|
||||
inviterNickname: '',
|
||||
inviterAvatar: '',
|
||||
|
||||
// Bind Inviter Popup
|
||||
bindInviterVisible: false,
|
||||
bindInviteCode: '',
|
||||
|
||||
mobile: '', // 手机号
|
||||
douyinUserId: '', // 抖音用户ID
|
||||
douyinUserId: '', // 抖音用户ID
|
||||
customerServiceQrCode: '', // 客服二维码
|
||||
customerServiceId: '0071112x', // 抖音IM客服账号
|
||||
pointsBalance: 0,
|
||||
@ -854,6 +885,9 @@ export default {
|
||||
this.avatar = profile.avatar
|
||||
this.title = profile.title || ''
|
||||
this.inviteCode = profile.invite_code
|
||||
this.inviterId = profile.inviter_id || 0
|
||||
this.inviterNickname = profile.inviter_nickname || ''
|
||||
this.inviterAvatar = profile.inviter_avatar || ''
|
||||
this.pointsBalance = this.normalizePointsBalance(profile.balance)
|
||||
this.mobile = profile.mobile || ''
|
||||
this.douyinUserId = profile.douyin_user_id || ''
|
||||
@ -865,6 +899,9 @@ export default {
|
||||
cachedUser.avatar = profile.avatar
|
||||
cachedUser.title = profile.title
|
||||
cachedUser.invite_code = profile.invite_code
|
||||
cachedUser.inviter_id = profile.inviter_id
|
||||
cachedUser.inviter_nickname = profile.inviter_nickname
|
||||
cachedUser.inviter_avatar = profile.inviter_avatar
|
||||
cachedUser.mobile = profile.mobile
|
||||
cachedUser.points_balance = this.pointsBalance
|
||||
uni.setStorageSync('user_info', cachedUser)
|
||||
@ -882,9 +919,12 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
// 降级到旧逻辑
|
||||
// 降级到旧逻辑 (通常不会走到这里,除非 API 挂了)
|
||||
// ... (省略部分降级代码,或者保持原样)
|
||||
// 简单起见,如果 profile 失败,降级逻辑里可能拿不到 inviterId,
|
||||
// 但为了保持健壮性,这里保留原有的逻辑,只是不再去更新 inviterId(因为旧逻辑拿不到)
|
||||
|
||||
console.log('[Mine] profile API 无数据,使用降级逻辑')
|
||||
// 先尝试从缓存获取基础信息
|
||||
const cachedUser = uni.getStorageSync('user_info')
|
||||
const cachedUserId = uni.getStorageSync('user_id')
|
||||
|
||||
@ -893,6 +933,11 @@ export default {
|
||||
this.nickname = cachedUser.nickname
|
||||
this.avatar = cachedUser.avatar
|
||||
this.inviteCode = cachedUser.invite_code
|
||||
// 缓存里可能有 inviter 信息
|
||||
this.inviterId = cachedUser.inviter_id || 0
|
||||
this.inviterNickname = cachedUser.inviter_nickname || ''
|
||||
this.inviterAvatar = cachedUser.inviter_avatar || ''
|
||||
|
||||
this.title = cachedUser.title || ''
|
||||
this.pointsBalance = this.normalizePointsBalance(cachedUser.points_balance)
|
||||
this.mobile = cachedUser.mobile || cachedUser.phone || cachedUser.phone_number || ''
|
||||
@ -900,44 +945,51 @@ export default {
|
||||
} else if (cachedUserId) {
|
||||
this.userId = cachedUserId
|
||||
}
|
||||
|
||||
|
||||
// ... 继续原有加载 stats 逻辑
|
||||
if (this.userId) {
|
||||
try {
|
||||
const balanceRes = await getPointsBalance(this.userId)
|
||||
if (balanceRes !== undefined) {
|
||||
this.pointsBalance = this.normalizePointsBalance(balanceRes)
|
||||
if (cachedUser) {
|
||||
cachedUser.points_balance = this.pointsBalance
|
||||
uni.setStorageSync('user_info', cachedUser)
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
const s = await getUserStats(this.userId)
|
||||
if (s) this.stats = { ...this.stats, ...s }
|
||||
} else {
|
||||
// 如果没有 userId,尝试调用 getUserInfo (即使可能失败)
|
||||
const res = await getUserInfo()
|
||||
if (res) {
|
||||
this.userId = res.id
|
||||
this.nickname = res.nickname
|
||||
this.avatar = res.avatar
|
||||
this.title = res.title || res.level_name || ''
|
||||
this.inviteCode = res.invite_code
|
||||
this.pointsBalance = this.normalizePointsBalance(res.points_balance)
|
||||
this.mobile = res.mobile || res.phone || res.phone_number || ''
|
||||
this.douyinUserId = res.douyin_user_id || ''
|
||||
uni.setStorageSync('user_info', res)
|
||||
uni.setStorageSync('user_id', res.id)
|
||||
|
||||
// Load stats
|
||||
const s = await getUserStats(res.id)
|
||||
if(s) this.stats = { ...this.stats, ...s }
|
||||
}
|
||||
const s = await getUserStats(this.userId)
|
||||
if (s) this.stats = { ...this.stats, ...s }
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('[Mine] loadUserInfo 错误:', e)
|
||||
// If 401, maybe clear token
|
||||
}
|
||||
},
|
||||
|
||||
showBindInviterPopup() {
|
||||
if (!this.checkPhoneBound()) return
|
||||
this.bindInviteCode = ''
|
||||
this.bindInviterVisible = true
|
||||
},
|
||||
|
||||
closeBindInviterPopup() {
|
||||
this.bindInviterVisible = false
|
||||
},
|
||||
|
||||
async handleBindInviter() {
|
||||
const code = this.bindInviteCode.trim()
|
||||
if (!code) {
|
||||
uni.showToast({ title: '请输入邀请码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
// 不允许绑定自己
|
||||
if (code === this.inviteCode) {
|
||||
uni.showToast({ title: '不能绑定自己的邀请码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
uni.showLoading({ title: '绑定中...' })
|
||||
await bindInviter(code)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '绑定成功', icon: 'success' })
|
||||
this.bindInviterVisible = false
|
||||
// 刷新用户信息,获取已绑定的邀请人信息
|
||||
this.loadUserInfo()
|
||||
} catch (err) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: err.message || '绑定失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
resetUser() {
|
||||
@ -2271,6 +2323,58 @@ export default {
|
||||
.invite-time { font-size: 22rpx; color: $text-tertiary; margin-top: 4rpx; }
|
||||
.invite-status { font-size: 24rpx; color: #10B981; }
|
||||
|
||||
/* 绑定邀请码弹窗 */
|
||||
.bind-inviter-popup {
|
||||
width: 600rpx;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.bind-inviter-body {
|
||||
padding: 40rpx 30rpx 50rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.bind-desc {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.input-wrapper {
|
||||
width: 100%;
|
||||
background: #F5F7FA;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
margin-bottom: 50rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #EBEEF5;
|
||||
}
|
||||
.invite-code-input {
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
height: 48rpx;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
.bind-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: linear-gradient(135deg, #FF6B00 0%, #FF9500 100%);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
.bind-btn:active {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||
@keyframes zoomIn { from { transform: scale(0.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }
|
||||
</style>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
const BASE_URL = 'https://kdy.1024tool.vip'
|
||||
const BASE_URL = 'http://127.0.0.1:9991'
|
||||
|
||||
let authModalShown = false
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user