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

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 }) 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 // 短信登录 API
// ============================================ // ============================================

View File

@ -17,13 +17,24 @@
<view class="login-card glass-card"> <view class="login-card glass-card">
<!-- 切换Tab --> <!-- 切换Tab -->
<view class="tab-bar"> <view class="tab-bar">
<!-- #ifdef MP-WEIXIN -->
<view <view
class="tab-item" class="tab-item"
:class="{ active: loginMode === 'wechat' }" :class="{ active: loginMode === 'wechat' }"
@tap="switchMode('wechat')" @tap="switchMode('wechat')"
> >
<text class="tab-text">手机号快捷登录</text> <text class="tab-text">微信快捷登录</text>
</view> </view>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<view
class="tab-item"
:class="{ active: loginMode === 'toutiao' }"
@tap="switchMode('toutiao')"
>
<text class="tab-text">抖音快捷登录</text>
</view>
<!-- #endif -->
<view <view
class="tab-item" class="tab-item"
:class="{ active: loginMode === 'sms' }" :class="{ active: loginMode === 'sms' }"
@ -37,6 +48,7 @@
<!-- 内容区域 --> <!-- 内容区域 -->
<view class="content-area"> <view class="content-area">
<!-- 微信登录 --> <!-- 微信登录 -->
<!-- #ifdef MP-WEIXIN -->
<view v-if="loginMode === 'wechat'" class="login-panel wechat-panel"> <view v-if="loginMode === 'wechat'" class="login-panel wechat-panel">
<view class="panel-icon-wrap"> <view class="panel-icon-wrap">
<view class="panel-icon wechat-icon"> <view class="panel-icon wechat-icon">
@ -46,7 +58,6 @@
<text class="panel-title">一键获取手机号</text> <text class="panel-title">一键获取手机号</text>
<text class="panel-desc">授权获取本机手机号安全快速登录</text> <text class="panel-desc">授权获取本机手机号安全快速登录</text>
<!-- #ifdef MP-WEIXIN -->
<button <button
class="btn-primary btn-login" class="btn-primary btn-login"
open-type="getPhoneNumber" open-type="getPhoneNumber"
@ -55,14 +66,30 @@
> >
{{ loading ? '获取中...' : '一键获取手机号' }} {{ loading ? '获取中...' : '一键获取手机号' }}
</button> </button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="btn-primary btn-login" disabled>
当前环境不支持
</button>
<!-- #endif -->
</view> </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"> <view v-else class="login-panel sms-panel">
@ -148,14 +175,22 @@
import { ref, computed, onMounted, onUnmounted } from 'vue' import { ref, computed, onMounted, onUnmounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { request } from '../../utils/request' 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' import { vibrateShort } from '@/utils/vibrate.js'
const loading = ref(false) const loading = ref(false)
const agreementChecked = ref(false) const agreementChecked = ref(false)
// //
// #ifdef MP-WEIXIN
const loginMode = ref('wechat') const loginMode = ref('wechat')
// #endif
// #ifdef MP-TOUTIAO
const loginMode = ref('toutiao')
// #endif
// #ifndef MP-WEIXIN || MP-TOUTIAO
const loginMode = ref('sms')
// #endif
// OpenID // OpenID
async function ensureOpenID() { async function ensureOpenID() {
@ -163,6 +198,8 @@ async function ensureOpenID() {
if (current) return if (current) return
console.log('[DEBUG] 本地缺少 openid, 尝试静默获取...') console.log('[DEBUG] 本地缺少 openid, 尝试静默获取...')
// #ifdef MP-WEIXIN
uni.login({ uni.login({
provider: 'weixin', provider: 'weixin',
success: async (loginRes) => { 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(() => { 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) { function saveUserData(data) {
if (!data) return if (!data) return
console.log('[DEBUG] 准备执行 saveUserData, payload:', data) console.log('[DEBUG] 准备执行 saveUserData, payload:', data)
@ -545,6 +654,11 @@ function fetchExtraData(userId) {
box-shadow: 0 12rpx 32rpx rgba(7, 193, 96, 0.3); 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 { .icon-emoji {
font-size: 56rpx; font-size: 56rpx;
} }