admission-uniapp/src/bundle/pages/login/login.vue

376 lines
10 KiB
Vue

<template>
<view class="login">
<view class="z-10">
<w-navbarComp title="登录" />
<view class="flex flex-col items-center justify-between w-full mt-[15%] mb-[40rpx]">
<u-image :src="logo" mode="widthFix" height="120" width="200" />
<!-- <view class="mt-10 text-[36rpx] font-medium">充电桩维护系统</view> -->
</view>
<view class="login-form">
<view class="item">
<view class="label">账号</view>
<u-input
placeholder="请输入账号"
border="bottom"
v-model="form.username"
prefixIcon="man-add"
></u-input>
</view>
<view class="item">
<view class="label">密码</view>
<u-input
placeholder="请输入密码"
border="bottom"
v-model="form.password"
prefixIcon="lock-open"
></u-input>
</view>
</view>
<view class="base">
<u-button
class="login-btn"
type="primary"
shape="circle"
color="#2759FF"
text="登录"
@click="accountLogin"
></u-button>
</view>
<view class="agreement" data-name="wrapper" @click="handleClickEmpty">
<u-checkbox-group v-model="checked" placement="row" shape="circle" size="28rpx">
<u-checkbox class="btn" label="已同意" name="agreement"></u-checkbox>
<view class="text">
<text class="strong" @click.stop="handleNavigate(AgreementEnum.SERVICE)">
《用户注册协议》
</text>
<text class="strong" @click.stop="handleNavigate(AgreementEnum.PRIVACY)">
《隐私协议》
</text>
</view>
</u-checkbox-group>
</view>
<view class="wx-login">
<view class="name">第三方登录</view>
<block v-if="!isChecked">
<u-button
class="btn"
type="success"
shape="circle"
color="#1cd66c"
text=""
icon="chat"
@click="handleAgreement"
></u-button>
</block>
<block v-else>
<u-button
class="btn"
type="success"
shape="circle"
color="#1cd66c"
text=""
icon="chat"
open-type="getPhoneNumber"
@getphonenumber="wxLogin"
></u-button>
</block>
</view>
</view>
<img src="@/static/images/bg.png" alt="" class="page-bg-img" />
</view>
</template>
<script setup lang="ts">
import { computed, ref, unref, watch } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useUserStore } from '@/stores/user'
import { useAppStore } from '@/stores/app'
import { login as isLogin } from '@/api/account'
import wechatOa from '@/utils/wechat'
import cache from '@/utils/cache'
import { navigateTo } from '@/utils/util'
import { AgreementEnum } from '@/enums/agreementEnums'
import { BACK_URL, ROLEINDEX } from '@/enums/cacheEnums'
import { ChannelEnum, LoginTypeEnum } from '@/enums/appEnums'
import logo from '@/static/images/logo.png'
import { setNextRoute } from '@/hooks/useRoleData'
import { getAllDict } from '@/hooks/useDictOptions'
const userStore = useUserStore()
const appStore = useAppStore()
const loginData = ref()
const checked = ref<string[]>([])
const isCheckAgreement = ref()
const wxLoginCode = ref()
const isChecked = computed(() => unref(checked).length > 0)
const form = ref({
username: '',
password: ''
})
/**协议跳转 */
const handleNavigate = (type: AgreementEnum) => {
navigateTo({ path: '/bundle/pages/agreement/index', query: { type } })
}
/**同意协议 */
const handleAgreement = () => {
uni.$u.toast('请勾选已阅读并同意《用户注册协议》和《隐私协议》')
}
/**手机授权(仅微信) */
const wxLogin = async e => {
if (e.detail.errMsg === 'getPhoneNumber:ok') {
try {
// #ifdef MP-WEIXIN
uni.showLoading({
title: '请稍后...'
})
uni.checkSession({
complete: result => {
handleLogin(e)
},
fail: err => {
console.log(err)
}
})
// #endif
} catch (error) {
uni.$u.toast(error)
}
} else {
return
}
}
onLoad(async options => {
if (userStore.isLogin) {
// 已经登录 => 首页
setNextRoute()
}
uni.login({
provider: 'weixin',
success: function (loginRes) {
// 用户code
wxLoginCode.value = loginRes.code
}
})
appStore.setFirstLogin(false)
// #ifdef H5
const { code } = options
if (code) {
uni.showLoading({
title: '请稍后...'
})
try {
const data = await wechatOa.authLogin(code)
loginHandle(data)
} catch (error: any) {
uni.hideLoading()
throw new Error(error)
}
}
// #endif
})
/**登录 */
async function handleLogin(e) {
// 获取登录code
const { code }: any = await uni.login({
provider: 'weixin'
})
// 调用登录接口
const data = await isLogin({
code,
scene: LoginTypeEnum.MNP,
iv: e.detail.iv,
encryptedData: e.detail.encryptedData,
channel: ChannelEnum.USER_PLATFORM
})
// 保存登录数据
loginData.value = data
// 登录处理
loginHandle(data)
}
async function accountLogin() {
if (!form.value.username) return uni.$u.toast('请输入账号')
else if (!form.value.password) return uni.$u.toast('请输入密码')
if (!unref(isChecked)) return uni.$u.toast('请勾选已阅读并同意《用户注册协议》和《隐私协议》')
// 调用登录接口
const data = await isLogin({
scene: LoginTypeEnum.ACCOUNT,
username: form.value.username,
password: form.value.password
})
// 登录处理
loginHandle(data)
}
/*** 登录处理*/
async function loginHandle(data: any) {
// 从数据中取出token和是否绑定手机标志
const { token, isBindMobile } = data
// 保存登录的token
userStore.login(token)
await getAllDict()
// 获取用户信息
await userStore.getUser()
// 获取系统配置
// await appStore.getConfig()
// 显示登录成功提示
uni.$u.toast('登录成功')
// 隐藏登录加载框
uni.hideLoading()
// appStore.setFirstLogin(true)
const { userInfo } = userStore
// 判断是主账号登录还是电销/招生登录
if (userInfo.postIds == 0 && userInfo.masterAccount == 1) {
cache.set(ROLEINDEX, 2)
setNextRoute()
} else {
if (userInfo.roles?.length > 1) {
uni.redirectTo({
url: '/bundle/pages/select-role/index'
})
} else {
setNextRoute()
}
}
cache.remove(BACK_URL)
}
/**点击空白处 */
const handleClickEmpty = e => {
if (e.target.dataset.name) {
isCheckAgreement.value = !isCheckAgreement.value
}
}
watch(
() => unref(isCheckAgreement),
newVal => {
checked.value = newVal ? ['agreement'] : []
}
)
</script>
<style lang="scss" scoped>
.login {
@include flex-direction;
height: 100vh;
.base {
margin-top: 50rpx;
margin-bottom: 30rpx;
padding: 0 30px;
.logo {
@include flex-direction;
align-items: center;
margin: 80rpx 0;
.title {
font-size: 36rpx;
margin-top: 40rpx;
}
}
.login-btn {
:deep(.u-button) {
height: 88rpx !important;
}
:deep(.u-button__text) {
font-size: 32rpx !important;
}
}
}
.agreement {
// height: 140rpx;
@include flex-justify(center);
font-size: 34rpx;
color: #3d3d3d;
:deep(.u-checkbox-group) {
align-items: center;
}
:deep(.u-checkbox) {
margin-bottom: 0 !important;
text {
line-height: unset !important;
}
}
:deep(.btn) {
text {
font-size: 34rpx !important;
}
}
.strong {
color: #2759ff;
}
.text {
margin-top: 10rpx;
}
}
.login-form {
padding: 0 30px;
.item {
@apply mb-2;
.label {
@apply text-2xl font-bold mb-1;
}
}
}
.wx-login {
@apply fixed left-[50%] px-[30px];
transform: translateX(-50%);
bottom: Max(env(safe-area-inset-bottom), 40rpx);
.name {
@apply px-3 relative w-full text-center;
&::before {
content: '';
width: 100%;
height: 1px;
background-color: #dedbdb;
position: absolute;
left: -100%;
top: 50%;
transform: translateY(-50%);
}
&::after {
content: '';
width: 100%;
height: 1px;
background-color: #dedbdb;
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
}
}
.btn {
:deep(button) {
@apply w-[60px] h-[60px] mt-3;
}
:deep(.u-icon text) {
font-size: 40px !important;
}
}
}
}
</style>