海信医疗-远程超声管理平台-信创国产化
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

384 lines
11 KiB

1 month ago
<template>
<div class="login">
1 month ago
<!-- 左侧品牌栏 -->
<div class="login_left">
<div class="brand-box">
<!-- 内嵌SVG 超声探头图标 -->
<div class="icon-placeholder">
<svg width="140" height="140" viewBox="0 0 1024 1024" fill="#ffffff">
<path
d="M725.3 298.7c-35.3-35.3-92.7-35.3-128 0L341.3 554.7c-35.3 35.3-35.3 92.7 0 128s92.7 35.3 128 0l256-256c35.3-35.3 35.3-92.7 0-128zM298.7 682.7c-58.9 58.9-58.9 154.4 0 213.3s154.4 58.9 213.3 0l256-256c58.9-58.9 58.9-154.4 0-213.3s-154.4-58.9-213.3 0l-256 256z"
></path>
<path
d="M192 832a64 64 0 1 0 128 0 64 64 0 1 0-128 0zM832 192a64 64 0 1 0 0 128 64 64 0 1 0 0-128z"
></path>
<path
d="M640 320a64 64 0 1 0 0-128 64 64 0 1 0 0 128zM320 640a64 64 0 1 0 0-128 64 64 0 1 0 0 128z"
></path>
</svg>
1 month ago
</div>
1 month ago
<div class="brand-logo">Hisense</div>
<div class="brand-text">信联</div>
</div>
<!-- 底部波浪装饰 -->
<div class="wave-bg"></div>
</div>
<!-- 右侧登录表单区 -->
<div class="login_right">
<div class="login_header">
<i class="el-icon-setting" @click="showSettingsDialog = true"></i>
<i class="el-icon-close" @click="handleClose"></i>
</div>
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<div class="form-header">
<div class="role-icon">{{ roleIconText }}</div>
<h3 class="title">你好, {{ roleName }}</h3>
1 month ago
</div>
1 month ago
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="请输入账号"
>
<svg-icon
slot="prefix"
icon-class="user"
class="el-input__icon input-icon"
/>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="请输入密码"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="password"
class="el-input__icon input-icon"
/>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="validCode"
class="el-input__icon input-icon"
/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" />
</div>
</el-form-item>
<el-checkbox
v-model="loginForm.rememberMe"
style="margin: 0px 0px 25px 0px"
>
自动登录
</el-checkbox>
<el-form-item>
<el-button
:loading="loading"
size="medium"
type="success"
style="width: 100%"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
</el-form-item>
</el-form>
1 month ago
</div>
1 month ago
<!-- 登录设置弹窗 -->
<el-dialog
title="登录设置"
:visible.sync="showSettingsDialog"
width="500px"
:close-on-click-modal="false"
>
<el-form :model="settingsForm" label-width="80px">
<el-form-item label="地址">
<el-input v-model="settingsForm.address" placeholder="请输入地址" />
</el-form-item>
<el-form-item label="端口">
<el-input v-model="settingsForm.port" placeholder="请输入端口" />
</el-form-item>
<el-form-item label="协议">
<el-radio-group v-model="settingsForm.protocol">
<el-radio label="HTTP">HTTP</el-radio>
<el-radio label="HTTPS">HTTPS</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="success" @click="handleSettingsConfirm">
确定
</el-button>
<el-button @click="showSettingsDialog = false">取消</el-button>
</div>
</el-dialog>
1 month ago
</div>
</template>
<script>
1 month ago
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
1 month ago
export default {
name: "Login",
data() {
return {
1 month ago
// 角色信息
roleName: "会诊专家", // 示例:你好, 会诊专家
roleIconText: "家", // 示例:顶部圆形图标文字
1 month ago
codeUrl: "",
loginForm: {
1 month ago
username: "hzzjys",
password: "",
1 month ago
rememberMe: false,
code: "",
1 month ago
uuid: "",
1 month ago
},
loginRules: {
username: [
1 month ago
{ required: true, trigger: "blur", message: "请输入您的账号" },
1 month ago
],
password: [
1 month ago
{ required: true, trigger: "blur", message: "请输入您的密码" },
1 month ago
],
},
loading: false,
captchaEnabled: true,
1 month ago
redirect: undefined,
showSettingsDialog: false,
settingsForm: {
address: "47.92.192.91",
port: "8688",
protocol: "HTTP",
},
};
1 month ago
},
watch: {
$route: {
1 month ago
handler(route) {
this.redirect = route.query && route.query.redirect;
1 month ago
},
1 month ago
immediate: true,
},
1 month ago
},
created() {
1 month ago
this.getCode();
this.getCookie();
// 实际业务中,这里可以调用接口获取当前角色信息
// this.getRoleInfo();
1 month ago
},
methods: {
getCode() {
1 month ago
getCodeImg().then((res) => {
this.captchaEnabled =
res.captchaEnabled === undefined ? true : res.captchaEnabled;
1 month ago
if (this.captchaEnabled) {
1 month ago
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
1 month ago
}
1 month ago
});
1 month ago
},
getCookie() {
1 month ago
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get("rememberMe");
1 month ago
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
1 month ago
password:
password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
};
1 month ago
},
handleLogin() {
1 month ago
this.$refs.loginForm.validate((valid) => {
1 month ago
if (valid) {
1 month ago
this.loading = true;
1 month ago
if (this.loginForm.rememberMe) {
1 month ago
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), {
expires: 30,
});
Cookies.set("rememberMe", this.loginForm.rememberMe, {
expires: 30,
});
1 month ago
} else {
1 month ago
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove("rememberMe");
1 month ago
}
1 month ago
this.$store
.dispatch("Login", this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
})
.catch(() => {
this.loading = false;
if (this.captchaEnabled) {
this.getCode();
}
});
1 month ago
}
1 month ago
});
},
handleClose() {
window.close();
},
// 登录设置确定逻辑
handleSettingsConfirm() {
// 这里可以添加保存地址、端口、协议的逻辑
console.log("保存设置:", this.settingsForm);
this.showSettingsDialog = false;
},
},
};
1 month ago
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.login {
display: flex;
1 month ago
height: 100vh;
overflow: hidden;
/* 左侧品牌栏 */
.login_left {
flex: 0 0 33%; /* 按参考图比例:左侧约占1/3 */
background-color: #009696; /* 海信医疗主色调 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
.brand-box {
text-align: center;
color: #fff;
z-index: 2;
.icon-placeholder {
width: 180px;
height: 180px;
// background: url("../assets/images/hisense-icon.png") no-repeat center / contain;
margin: 0 auto 16px;
}
1 month ago
1 month ago
.brand-logo {
font-size: 22px;
font-weight: bold;
margin-bottom: 8px;
}
.brand-text {
font-size: 20px;
font-weight: 500;
}
}
/* 底部波浪装饰 */
.wave-bg {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 160px;
background: linear-gradient(to top, rgba(0, 150, 150, 0.8), transparent);
opacity: 0.3;
border-radius: 100% 100% 0 0;
1 month ago
}
}
1 month ago
/* 右侧登录区 */
.login_right {
flex: 1;
background: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
padding: 20px;
box-sizing: border-box;
.login_header {
position: absolute;
top: 20px;
right: 20px;
display: flex;
gap: 16px;
.el-icon-setting,
.el-icon-close {
cursor: pointer;
font-size: 28px;
color: #666;
}
}
.login-form {
border-radius: 6px;
width: 100%;
max-width: 400px;
padding: 25px 25px 5px 25px;
z-index: 1;
.form-header {
text-align: center;
margin-bottom: 30px;
.role-icon {
width: 80px;
height: 80px;
line-height: 80px;
background-color: #ff9900; /* 橙色圆形图标 */
border-radius: 50%;
color: #fff;
font-size: 32px;
margin: 0 auto 10px;
}
.title {
margin: 0;
color: #333;
font-size: 24px;
}
}
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
color: #009696;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
height: 38px;
cursor: pointer;
vertical-align: middle;
}
}
}
1 month ago
}
}
1 month ago
</style>