| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- import { View, Text } from '@tarojs/components'
- import { useState, useEffect } from 'react'
- import Taro from '@tarojs/taro'
- import { cn } from '@/utils/cn'
- import Navbar from '@/components/ui/navbar'
- import { isWeapp } from '@/utils/platform'
- import { Button } from '@/components/ui/button'
- export default function WechatLogin() {
- const [loading, setLoading] = useState(false)
- const [isWechatEnv, setIsWechatEnv] = useState(true)
- // 设置导航栏标题并检查平台
- useEffect(() => {
- Taro.setNavigationBarTitle({
- title: '微信登录'
- })
-
- // 检查是否为微信小程序环境
- const wechatEnv = isWeapp()
- setIsWechatEnv(wechatEnv)
-
- // 如果不是微信小程序,显示提示并延迟跳转
- if (!wechatEnv) {
- Taro.showModal({
- title: '提示',
- content: '微信登录功能仅支持在微信小程序中使用',
- showCancel: false,
- confirmText: '返回',
- success: () => {
- setTimeout(() => {
- Taro.navigateBack()
- }, 500)
- }
- })
- }
- }, [])
- const handleWechatLogin = async () => {
- setLoading(true)
-
- try {
- Taro.showLoading({
- title: '登录中...',
- mask: true
- })
- // 1. 获取用户信息授权
- const userProfile = await Taro.getUserProfile({
- desc: '用于完善用户资料'
- }).catch(err => {
- if (err.errMsg.includes('deny') || err.errMsg.includes('cancel')) {
- throw new Error('用户拒绝授权')
- }
- throw err
- })
- // 2. 获取登录code
- const loginRes = await Taro.login()
-
- if (!loginRes.code) {
- throw new Error('获取登录凭证失败')
- }
- // 3. 调用后端小程序登录API
- const response = await Taro.request({
- url: `${process.env.API_BASE_URL || ''}/api/v1/auth/mini-login`,
- method: 'POST',
- data: {
- code: loginRes.code,
- userInfo: userProfile.userInfo
- },
- header: {
- 'Content-Type': 'application/json'
- }
- })
- Taro.hideLoading()
- if (response.statusCode === 200) {
- const { token, user, isNewUser } = response.data
-
- // 4. 保存token和用户信息
- Taro.setStorageSync('token', token)
- Taro.setStorageSync('userInfo', user)
-
- Taro.showToast({
- title: isNewUser ? '注册成功' : '登录成功',
- icon: 'success',
- duration: 1500
- })
-
- // 跳转到首页
- setTimeout(() => {
- Taro.switchTab({ url: '/pages/index/index' })
- }, 1500)
- } else {
- throw new Error(response.data.message || '登录失败')
- }
- } catch (error: any) {
- Taro.hideLoading()
-
- const errorMessage = error.message || '登录失败'
-
- if (errorMessage.includes('用户拒绝授权')) {
- Taro.showModal({
- title: '提示',
- content: '需要授权才能使用小程序的全部功能',
- showCancel: false,
- confirmText: '知道了'
- })
- } else if (errorMessage.includes('网络')) {
- Taro.showModal({
- title: '网络错误',
- content: '请检查网络连接后重试',
- showCancel: false,
- confirmText: '确定'
- })
- } else {
- Taro.showToast({
- title: errorMessage,
- icon: 'none',
- duration: 3000
- })
- }
- } finally {
- setLoading(false)
- }
- }
- const goToAccountLogin = () => {
- Taro.navigateBack()
- }
- return (
- <View className="min-h-screen bg-gradient-to-br from-green-50 via-white to-blue-50">
- <Navbar
- title="微信登录"
- backgroundColor="bg-transparent"
- textColor="text-gray-900"
- border={false}
- />
-
- {!isWechatEnv ? (
- <View className="flex-1 flex items-center justify-center px-6">
- <View className="flex flex-col items-center">
- <View className="i-heroicons-exclamation-triangle-20-solid w-16 h-16 text-orange-500 mx-auto mb-4" />
- <Text className="text-lg font-semibold text-gray-900 mb-2">当前环境不支持</Text>
- <Text className="text-sm text-gray-600 mb-6">
- 微信登录功能仅支持在微信小程序中使用
- </Text>
- <Button
- className="w-full max-w-xs"
- size="lg"
- variant="default"
- onClick={goToAccountLogin}
- >
- <View className="i-heroicons-arrow-left-20-solid w-4 h-4 mr-2" />
- 返回账号登录
- </Button>
- </View>
- </View>
- ) : (
- <View className="flex-1 px-6 py-12">
- {/* Logo区域 */}
- <View className="flex flex-col items-center mb-10">
- <View className="w-20 h-20 mb-4 rounded-full bg-green-100 flex items-center justify-center">
- <View className="i-heroicons-chat-bubble-left-right-20-solid w-12 h-12 text-green-500" />
- </View>
- <Text className="text-2xl font-bold text-gray-900 mb-2">微信一键登录</Text>
- <Text className="text-gray-600 text-sm">便捷登录,无需输入账号密码</Text>
- </View>
- {/* 功能介绍 */}
- <View className="bg-white rounded-2xl shadow-sm p-6 mb-8">
- <Text className="text-lg font-semibold text-gray-900 mb-4">登录后您将享受</Text>
-
- <View className="space-y-3">
- <View className="flex items-center">
- <View className="w-2 h-2 bg-green-500 rounded-full mr-3" />
- <Text className="text-sm text-gray-700">数据云端同步</Text>
- </View>
- <View className="flex items-center">
- <View className="w-2 h-2 bg-green-500 rounded-full mr-3" />
- <Text className="text-sm text-gray-700">个性化推荐</Text>
- </View>
- <View className="flex items-center">
- <View className="w-2 h-2 bg-green-500 rounded-full mr-3" />
- <Text className="text-sm text-gray-700">多端数据共享</Text>
- </View>
- <View className="flex items-center">
- <View className="w-2 h-2 bg-green-500 rounded-full mr-3" />
- <Text className="text-sm text-gray-700">专属会员权益</Text>
- </View>
- </View>
- </View>
- {/* 微信登录按钮 */}
- <View className="space-y-4">
- <Button
- className={cn(
- "w-full",
- "bg-green-500 text-white hover:bg-green-600",
- "border-none"
- )}
- size="lg"
- variant="default"
- onClick={handleWechatLogin}
- disabled={loading || !isWechatEnv}
- loading={loading}
- >
- <View className="i-heroicons-chat-bubble-left-right-20-solid w-5 h-5 mr-2" />
- {loading ? '登录中...' : '微信一键登录'}
- </Button>
- <Button
- className="w-full"
- size="lg"
- variant="outline"
- onClick={goToAccountLogin}
- >
- <View className="i-heroicons-arrow-left-20-solid w-4 h-4 mr-2" />
- 使用账号密码登录
- </Button>
- </View>
- {/* 隐私声明 */}
- <View className="mt-8 text-center">
- <Text className="text-xs text-gray-500 leading-relaxed">
- 点击"微信一键登录"即表示您同意
- <Text className="text-blue-500">《用户协议》</Text>
- 和
- <Text className="text-blue-500">《隐私政策》</Text>
- </Text>
- <Text className="text-xs text-gray-400 mt-2">
- 我们将严格保护您的个人信息安全
- </Text>
- </View>
- </View>
- )}
- </View>
- )
- }
|