新增了抖音登录,区分不同场景的登录

This commit is contained in:
tsui110 2026-01-02 11:36:26 +08:00
parent e24f05f6ac
commit 8237e3ef42
2 changed files with 153 additions and 33 deletions

View File

@ -5,6 +5,12 @@ export function wechatLogin(code, invite_code) {
return request({ url: '/api/app/users/weixin/login', method: 'POST', data })
}
// 抖音小程序登录
export function toutiaoLogin(code, invite_code) {
const data = invite_code ? { code, invite_code } : { code }
return request({ url: '/api/app/users/toutiao/login', method: 'POST', data })
}
// ============================================
// 短信登录 API
// ============================================

View File

@ -17,13 +17,24 @@
<view class="login-card glass-card">
<!-- 切换Tab -->
<view class="tab-bar">
<!-- #ifdef MP-WEIXIN -->
<view
class="tab-item"
:class="{ active: loginMode === 'wechat' }"
@tap="switchMode('wechat')"
>
<text class="tab-text">手机号快捷登录</text>
<text class="tab-text">微信快捷登录</text>
</view>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<view
class="tab-item"
:class="{ active: loginMode === 'toutiao' }"
@tap="switchMode('toutiao')"
>
<text class="tab-text">抖音快捷登录</text>
</view>
<!-- #endif -->
<view
class="tab-item"
:class="{ active: loginMode === 'sms' }"
@ -37,6 +48,7 @@
<!-- 内容区域 -->
<view class="content-area">
<!-- 微信登录 -->
<!-- #ifdef MP-WEIXIN -->
<view v-if="loginMode === 'wechat'" class="login-panel wechat-panel">
<view class="panel-icon-wrap">
<view class="panel-icon wechat-icon">
@ -46,7 +58,6 @@
<text class="panel-title">一键获取手机号</text>
<text class="panel-desc">授权获取本机手机号安全快速登录</text>
<!-- #ifdef MP-WEIXIN -->
<button
class="btn-primary btn-login"
open-type="getPhoneNumber"
@ -55,14 +66,30 @@
>
{{ loading ? '获取中...' : '一键获取手机号' }}
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="btn-primary btn-login" disabled>
当前环境不支持
</button>
<!-- #endif -->
</view>
<!-- #endif -->
<!-- 抖音登录 -->
<!-- #ifdef MP-TOUTIAO -->
<view v-if="loginMode === 'toutiao'" class="login-panel toutiao-panel">
<view class="panel-icon-wrap">
<view class="panel-icon toutiao-icon">
<text class="icon-emoji">🎵</text>
</view>
</view>
<text class="panel-title">一键获取手机号</text>
<text class="panel-desc">授权获取本机手机号安全快速登录</text>
<button
class="btn-primary btn-login"
open-type="getPhoneNumber"
:disabled="loading"
@getphonenumber="onToutiaoGetPhoneNumber"
>
{{ loading ? '获取中...' : '一键获取手机号' }}
</button>
</view>
<!-- #endif -->
<!-- 短信登录 -->
<view v-else class="login-panel sms-panel">
@ -148,14 +175,22 @@
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { request } from '../../utils/request'
import { wechatLogin, bindPhone, getUserStats, getPointsBalance, sendSmsCode, smsLogin } from '../../api/appUser'
import { wechatLogin, toutiaoLogin, bindPhone, getUserStats, getPointsBalance, sendSmsCode, smsLogin } from '../../api/appUser'
import { vibrateShort } from '@/utils/vibrate.js'
const loading = ref(false)
const agreementChecked = ref(false)
//
//
// #ifdef MP-WEIXIN
const loginMode = ref('wechat')
// #endif
// #ifdef MP-TOUTIAO
const loginMode = ref('toutiao')
// #endif
// #ifndef MP-WEIXIN || MP-TOUTIAO
const loginMode = ref('sms')
// #endif
// OpenID
async function ensureOpenID() {
@ -163,6 +198,8 @@ async function ensureOpenID() {
if (current) return
console.log('[DEBUG] 本地缺少 openid, 尝试静默获取...')
// #ifdef MP-WEIXIN
uni.login({
provider: 'weixin',
success: async (loginRes) => {
@ -181,6 +218,28 @@ async function ensureOpenID() {
}
}
})
// #endif
// #ifdef MP-TOUTIAO
uni.login({
provider: 'toutiao',
success: async (loginRes) => {
try {
const res = await request({
url: '/api/app/common/openid',
method: 'POST',
data: { code: loginRes.code, platform: 'toutiao' }
})
if (res && res.openid) {
console.log('[DEBUG] 静默获取 openid 成功:', res.openid)
uni.setStorageSync('openid', res.openid)
}
} catch (err) {
console.error('[DEBUG] 静默获取 openid 失败:', err)
}
}
})
// #endif
}
onLoad(() => {
@ -362,6 +421,56 @@ function onGetPhoneNumber(e) {
})
}
//
function onToutiaoGetPhoneNumber(e) {
if (!agreementChecked.value) {
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
vibrateShort()
return
}
const phoneCode = e.detail.code
if (!phoneCode) {
uni.showToast({ title: '需要授权手机号', icon: 'none' })
return
}
loading.value = true
uni.login({
provider: 'toutiao',
success: async (res) => {
try {
const inviterCode = uni.getStorageSync('inviter_code')
const data = await toutiaoLogin(res.code, inviterCode)
saveUserData(data)
// ()
const isBound = data.phone || data.phone_number || data.mobile
if (!isBound) {
try {
await bindPhone(data.user_id, phoneCode)
} catch (e) {}
}
//
fetchExtraData(data.user_id)
uni.showToast({ title: '✨ 登录成功!', icon: 'none', duration: 1200 })
setTimeout(() => uni.reLaunch({ url: '/pages/mine/index' }), 600)
} catch (err) {
uni.showToast({ title: err.message || '登录失败', icon: 'none' })
} finally {
loading.value = false
}
},
fail: () => {
loading.value = false
}
})
}
function saveUserData(data) {
if (!data) return
console.log('[DEBUG] 准备执行 saveUserData, payload:', data)
@ -545,6 +654,11 @@ function fetchExtraData(userId) {
box-shadow: 0 12rpx 32rpx rgba(7, 193, 96, 0.3);
}
&.toutiao-icon {
background: linear-gradient(135deg, #000000 0%, #1a1a1a 100%);
box-shadow: 0 12rpx 32rpx rgba(0, 0, 0, 0.3);
}
.icon-emoji {
font-size: 56rpx;
}