You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
virtual-patient-web/src/views/login/index.vue

283 lines
7.5 KiB
Vue

<script setup lang="ts">
import Motion from "./utils/motion";
import { useRouter } from "vue-router";
import { message } from "@/utils/message";
// import { loginRules } from "./utils/rule";
// import { useNav } from "@/layout/hooks/useNav";
import type { FormInstance } from "element-plus";
import { useLayout } from "@/layout/hooks/useLayout";
import { useUserStoreHook } from "@/store/modules/user";
import { initRouter } from "@/router/utils";
// import { leftLogo, sst } from "./utils/static";
import bg from "../../assets/login/login_bg.png";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
// import update from "./components/update.vue";
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from "vue";
import Lock from "@iconify-icons/icon-park-outline/lock";
import User from "@iconify-icons/icon-park-outline/user";
import PreviewClose from "@iconify-icons/icon-park-outline/preview-close";
import PreviewOpen from "@iconify-icons/icon-park-outline/preview-open";
defineOptions({
name: "Login"
});
const router = useRouter();
const loading = ref(false);
const ruleFormRef = ref<FormInstance>();
const checked = ref(false);
// const currentPage = computed(() => {
// return useUserStoreHook().currentPage;
// });
const { initStorage } = useLayout();
initStorage();
// const { dataTheme, dataThemeChange } = useDataThemeChange();
// dataThemeChange();
// const { title } = useNav();
const ruleForm = reactive({
username: "",
password: ""
});
const onLogin = async (formEl: FormInstance | undefined) => {
loading.value = true;
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
useUserStoreHook()
.loginByUsername({
userAccount: ruleForm.username,
password: ruleForm.password
})
.then((res: any) => {
loading.value = false;
if (res.code === 200) {
if (res.data.roleCode === "1") {
initRouter().then(() => {
router.push("/selectCase");
});
} else {
initRouter().then(() => {
router.push("/inquiryCase");
});
}
message("登录成功", { type: "success" });
// sessionStorage.setItem("userInfo", JSON.stringify({ role: "1" }));
}
})
.catch(() => {
loading.value = false;
message("登录失败", { type: "error" });
});
} else {
loading.value = false;
return fields;
}
});
};
const passwordType = ref("password");
const refInput = ref();
/** 使用公共函数,避免`removeEventListener`失效 */
function onkeypress({ code }: KeyboardEvent) {
if (code === "Enter") {
onLogin(ruleFormRef.value);
}
}
function showPass() {
if (passwordType.value === "password") {
passwordType.value = "text";
} else {
passwordType.value = "password";
}
nextTick(() => {
refInput.value.focus();
});
}
onMounted(() => {
window.document.addEventListener("keypress", onkeypress);
});
onBeforeUnmount(() => {
window.document.removeEventListener("keypress", onkeypress);
});
</script>
<template>
<div class="select-none">
<img :src="bg" class="wave" />
<div class="login-container">
<div class="login-left">
<span class="login-left-title">欢迎使用</span>
<span class="systeam-name">虚拟病人系统</span>
<span class="desc">Welcome to the Virtual Patient System</span>
</div>
<div class="login-box">
<div class="login-form">
<div class="top">
<p class="title">欢迎登录虚拟病人系统</p>
<p class="top_desc">Welcome to login</p>
</div>
<el-form ref="ruleFormRef" :model="ruleForm" size="large">
<Motion :delay="100">
<el-form-item
:rules="[
{
required: true,
message: '请输入账号',
trigger: 'blur'
}
]"
prop="username"
>
<el-input
style="height: 60px; font-size: 16px"
v-model="ruleForm.username"
placeholder="账号"
:prefix-icon="useRenderIcon(User)"
/>
</el-form-item>
</Motion>
<Motion :delay="150">
<el-form-item
prop="password"
:rules="[
{
required: true,
message: '请输入密码',
trigger: 'blur'
}
]"
>
<el-input
style="height: 60px; font-size: 16px"
ref="refInput"
:type="passwordType"
v-model="ruleForm.password"
placeholder="密码"
:prefix-icon="useRenderIcon(Lock)"
>
<template #suffix>
<el-icon
class="el-icon el-input__icon el-input__password"
@click="showPass"
>
<IconifyIconOffline
:icon="
passwordType == 'password'
? PreviewClose
: PreviewOpen
"
/>
</el-icon>
</template>
</el-input>
</el-form-item>
</Motion>
<Motion :delay="250">
<div class="w-full h-[20px] flex justify-between items-center">
<el-checkbox v-model="checked">
{{ "" }}
</el-checkbox>
<!-- <el-button
link
class="btn-color"
type="primary"
@click="useUserStoreHook().SET_CURRENTPAGE(4)"
>
{{ "忘记密码?" }}
</el-button> -->
</div>
<el-button
class="w-full mt-9 login-btn"
size="large"
type="primary"
color="rgba(66, 135, 255, 1)"
:loading="loading"
@click="onLogin(ruleFormRef)"
>
登录
</el-button>
</Motion>
</el-form>
<!-- 忘记密码 -->
<!-- <update v-if="currentPage === 4" /> -->
</div>
</div>
</div>
</div>
</template>
<style scoped>
@import url("@/style/login.css");
</style>
<style lang="scss" scoped>
:deep(.el-input-group__append, .el-input-group__prepend) {
padding: 0;
}
.login-btn {
height: 60px;
font-size: 16px;
color: #fff;
background: #4287ff;
border-radius: 6px;
box-shadow: 0 10px 20px 2px rgb(24 144 255 / 20%);
}
.btn-color {
color: #1c0d82;
}
.btn-color:hover {
color: #1c0d82;
opacity: 0.5;
}
.el-input__icon {
cursor: pointer;
}
// :deep(.el-button) {
// font-weight: bold;
// color: #fff;
// }
.login-left {
display: flex;
flex-direction: column;
span {
font-size: 50px;
font-weight: bold;
color: #fff;
}
.systeam-name {
font-size: 80px;
}
}
.login-box {
.top {
.title {
font-size: 24px;
font-weight: 400;
color: #333;
}
.top_desc {
margin-bottom: 52px;
font-size: 23px;
font-weight: 400;
color: #666;
}
}
}
</style>