import { getPageStyle } from '@/utils/page-style' import { View, Text, Button, Checkbox, CheckboxGroup, Image } from '@tarojs/components' import { useEffect, useState } from 'react' import Taro from '@tarojs/taro' import { getToken, wechatLogin } from '@/services/auth' import './index.scss' const LOGIN_PAGE_URL = '/pages/login/index' const DEFAULT_POST_LOGIN_URL = '/pages/device/index' const TAB_BAR_ROUTES = new Set([ '/pages/device/index', '/pages/chat/index', '/pages/location/index', '/pages/sleep/index', ]) function consumePostLoginRedirect(): string { const storedUrl = String(Taro.getStorageSync('postLoginRedirect') || '').trim() Taro.removeStorageSync('postLoginRedirect') if (!storedUrl || storedUrl === LOGIN_PAGE_URL || !storedUrl.startsWith('/pages/')) { return DEFAULT_POST_LOGIN_URL } return storedUrl } function navigateAfterLogin(url: string): void { const route = url.split('?')[0] if (!TAB_BAR_ROUTES.has(route)) { Taro.reLaunch({ url }) return } // Tab pages must be opened with switchTab so their lifecycle and custom tab bar refresh. void Promise.resolve(Taro.switchTab({ url: route })).catch(() => { Taro.reLaunch({ url: route }) }) } export default function Login() { const [submitting, setSubmitting] = useState(false) const [agreementAccepted, setAgreementAccepted] = useState(false) useEffect(() => { if (getToken()) { navigateAfterLogin(consumePostLoginRedirect()) return } }, []) const handleLogin = async () => { if (submitting) return if (!agreementAccepted) { Taro.showToast({ title: '请先阅读并同意协议', icon: 'none', }) return } setSubmitting(true) Taro.showLoading({ title: '登录中...' }) try { const loginRes = await Taro.login() if (!loginRes.code) { throw new Error('未获取到微信登录凭证') } const session = await wechatLogin({ code: loginRes.code, }) const nextUserInfo = { nickname: session.nickname || '', } if (nextUserInfo.nickname) { Taro.setStorageSync('userInfo', { nickname: nextUserInfo.nickname, }) } else { Taro.removeStorageSync('userInfo') } Taro.showToast({ title: '登录成功', icon: 'success' }) setTimeout(() => { navigateAfterLogin(consumePostLoginRedirect()) }, 300) } catch (error: any) { console.error('[login] failed:', error) const message = String(error?.message || '登录失败,请重试') Taro.showModal({ title: '登录失败', content: message, showCancel: false, }) } finally { Taro.hideLoading() setSubmitting(false) } } const handleGuestBrowse = () => { Taro.removeStorageSync('postLoginRedirect') Taro.reLaunch({ url: '/pages/device/index' }) } const handleAgreementChange = (event) => { const values = event.detail.value || [] setAgreementAccepted(values.includes('accepted')) } const openUserAgreement = () => { Taro.showModal({ title: '用户服务协议', content: '欢迎使用伴伴。您在使用本小程序前,应阅读并同意本协议。我们将为您提供设备绑定、状态查看、消息互动、定位展示等服务。请您遵守法律法规,不得利用本服务从事违法或侵犯他人权益的行为。', showCancel: false, confirmText: '我知道了', }) } const openPrivacyPolicy = () => { const taroWithPrivacy = Taro as typeof Taro & { openPrivacyContract?: (option?: { success?: () => void fail?: (error: unknown) => void }) => void } if (typeof taroWithPrivacy.openPrivacyContract === 'function') { taroWithPrivacy.openPrivacyContract({ fail: () => { Taro.showModal({ title: '隐私政策', content: '暂时无法打开隐私保护指引,请稍后重试。', showCancel: false, confirmText: '我知道了', }) }, }) return } Taro.showModal({ title: '隐私政策', content: '伴伴会在提供设备绑定、消息互动、定位展示等功能时,按需处理您的账号信息、设备信息和位置信息。我们仅在实现相关功能所必需的范围内使用上述信息。', showCancel: false, confirmText: '我知道了', }) } return ( 伴伴 让关爱随时随地 AI 智能对话 实时定位追踪 设备状态监控 登录后启用设备管理 仅在绑定设备、查看定位和管理宝贝资料时需要登录。 暂不登录,先浏览 我已阅读并同意 《用户服务协议》 和 《隐私政策》 ) }