feat: 添加抖音订单绑定功能并改进RPC日志。
This commit is contained in:
parent
bcbb18a939
commit
237d785a4f
@ -372,3 +372,10 @@ export function purchaseGamePass(package_id, count = 1) {
|
||||
return authRequest({ url: '/api/app/game-passes/purchase', method: 'POST', data: { package_id, count } })
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定抖音订单获取抖音用户ID
|
||||
* @param {string} shop_order_id - 抖音订单号
|
||||
*/
|
||||
export function bindDouyinOrder(order_id) {
|
||||
return authRequest({ url: '/api/app/users/douyin/bind-order', method: 'POST', data: { order_id } })
|
||||
}
|
||||
|
||||
@ -181,6 +181,12 @@
|
||||
</view>
|
||||
<text class="menu-label">帮助中心</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="toBindDouyinOrder">
|
||||
<view class="menu-icon-box">
|
||||
<image class="menu-icon-img" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDExVjlhMyAzIDAgMCAxIDMtM2g0YTMgMyAwIDAgMSAzIDN2Mm0tMTAtM2gtNGEzIDMgMCAwIDAtMyAzdi04YTIgMiAwIDAgMSAyLTJoMTRhMiAyIDAgMCAxIDIgMnY4YTIgMiAwIDAgMS0yIDJoLTRhMyAzIDAgMCAxLTMtM3oiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjEzIiByPSIzIi8+PC9zdmc+" mode="aspectFit"></image>
|
||||
</view>
|
||||
<text class="menu-label">{{ douyinUserId ? '已绑定' : '绑定订单' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -468,7 +474,7 @@
|
||||
<script>
|
||||
import {
|
||||
getUserInfo, getUserStats, getPointsBalance, getUserPoints, getUserCoupons, getItemCards,
|
||||
getUserTasks, getTaskProgress, getInviteRecords, modifyUser, getUserProfile
|
||||
getUserTasks, getTaskProgress, getInviteRecords, modifyUser, getUserProfile, bindDouyinOrder
|
||||
} from '../../api/appUser.js'
|
||||
import { checkPhoneBoundSync } from '../../utils/checkPhone.js'
|
||||
|
||||
@ -481,6 +487,7 @@ export default {
|
||||
title: '', // 用户头衔
|
||||
inviteCode: '',
|
||||
mobile: '', // 手机号
|
||||
douyinUserId: '', // 抖音用户ID
|
||||
pointsBalance: 0,
|
||||
|
||||
stats: {
|
||||
@ -792,6 +799,7 @@ export default {
|
||||
this.inviteCode = profile.invite_code
|
||||
this.pointsBalance = this.normalizePointsBalance(profile.balance)
|
||||
this.mobile = profile.mobile || ''
|
||||
this.douyinUserId = profile.douyin_user_id || ''
|
||||
|
||||
// 更新缓存
|
||||
const cachedUser = uni.getStorageSync('user_info') || {}
|
||||
@ -831,6 +839,7 @@ export default {
|
||||
this.title = cachedUser.title || ''
|
||||
this.pointsBalance = this.normalizePointsBalance(cachedUser.points_balance)
|
||||
this.mobile = cachedUser.mobile || cachedUser.phone || cachedUser.phone_number || ''
|
||||
this.douyinUserId = cachedUser.douyin_user_id || ''
|
||||
} else if (cachedUserId) {
|
||||
this.userId = cachedUserId
|
||||
}
|
||||
@ -860,6 +869,7 @@ export default {
|
||||
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)
|
||||
|
||||
@ -879,6 +889,7 @@ export default {
|
||||
this.avatar = ''
|
||||
this.title = ''
|
||||
this.pointsBalance = 0
|
||||
this.douyinUserId = ''
|
||||
this.stats = { coupon_count: 0, item_card_count: 0 }
|
||||
},
|
||||
handleJoin() {
|
||||
@ -933,6 +944,50 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
toBindDouyinOrder() {
|
||||
if (!this.checkPhoneBound()) return
|
||||
|
||||
// 检查是否已绑定
|
||||
if (this.douyinUserId) {
|
||||
uni.showToast({
|
||||
title: '您已绑定抖音账号,暂不支持换绑',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '绑定抖音订单',
|
||||
editable: true,
|
||||
placeholderText: '请输入抖音订单号',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
const orderId = res.content?.trim()
|
||||
if (!orderId) {
|
||||
uni.showToast({ title: '订单号不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
uni.showLoading({ title: '绑定中...' })
|
||||
const data = await bindDouyinOrder(orderId)
|
||||
this.douyinUserId = data.douyin_user_id
|
||||
|
||||
// 更新缓存
|
||||
const userInfo = uni.getStorageSync('user_info') || {}
|
||||
userInfo.douyin_user_id = data.douyin_user_id
|
||||
uni.setStorageSync('user_info', userInfo)
|
||||
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '绑定成功', icon: 'success' })
|
||||
} catch (err) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: err.message || '绑定失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleInvite() {
|
||||
const code = this.getInviteCode()
|
||||
const path = this.getInviteSharePath()
|
||||
|
||||
17
uni.scss
17
uni.scss
@ -192,7 +192,10 @@ $uni-font-size-paragraph: 15px;
|
||||
/* 1. 统一背景装饰 - 漂浮光球 */
|
||||
.bg-decoration {
|
||||
position: fixed;
|
||||
top: 0; left: 0; width: 100%; height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
@ -200,8 +203,10 @@ $uni-font-size-paragraph: 15px;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -100rpx; right: -100rpx;
|
||||
width: 600rpx; height: 600rpx;
|
||||
top: -100rpx;
|
||||
right: -100rpx;
|
||||
width: 600rpx;
|
||||
height: 600rpx;
|
||||
background: radial-gradient(circle, rgba($brand-primary, 0.15) 0%, transparent 70%);
|
||||
filter: blur(60rpx);
|
||||
border-radius: 50%;
|
||||
@ -212,8 +217,10 @@ $uni-font-size-paragraph: 15px;
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 200rpx; left: -200rpx;
|
||||
width: 500rpx; height: 500rpx;
|
||||
top: 200rpx;
|
||||
left: -200rpx;
|
||||
width: 500rpx;
|
||||
height: 500rpx;
|
||||
background: radial-gradient(circle, rgba($brand-secondary, 0.1) 0%, transparent 70%);
|
||||
filter: blur(50rpx);
|
||||
border-radius: 50%;
|
||||
|
||||
@ -361,9 +361,13 @@ class NakamaManager {
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[Nakama] RPC response:', id, response);
|
||||
|
||||
if (response.rpc && response.rpc.payload) {
|
||||
try {
|
||||
return JSON.parse(response.rpc.payload);
|
||||
const parsed = JSON.parse(response.rpc.payload);
|
||||
console.log('[Nakama] RPC parsed result:', id, parsed);
|
||||
return parsed;
|
||||
} catch (e) {
|
||||
return response.rpc.payload;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user