376 lines
10 KiB
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>
|