Files
2024-02-22 18:37:23 +08:00

297 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
@name: 登录引导页
@author: kahu4
@date: 2023-11-08 16:20
@descriptionindex
@update: 2023-11-08 16:20
-->
<script setup>
import { loginLogoIcon, wechat } from "@/utils/images";
import { useRouter } from "@/hooks/useRouter";
import { loginMethods } from "@/pages/login/index.data";
import { wxLogin } from "@/utils/wechatUtils";
import { ref } from "vue";
import { useInterface } from "@/hooks/useInterface";
import { privacyAgreementUrl, userAgreementUrl, weixinLogin } from "@/api/auth";
import { useMainStore } from "@/store/modules/useMainStore";
import { afterLogin } from "@/utils";
const {toast, loading, hideLoading} = useInterface()
const {goBack, push} = useRouter()
const mainStore = useMainStore()
async function toLogin(loginMethod) {
push({url: '/pages/login/index', animationType: 'slide-in-right'}, {data: {...loginMethod}})
}
// ============================= 微信登录相关
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()
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)
}
return flag
}
/**
* 跳转协议
* @param type
*/
function toAgreement(type) {
const urls = [userAgreementUrl, privacyAgreementUrl]
push({url: '/pages/webview/index'}, {data: {src: urls[type]}})
}
</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"
:src="loginLogoIcon"
/>
</view>
<view class="button-group">
<!-- #ifdef MP-WEIXIN -->
<view
v-if="privacyPolicy.length<=0"
class="button animation-button disabled"
@click="checkPrivacy"
>
<!-- <image-->
<!-- class="icon"-->
<!-- :src="wechat"-->
<!-- />-->
一键登录
</view>
<button
v-else
class="button animation-button"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
@click="getCode"
>
<!-- <image-->
<!-- class="icon"-->
<!-- :src="wechat"-->
<!-- />-->
一键登录
</button>
<!-- #endif -->
<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>
<!-- #ifdef MP-WEIXIN -->
<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>
</view>
<!-- #endif -->
</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;
font-size: 28rpx;
border-radius: 0;
.icon {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
}
.white-button {
background: $white-color;
border: 1rpx solid #333;
color: #333;
}
}
}
.agreement-box {
@include usePadding(30, 0);
position: fixed;
bottom: 5%;
width: 100%;
font-size: 24rpx;
color: $tips-color;
transition: all .3s;
.agreement-text {
text-align: center;
.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);
}
}
</style>