| | |
| | | </div> |
| | | |
| | | <button class="login-btn" :style="[inputStyle]" @tap="submit">登录</button> |
| | | <image class="lowerRightCorner" :src="droneSvg" /> |
| | | <button class="wechat-login-btn" @tap="wechatLogin">微信登录</button> |
| | | |
| | | <view class="agreement"> |
| | | <label> |
| | | <checkbox :checked="agreed" @click="agreed = !agreed" /> |
| | | 同意《用户协议》与《隐私政策》 |
| | | </label> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | import { useUserStore } from "@/store/index.js"; |
| | | |
| | | import { HOME_PATH, LOGIN_PATH, removeQueryString } from "@/router"; |
| | | import { onMounted } from "vue"; |
| | | import { ref } from "vue"; |
| | | |
| | | import logoSvg from "@/static/images/logo.svg"; |
| | | import showPasswordSvg from "@/static/images/show-password.svg"; |
| | |
| | | const usernameSvg = getAssetsImage("/images/login/username.svg"); |
| | | const passwordSvg = getAssetsImage("/images/login/password.svg"); |
| | | // const logoSvg = getAssetsImage("/images/login/logo.svg"); |
| | | |
| | | const agreed = ref(true); |
| | | |
| | | const userStore = useUserStore(); |
| | | const loginForm = ref({ |
| | |
| | | ); |
| | | userStore.setUserInfo(res.data); |
| | | uni.reLaunch({ |
| | | url: "/pages/map/index", |
| | | url: "/pages/page/index", |
| | | }); |
| | | } catch (error) { |
| | | const errorMsg = |
| | |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // 核心登录函数 |
| | | const wechatLogin = async () => { |
| | | // 1. 协议检查 |
| | | if (!agreed.value) { |
| | | uni.showToast({ title: '请先同意协议', icon: 'none' }); |
| | | return; |
| | | } |
| | | |
| | | // loading.value = true; |
| | | |
| | | try { |
| | | // 2. 获取登录凭证 (code) |
| | | const loginRes = await uni.login({ |
| | | provider: 'weixin', |
| | | timeout: 10000 |
| | | }); |
| | | |
| | | if (!loginRes.code) { |
| | | throw new Error('获取登录码失败'); |
| | | } |
| | | console.log('获取到code:', loginRes.code); |
| | | |
| | | // 3. 获取用户信息 (需要用户授权弹窗) |
| | | const userProfileRes = await uni.getUserProfile({ |
| | | desc: '用于完善您的会员信息', // 声明用途,会展示给用户 |
| | | lang: 'zh_CN' |
| | | }); |
| | | |
| | | console.log('用户信息:', userProfileRes.userInfo); |
| | | |
| | | // 4. 调用后端登录接口 |
| | | const serverRes = await uni.request({ |
| | | // url: 'https://你的域名.com/api/wx-login', // 替换为你的真实接口 |
| | | // method: 'POST', |
| | | // data: { |
| | | // code: loginRes.code, |
| | | // rawData: userProfileRes.rawData, |
| | | // signature: userProfileRes.signature, |
| | | // encryptedData: userProfileRes.encryptedData, |
| | | // iv: userProfileRes.iv, |
| | | // userInfo: userProfileRes.userInfo // 注意:userInfo 仅为昵称头像等非敏感信息 |
| | | // }, |
| | | // header: { 'Content-Type': 'application/json' } |
| | | }); |
| | | |
| | | // 5. 处理登录结果 |
| | | const { data } = serverRes; |
| | | if (data.success && data.token) { |
| | | // 保存登录状态 |
| | | uni.setStorageSync('token', data.token); |
| | | uni.setStorageSync('userInfo', data.userInfo || userProfileRes.userInfo); |
| | | |
| | | uni.showToast({ title: '登录成功', icon: 'success' }); |
| | | |
| | | // 登录成功后的跳转逻辑 |
| | | const pages = getCurrentPages(); |
| | | if (pages.length > 1) { |
| | | uni.navigateBack(); |
| | | } else { |
| | | uni.switchTab({ url: '/pages/page/index' }); // 跳转到首页 |
| | | } |
| | | } else { |
| | | throw new Error(data.message || '登录失败'); |
| | | } |
| | | |
| | | } catch (error) { |
| | | console.error('登录全过程失败:', error); |
| | | uni.showToast({ |
| | | title: error.errMsg || error.message || '登录失败', |
| | | icon: 'none' |
| | | }); |
| | | } finally { |
| | | // loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // 从本地存储加载记住的密码 |
| | | onMounted(() => { |
| | |
| | | @apply border-none; |
| | | } |
| | | } |
| | | |
| | | .wechat-login-btn { |
| | | z-index: 1; |
| | | @apply flex items-center justify-center py-12rpx px-0 text-30rpx border-none; |
| | | background: #07C160; |
| | | color: white; |
| | | width: 590rpx; |
| | | height: 76rpx; |
| | | border-radius: 40rpx 40rpx 40rpx 40rpx; |
| | | margin-top: 30rpx; |
| | | |
| | | &::after { |
| | | @apply border-none; |
| | | } |
| | | } |
| | | |
| | | .alternative { |
| | | @apply flex justify-between mt-30rpx; |