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.
366 lines
11 KiB
366 lines
11 KiB
<template> |
|
<div class="login"> |
|
<!-- 左侧品牌栏 --> |
|
<div class="login_left"> |
|
<div class="brand-box"> |
|
<!-- 内嵌SVG 超声探头图标 --> |
|
<img src="@/assets/images/login-background.jpg" alt="Hisense Icon" /> |
|
<div>信联</div> |
|
</div> |
|
<!-- 底部波浪装饰 --> |
|
<div class="wave-wrapper"> |
|
<div class="wave wave-1"></div> |
|
<div class="wave wave-2"></div> |
|
<div class="wave wave-3"></div> |
|
<div class="wave wave-4"></div> |
|
</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"> |
|
<img :src="$store.state.user.userInfo.avatar" alt="" /> |
|
</div> |
|
<h3 class="title">你好, {{ $store.state.user.userName }}</h3> |
|
</div> |
|
<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> |
|
<el-checkbox v-model="loginForm.rememberMe"> 自动登录 </el-checkbox> |
|
</el-form-item> |
|
<el-form-item> |
|
<el-button |
|
:loading="loading" |
|
type="primary" |
|
style="width: 100%" |
|
@click.native.prevent="handleLogin" |
|
> |
|
<span v-if="!loading">登 录</span> |
|
<span v-else>登 录 中...</span> |
|
</el-button> |
|
</el-form-item> |
|
</el-form> |
|
</div> |
|
<!-- 登录设置弹窗 --> |
|
<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="primary" @click="handleSettingsConfirm"> |
|
确定 |
|
</el-button> |
|
<el-button @click="showSettingsDialog = false">取消</el-button> |
|
</div> |
|
</el-dialog> |
|
</div> |
|
</template> |
|
<script> |
|
import Cookies from "js-cookie"; |
|
import { encrypt, decrypt } from "@/utils/jsencrypt"; |
|
import CryptoJS from "crypto-js"; |
|
export default { |
|
name: "Login", |
|
data() { |
|
return { |
|
// 角色信息 |
|
roleName: "会诊专家", // 示例:你好, 会诊专家 |
|
roleIconText: "家", // 示例:顶部圆形图标文字 |
|
loginForm: { |
|
username: "hzzjys", |
|
password: "", |
|
rememberMe: false, |
|
uuid: "", |
|
}, |
|
loginRules: { |
|
username: [ |
|
{ required: true, trigger: "blur", message: "请输入您的账号" }, |
|
], |
|
password: [ |
|
{ required: true, trigger: "blur", message: "请输入您的密码" }, |
|
], |
|
}, |
|
loading: false, |
|
redirect: undefined, |
|
showSettingsDialog: false, |
|
settingsForm: { |
|
address: "47.92.192.91", |
|
port: "8688", |
|
protocol: "HTTP", |
|
}, |
|
}; |
|
}, |
|
watch: { |
|
$route: { |
|
handler(route) { |
|
this.redirect = route.query && route.query.redirect; |
|
}, |
|
immediate: true, |
|
}, |
|
}, |
|
created() { |
|
this.getCookie(); |
|
// this.handleLogin(); |
|
}, |
|
methods: { |
|
// 与 Qt CEncrypt::DataEncryptMD5 逻辑一致 |
|
md5Encrypt(str) { |
|
return CryptoJS.MD5(str).toString(); |
|
}, |
|
getCookie() { |
|
const username = Cookies.get("username"); |
|
const password = Cookies.get("password"); |
|
const rememberMe = Cookies.get("rememberMe"); |
|
this.loginForm = { |
|
username: username === undefined ? this.loginForm.username : username, |
|
password: |
|
password === undefined ? this.loginForm.password : decrypt(password), |
|
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), |
|
}; |
|
this.handleLogin(); |
|
}, |
|
handleLogin() { |
|
this.$refs.loginForm.validate((valid) => { |
|
if (valid) { |
|
this.loading = true; |
|
if (this.loginForm.rememberMe) { |
|
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, |
|
}); |
|
} else { |
|
Cookies.remove("username"); |
|
Cookies.remove("password"); |
|
Cookies.remove("rememberMe"); |
|
} |
|
this.$store |
|
.dispatch("Login", { |
|
username: this.loginForm.username, |
|
password: this.md5Encrypt(this.loginForm.password), |
|
psign: this.md5Encrypt("xycloud_" + this.loginForm.password), |
|
version: this.$store.getters.loginInfo?.upgrade_data?.version || "V01.01.16", |
|
}) |
|
.then(() => { |
|
this.$router.push({ path: this.redirect || "/" }).catch(() => {}); |
|
}) |
|
.catch(() => { |
|
this.loading = false; |
|
}); |
|
} |
|
}); |
|
}, |
|
handleClose() { |
|
window.close(); |
|
}, |
|
// 登录设置确定逻辑 |
|
handleSettingsConfirm() { |
|
// 这里可以添加保存地址、端口、协议的逻辑 |
|
console.log("保存设置:", this.settingsForm); |
|
this.showSettingsDialog = false; |
|
}, |
|
}, |
|
}; |
|
</script> |
|
|
|
<style rel="stylesheet/scss" lang="scss" scoped> |
|
.login { |
|
display: flex; |
|
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; |
|
.brand-logo { |
|
font-size: 22px; |
|
font-weight: bold; |
|
margin-bottom: 8px; |
|
} |
|
} |
|
/* 优化后的水波纹容器 */ |
|
.wave-wrapper { |
|
position: absolute; |
|
bottom: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
overflow: hidden; |
|
z-index: 1; |
|
pointer-events: none; |
|
} |
|
|
|
/* 三层波浪:速度、透明度、大小区分明显 */ |
|
.wave { |
|
position: absolute; |
|
left: 0; |
|
width: 200%; |
|
height: 100%; |
|
background-size: 100% auto; |
|
background-repeat: no-repeat; |
|
background-position: center bottom; |
|
opacity: 0.3; |
|
animation: waveUpDown 6s ease-in-out infinite alternate; |
|
} |
|
|
|
.wave-1 { |
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320'%3E%3Cpath fill='%23ffffff' fill-opacity='0.2' d='M0,160L48,181.3C96,203,192,245,288,245.3C384,245,480,203,576,181.3C672,160,768,160,864,176C960,192,1056,224,1152,218.7C1248,213,1344,171,1392,149.3L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z'%3E%3C/path%3E%3C/svg%3E"); |
|
bottom: -10%; |
|
height: 40%; |
|
animation-duration: 7s; |
|
opacity: 0.25; |
|
} |
|
|
|
.wave-2 { |
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320'%3E%3Cpath fill='%23ffffff' fill-opacity='0.15' d='M0,224L48,213.3C96,203,192,181,288,186.7C384,192,480,224,576,229.3C672,235,768,213,864,192C960,171,1056,149,1152,160C1248,171,1344,213,1392,234.7L1440,256L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z'%3E%3C/path%3E%3C/svg%3E"); |
|
bottom: -5%; |
|
height: 35%; |
|
animation-duration: 5s; |
|
opacity: 0.2; |
|
} |
|
|
|
.wave-3 { |
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320'%3E%3Cpath fill='%23ffffff' fill-opacity='0.1' d='M0,256L48,240C96,224,192,192,288,197.3C384,203,480,245,576,240C672,235,768,181,864,160C960,139,1056,149,1152,170.7C1248,192,1344,224,1392,240L1440,256L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z'%3E%3C/path%3E%3C/svg%3E"); |
|
bottom: 0; |
|
height: 30%; |
|
animation-duration: 4s; |
|
opacity: 0.15; |
|
} |
|
|
|
/* 波浪上下起伏动画,更柔和 */ |
|
@keyframes waveUpDown { |
|
0% { |
|
transform: translateY(0); |
|
} |
|
100% { |
|
transform: translateY(-15px); |
|
} |
|
} |
|
} |
|
|
|
/* 右侧登录区 */ |
|
.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; |
|
.role-icon { |
|
width: 60px; |
|
height: 60px; |
|
line-height: 60px; |
|
background-color: #ff9900; /* 橙色圆形图标 */ |
|
border-radius: 50%; |
|
color: #fff; |
|
margin: 0 auto 10px; |
|
img { |
|
width: 100%; |
|
height: 100%; |
|
} |
|
} |
|
.title { |
|
margin: 0; |
|
color: #333; |
|
} |
|
} |
|
.input-icon { |
|
height: 39px; |
|
width: 14px; |
|
margin-left: 2px; |
|
color: #009696; |
|
} |
|
} |
|
} |
|
} |
|
</style> |