Files

297 lines
6.1 KiB
Vue
Raw Normal View History

2023-11-14 17:21:03 +08:00
<!--
@name: 登录引导页
@author: kahu4
@date: 2023-11-08 16:20
@descriptionindex
@update: 2023-11-08 16:20
-->
<script setup>
import { loginLogoIcon, wechat } from "@/utils/images";
2023-11-14 17:21:03 +08:00
import { useRouter } from "@/hooks/useRouter";
import { loginMethods } from "@/pages/login/index.data";
2023-11-15 19:59:37 +08:00
import { wxLogin } from "@/utils/wechatUtils";
import { ref } from "vue";
2023-11-15 19:59:37 +08:00
import { useInterface } from "@/hooks/useInterface";
import { privacyAgreementUrl, userAgreementUrl, weixinLogin } from "@/api/auth";
2024-02-22 18:37:23 +08:00
import { useMainStore } from "@/store/modules/useMainStore";
2023-11-15 19:59:37 +08:00
import { afterLogin } from "@/utils";
2023-11-14 17:21:03 +08:00
2023-11-15 19:59:37 +08:00
const {toast, loading, hideLoading} = useInterface()
2023-11-14 17:21:03 +08:00
const {goBack, push} = useRouter()
2023-11-15 19:59:37 +08:00
const mainStore = useMainStore()
2023-11-14 17:21:03 +08:00
2023-11-15 19:59:37 +08:00
async function toLogin(loginMethod) {
push({url: '/pages/login/index', animationType: 'slide-in-right'}, {data: {...loginMethod}})
2023-11-15 19:59:37 +08:00
}
// ============================= 微信登录相关
const code = ref('') // logingCode必须比getPhoneNumber的code先获取
async function getCode() {
loading({
title: '登陆中...'
})
try {
code.value = await wxLogin();
} catch (e) {
console.error(e)
toast('获取code失败')
hideLoading()
}
}
async function getPhoneNumber(e) {
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
console.error(e)
hideLoading()
toast({title: '登录失败'})
}
try {
const phoneCode = e.detail.code
const res = await weixinLogin({
phoneCode,
loginCode: code.value
});
if (res) {
await mainStore.setAccessToken(res)
await mainStore.getUserInfo()
2023-11-15 19:59:37 +08:00
afterLogin()
}
} catch (e) {
console.error(e)
toast({title: '登录失败'})
} finally {
hideLoading()
}
}
const privacyPolicy = ref([]) // 协议双向绑定
const isPrivacyError = ref(false) // 未勾选协议
/**
* 检查是否勾选协议
* @returns {boolean}
*/
function checkPrivacy() {
const flag = privacyPolicy.value.length > 0
if (!flag) {
toast({title: '请先阅读并同意用户协议和隐私政策'})
isPrivacyError.value = true
setTimeout(() => {
isPrivacyError.value = false
}, 1000)
2023-11-14 17:21:03 +08:00
}
2023-11-15 19:59:37 +08:00
return flag
}
/**
* 跳转协议
* @param type
*/
function toAgreement(type) {
const urls = [userAgreementUrl, privacyAgreementUrl]
push({url: '/pages/webview/index'}, {data: {src: urls[type]}})
2023-11-14 17:21:03 +08:00
}
2023-11-15 19:59:37 +08:00
2023-11-14 17:21:03 +08:00
</script>
<template>
<view class="login-guid">
<uv-navbar
:fixed="false"
title="登录"
left-arrow
@leftClick="goBack"
/>
<view class="main-box flex flex-jc__center">
<image
class="logo"
2023-11-22 18:55:55 +08:00
:src="loginLogoIcon"
2023-11-14 17:21:03 +08:00
/>
</view>
<view class="button-group">
2023-11-15 19:59:37 +08:00
<!-- #ifdef MP-WEIXIN -->
<view
v-if="privacyPolicy.length<=0"
class="button animation-button disabled"
@click="checkPrivacy"
>
2024-02-22 18:37:23 +08:00
<!-- <image-->
<!-- class="icon"-->
<!-- :src="wechat"-->
<!-- />-->
一键登录
2023-11-15 19:59:37 +08:00
</view>
<button
v-else
class="button animation-button"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
@click="getCode"
>
2024-02-22 18:37:23 +08:00
<!-- <image-->
<!-- class="icon"-->
<!-- :src="wechat"-->
<!-- />-->
一键登录
2023-11-15 19:59:37 +08:00
</button>
<!-- #endif -->
2023-11-14 17:21:03 +08:00
<template
v-for="(loginMethod) in loginMethods"
:key="loginMethod.type"
>
<view
:class="`button animation-button ${loginMethod.classNames.join(' ')}`"
@click="toLogin(loginMethod)"
>
<image
class="icon"
:src="loginMethod.icon"
/>
{{ loginMethod.label }}
</view>
</template>
</view>
2023-11-17 20:55:32 +08:00
<!-- #ifdef MP-WEIXIN -->
2023-11-15 19:59:37 +08:00
<view
class="agreement-box"
:class="{'error-animation':isPrivacyError}"
>
<uv-checkbox-group
v-model="privacyPolicy"
shape="circle"
activeColor="#ec6e47"
>
<uv-checkbox :name="1">
<view class="agreement-text">
阅读并同意
<span
class="color"
@click="toAgreement(0)"
>
YSHOP商城用户协议
</span>
<span
class="color"
@click="toAgreement(1)"
>
YSHOP商城隐私协议
</span>
</view>
</uv-checkbox>
</uv-checkbox-group>
2023-11-14 17:21:03 +08:00
</view>
2023-11-17 20:55:32 +08:00
<!-- #endif -->
2023-11-14 17:21:03 +08:00
</view>
</template>
<style
scoped
lang="scss"
>
.login-guid {
width: 100%;
height: 100vh;
background: $white-color;
.main-box {
width: 100%;
top: 300rpx;
position: absolute;
.logo {
width: 255rpx;
height: 96rpx;
}
}
.button-group {
@include usePadding(50, 0);
width: 100%;
font-size: 28rpx;
position: absolute;
bottom: 20%;
.button {
width: 100%;
margin-bottom: 30rpx;
display: flex;
align-items: center;
justify-content: center;
height: 88rpx;
2023-11-17 20:55:32 +08:00
font-size: 28rpx;
border-radius: 0;
2023-11-14 17:21:03 +08:00
.icon {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
}
.white-button {
background: $white-color;
border: 1rpx solid #333;
color: #333;
}
}
2023-11-15 19:59:37 +08:00
}
.agreement-box {
@include usePadding(30, 0);
position: fixed;
bottom: 5%;
width: 100%;
font-size: 24rpx;
color: $tips-color;
transition: all .3s;
.agreement-text {
2023-11-14 17:21:03 +08:00
text-align: center;
2023-11-15 19:59:37 +08:00
.color {
color: $primary-color;
}
}
:deep(.uv-checkbox ) {
width: 100%;
align-items: flex-start;
.uv-checkbox__icon-wrap {
}
}
}
.error-animation {
animation: error-text 0.8s 1;
}
@keyframes error-text {
0% {
transform: translateX(0);
}
5%, 25%, 45%, 65%, 85% {
transform: translateX(-10rpx);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(10rpx);
}
15%, 35%, 55%, 75%, 95% {
transform: translateX(20rpx);
}
20%, 40%, 60%, 80%, 100% {
transform: translateX(-20rpx);
2023-11-14 17:21:03 +08:00
}
}
</style>