rax-medical/src/views/login/login.vue
2024-02-22 20:48:08 +08:00

555 lines
19 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.

<template>
<div class="login-page">
<div class="left-content move_4"></div>
<div class="right-content">
<div class="select-hospital-box">
<el-select class="select-hospital" v-model="currentHospital" size="small" @change="selectHospital">
<el-option v-for="item in hospitals" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<img v-show="!isShowRegister" class="logo move_2" src="@/assets/imgs/logo.png">
<div v-if="!isShowRegister" class="login-block move_2">
<div class="login-way">
<span :class="passwordLogin && 'active'" @click="passwordLogin = true">密码登录</span>
<span :class="!passwordLogin && 'active'" @click="passwordLogin = false">验证码登录</span>
</div>
<el-form ref="loginFormRef" :model="loginParams" :rules="loginRules" label-width="0" size="small">
<div class="login-form password-login" v-if="passwordLogin">
<el-form-item prop="account">
<el-input v-model="loginParams.account" placeholder="请输入用户名">
<template #prepend>
<el-icon>
<User/>
</el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginParams.password" type="password" show-password placeholder="请输入密码">
<template #prepend>
<el-icon>
<Lock/>
</el-icon>
</template>
</el-input>
</el-form-item>
<el-button :loading="loading" class="login-btn" type="primary" @click="login('password')">登录</el-button>
<span class="register-btn" @click="getCaptchaCode()">注册账号</span>
</div>
<div class="login-form code-login" v-else>
<el-form-item prop="phone">
<el-input v-model="loginParams.phone" placeholder="请输入手机号">
<template #prepend>
<div @click.stop style="display: flex;align-items: center;">
<el-dropdown @command="selectPhoneArea">
<span style="color: #909399;">{{ loginParams.phoneArea }}<el-icon>
<DCaret />
</el-icon></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="item in phoneAreas" :command="item">{{ item
}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="loginParams.code" placeholder="请输入6位短信验证码">
<template #append>
<span class="send-btn" @click="sendCode">{{ loginParams.sendText }}</span>
</template>
</el-input>
</el-form-item>
<el-button class="login-btn" type="primary" @click="login('code')">登录</el-button>
</div>
</el-form>
</div>
<div v-else class="register-block move_2">
<div class="header-box">
<span class="title">新用户申请</span>
<el-icon @click="isShowRegister = false">
<Close />
</el-icon>
</div>
<el-form ref="registerFormRef" :model="registerParams" :rules="registerRules" label-width="100">
<el-form-item label="用户名" prop="account">
<el-input v-model="registerParams.account" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="registerParams.password" type="password" show-password
placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="registerParams.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="registerParams.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="医院" prop="hospital">
<el-select v-model="registerParams.hospital" style="width: 100%;">
<el-option v-for="item in hospitals" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="registerParams.sex">
<el-radio label="男" />
<el-radio label="女" />
</el-radio-group>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input v-model="registerParams.code" placeholder="请输入验证码"
style="width: calc(100% - 110px);"></el-input>
<img width="100" height="32" style="margin-left: 10px;" :src="captchaImgUrl" />
<a class="change_img" @click="refreshImg" href="#">看不清?</a>
</el-form-item>
</el-form>
<div class="footer-box">
<el-button type="primary" @click="register">注 册</el-button>
<span @click="isShowRegister = false">已有账号?</span>
</div>
</div>
</div>
</div>
<SliderVerify v-model:isShowSelf="sliderVConf.isShowSelf" :width="sliderVConf.width" :imgUrl="sliderImgUrl"
:height="sliderVConf.height" @success="toHome"></SliderVerify>
</template>
<script lang='ts' setup>
import { ElNotification } from 'element-plus';
//引入获取当前时间的函数
import { getTime } from '@/utils/time';
import {onMounted, reactive, ref, toRefs, watch} from 'vue'
import {useRouter,useRoute} from 'vue-router'
import {ElMessage, ElMessageBox} from 'element-plus'
import {useLoginStore} from '@/stores/user-info-store'
import {getHospitalsData, getPhoneAreasData} from '@/static-data/core'
import {v4} from "uuid";
import {HOST} from "@/utils/request";
import SliderVerify from "@/components/SliderVerify/index.vue";
//引入用户相关的小仓库
//import useUserStore from "@/stores/user-info-store";
//let useStore = useUserStore();
const router = useRouter()
const hospitals = ref([] as any)
getHospitalsData().then((res: any) => {
hospitals.value = res
})
const phoneAreas: any = getPhoneAreasData()
//定义变量控制按钮加载效果
let loading = ref(false);
//自定义校验规则函数
const validatorUserName = (rule: any, value: any, callback: any) => {
//rule:即为校验规则对象
//value:即为表单元素文本内容
//函数:如果符合条件callBack放行通过即为
//如果不符合条件callBack方法,注入错误提示信息
if (value.length >= 4) {
callback();
} else {
callback(new Error('账号长度至少4位'));
}
}
const validatorPassword = (rule: any, value: any, callback: any) => {
if (value.length >= 6) {
callback();
} else {
callback(new Error('密码长度至少6位'));
}
}
const validatorPhone = (rule: any, value: any, callback: any) => {
var isPhone = /^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
if (value.indexOf('****') >= 0) {
return callback().trim();
}
if (!isPhone.test(value)) {
callback(new Error('请输入合法手机号'));
} else {
callback();
}
}
const loginRules = reactive({
account: [
{ required: true, validator: validatorUserName, trigger: 'change' },
],
password: [
{ required: true, validator: validatorPassword, trigger: 'change' },
],
phone: [
{ required: true, validator:validatorPhone, trigger: 'blur' },
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
]
})
const registerRules = reactive({
account: [
{ required: true, validator: validatorUserName, trigger: 'change' },
],
password: [
{ required: true, validator: validatorUserName, trigger: 'change' },
],
name: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
],
phone: [
{ required: true, validator:validatorPhone, trigger: 'change' },
],
hospital: [
{ required: true, message: '请选择医院', trigger: 'blur' },
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
]
})
//获取路由器
let $router = useRouter();
//路由对象
let $route = useRoute();
const loginFormRef = ref()
const registerFormRef = ref()
const slideVerifyRef = ref()
const currentHospital = ref(useLoginStore().getlogin().hospital)
const isShowRegister = ref(false)
const passwordLogin = ref(true)
const loginParams = ref({
account: 'admin',
name: '',
password: '123456',
phone: '',
phoneArea: phoneAreas[0],
code: '',
isSendCode: false,
sendTimer: 0,
sendText: '获取短信验证码'
})
const registerParams = ref({
account: '',
password: '',
name: '',
phone: '',
hospital: '',
sex: '',
code: ''
})
const sliderVConf = ref({
isShowSelf: false,
width: 400,
height: 200
})
const captchaImgUrl = ref('')
const sliderImgUrl = ref('')
const selectHospital = (e: string) => {
// console.log(e)
}
const register = async () => {
await registerFormRef.value.validate((valid: any, fields: any) => {
if (valid) {
ElMessageBox.confirm(
'注册成功,是否登录?',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'success',
draggable: true
}
).then(() => {
loginParams.value.account = registerFormRef.value.account
loginParams.value.name = registerFormRef.value.name
currentHospital.value = registerFormRef.value.hospital
toHome()
}).catch(() => { })
} else {
// console.log('error submit!', fields)
}
})
}
const selectPhoneArea = (e: string) => {
loginParams.value.phoneArea = e
}
const sendCode = () => {
if (loginParams.value.isSendCode) return
let num = 60
ElMessage.success('发送成功!')
loginParams.value.isSendCode = true
loginParams.value.sendText = '请' + num + '秒后重新发送'
loginParams.value.sendTimer = setInterval(() => {
num--
if (num > 0) {
loginParams.value.sendText = '请' + num + '秒后重新发送'
} else {
loginParams.value.isSendCode = false
loginParams.value.sendText = '重新获取短信验证码'
clearInterval(loginParams.value.sendTimer)
}
}, 1000);
}
const login = async (type: string) => {
const obj = loginParams.value
if (!currentHospital.value) {
ElMessage.warning('请在右上角选择院区')
return
}
await loginFormRef.value.validate((valid: any, fields: any) => {
if (valid) {
// console.log('submit!')
sliderVConf.value.isShowSelf = true
} else {
// console.log('error submit!', fields)
}
//加载效果:开始加载
loading.value = true;
ElNotification({
type: 'success',
message: '欢迎回来',
title: `HI,${getTime()}`
});
/*try {
//保证登录成功
await useStore.userLogin(loginFormRef);
//编程式导航跳转到展示数据首页
//判断登录的时候,路由路径当中是否有query参数如果有就往query参数挑战没有跳转到首页
let redirect: any = $route.query.redirect;
$router.push({ path: redirect || '/' });
//登录成功加载效果也消失
loading.value = false;
}*/
/*} catch (error) {
//登录失败加载效果消息
loading.value = false;
//登录失败的提示信息
ElNotification({
type: 'error',
message: (error as Error).message
})*/
})
//登录成功加载效果也消失
loading.value = false;
}
function getCaptchaCode() {
isShowRegister.value = true
refreshImg()
}
function refreshImg() {
const randomStr = v4()
captchaImgUrl.value = HOST + '/admin/code/textImage?randomStr=' + randomStr
}
const toHome = () => {
const getPermissions = () => {
let permissions = '普通用户'
switch (loginParams.value.account) {
case 'admin':
permissions = '超级管理员'
break;
case 'dev1':
permissions = '高级管理员'
break;
case 'dev2':
permissions = '中级管理员'
break;
default:
break;
}
return permissions
}
useLoginStore().setlogin('isLogin', true)
useLoginStore().setlogin('account', loginParams.value.account)
useLoginStore().setlogin('name', loginParams.value.name || '暂未设置姓名')
useLoginStore().setlogin('hospital', currentHospital.value)
useLoginStore().setlogin('permissions', getPermissions())
router.push('/home')
}
</script>
<style lang='scss' scoped>
.login-page {
width: 100%;
height: 100%;
display: flex;
background-color: #F8F8F8;
.left-content {
width: 50%;
height: 100%;
background: url(@/assets/imgs/login/login_bck.png) no-repeat;
background-size: cover;
}
.right-content {
position: relative;
width: 50%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.select-hospital-box {
position: absolute;
top: 25px;
right: 25px;
}
.logo {
height: 70px;
}
.login-block {
width: 65%;
height: 430px;
min-width: 500px;
min-height: 300px;
padding: 50px;
margin-top: 20px;
background: white;
.login-way {
font-size: 18px;
color: #909399;
span {
cursor: pointer;
margin-right: 10px;
}
.active {
color: $main-color;
font-weight: 600;
}
}
.login-form {
:deep(.el-input) {
font-size: 16px;
margin-top: 20px;
.el-input-group__prepend,
.el-input__wrapper,
.el-input-group__append {
box-shadow: none;
border-bottom: 1px solid $border-color;
background-color: transparent;
padding: 10px 20px;
}
.el-input-group__prepend,
.el-input-group__append {
position: relative;
&::after {
content: '';
position: absolute;
width: 1px;
height: 16px;
top: calc(50% - 8px);
right: 0;
background-color: $border-color;
}
}
.el-input-group__append::after {
right: auto;
left: 0;
}
}
.send-btn {
cursor: pointer;
color: $main-color;
font-weight: 600;
}
}
.login-btn {
width: 100%;
margin-top: 40px;
font-size: 20px;
font-weight: 600;
padding: 25px 0 25px 0.3em;
border-radius: 0px;
letter-spacing: 0.3em;
}
.register-btn {
cursor: pointer;
float: right;
color: $main-color;
margin-top: 20px;
}
}
.register-block {
width: 65%;
min-width: 500px;
min-height: 300px;
padding: 50px;
background: white;
.header-box {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
.title {
font-size: 20px;
color: $main-color;
font-weight: 600;
}
.el-icon {
cursor: pointer;
}
}
.footer-box {
padding-left: 100px;
display: flex;
justify-content: space-between;
align-items: center;
.el-button {
font-size: 16px;
padding: 5px 50px;
}
&>span {
cursor: pointer;
font-size: 18px;
color: #909399;
}
}
}
}
}
</style>