Files
SoonWorkerD/src/renderer/views/login/index.vue
T
2026-05-12 21:42:42 +08:00

351 lines
9.0 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-container">
<img class="login_bg" src="@/assets/images/login_bg.jpg" />
<div class="flex_box form_box">
<el-form class="flex_box flex_col flex_row_center login-form" autoComplete="on" :model="loginForm"
:rules="loginRules" ref="loginForm" label-position="left">
<img class="login_logo" src="@/assets/images/logo.png" />
<div class="login_box">
<div class="login_title">用户登录</div>
<div class="login_label">用户名</div>
<el-form-item prop="username">
<el-input name="username" type="text" v-model="loginForm.username" autoComplete="on"
placeholder="username" />
</el-form-item>
<div class="login_label">密码</div>
<el-form-item prop="password">
<el-input name="password" :type="pwdType" @keyup.enter.native="handleLogin" v-model="loginForm.password"
autoComplete="on" placeholder="password"></el-input>
<span class="show-pwd" @click="showPwd">
</span>
</el-form-item>
<el-form-item>
<div class="login_check">
<el-checkbox v-model="isChecked">记住账号密码</el-checkbox>
</div>
</el-form-item>
<el-form-item>
<el-button class="login_btn" type="primary" :loading="loading" @click.native.prevent="handleLogin">{{
$t('login.logIn') }}</el-button>
</el-form-item>
<el-form-item>
<div class="login_ws_setting">
<el-button type="text" @click="showSocketSetting = !showSocketSetting">
{{ showSocketSetting ? '收起' : '设置 WebSocket 服务地址' }}
</el-button>
<div v-if="showSocketSetting" class="login_ws_input">
<el-input v-model="socketApi" placeholder="例如 ws://127.0.0.1:10010 或 ws://服务器IP:10010"
@blur="saveSocketApi" size="small" />
<span class="login_ws_tip">网页端部署后请填写实际服务地址保存后刷新或重新登录生效</span>
</div>
</div>
</el-form-item>
</div>
</el-form>
</div>
<el-popover v-if="guideStep" :placement="guideStep[0].placement" width="250" trigger="manual"
v-model="guideStep[0].show">
<div class="guide_box">
<div class="guide_title">新手引导<span>{{ parseInt(currentStep) + 1 }}/{{ guideStep.length }}</span>
</div>
<div class="guide_desc">{{ guideStep[0].step }}</div>
<div class="guide_btns">
<el-button @click="exitGuide" class="guide_btn1" size="mini" type="text">跳过引导</el-button>
<el-button v-if="parseInt(currentStep) > 0" @click="prevStep" class="guide_btn1" size="mini">上一步</el-button>
<el-button @click="nextStep" class="guide_btn2" size="mini" type="primary">{{ currentStep ==
guideStep.length
- 1 ? '完成引导' : '下一步' }}</el-button>
</div>
</div>
</el-popover>
</div>
</template>
<script>
import { validUsername } from '@/utils/validate'
import { getToken, setToken, removeToken } from '@/utils/auth'
export default {
name: 'login',
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error('请输入正确的用户名'))
} else {
callback()
}
}
const validatePass = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入您的密码'))
} else {
callback()
}
}
return {
loginForm: {
username: 'admin',
password: 'admin'
},
loginRules: {
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePass }]
},
isChecked: true,
loading: false,
pwdType: 'password',
showSocketSetting: false,
socketApi: ''
}
},
mounted() {
try {
this.socketApi = localStorage.getItem('WS_SOCKET_API') || 'ws://127.0.0.1:10010'
} catch (e) {
this.socketApi = 'ws://127.0.0.1:10010'
}
},
methods: {
saveSocketApi() {
try {
const v = (this.socketApi || '').trim()
if (v) localStorage.setItem('WS_SOCKET_API', v)
} catch (e) {}
},
showPwd() {
if (this.pwdType === 'password') {
this.pwdType = ''
} else {
this.pwdType = 'password'
}
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
setToken('data.token')
if (localStorage.getItem('setForm')) {
this.$store.dispatch('setDatas', { name: 'setForm', data: localStorage.getItem('setForm') })
}
this.$store.dispatch('setDatas', { name: 'token', data: 'data.token' })
this.$store.dispatch('setDatas', { name: 'oneLogin', data: true })
setTimeout(() => {
this.loading = false
this.$router.push({ path: '/' })
}, 2000);
// this.$store.dispatch('Login', this.loginForm).then(() => {
// this.loading = false
// this.$router.push({ path: '/' })
// }).catch(() => {
// this.loading = false
// })
} else {
console.log('error submit!!')
return false
}
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
$bg: #F1F1F1;
$light_gray: #000000;
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
height: 60px;
border-radius: 30px;
width: 100%;
background: #F1F1F1;
border-radius: 30px;
color: #000;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 60px;
font-size: 24px;
border-radius: 30px;
&:-webkit-autofill {
border-radius: 30px;
-webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: #000 !important;
}
}
}
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
$bg: #F1F1F1;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
position: fixed;
height: 100%;
width: 100%;
.login_bg {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
}
.form_box {
position: absolute;
left: 0;
right: 0;
z-index: 9;
width: 100%;
height: 100%;
padding: 0 0 0 120px;
}
.login-form {
height: 100%;
.login_logo {
width: 844px;
height: 158px;
margin-bottom: 48px;
}
.login_box {
width: 450px;
background-color: #fff;
border-radius: 24px;
padding: 48px;
.login_title {
font-weight: 500;
font-size: 30px;
color: #009688;
line-height: 44px;
text-align: center;
margin-bottom: 48px;
}
.login_label {
font-size: 24px;
color: #B2B2B2;
line-height: 36px;
margin-bottom: 24px;
}
.login_check {
::v-deep {
.el-checkbox {
display: flex;
align-items: center;
}
.el-checkbox__inner {
width: 24px;
height: 24px;
}
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #009688;
border-color: #009688;
}
.el-checkbox__inner::after {
width: 6px;
height: 14px;
left: 8px;
}
.el-checkbox__label {
font-size: 24px;
line-height: 24px;
}
.el-checkbox__input.is-checked+.el-checkbox__label {
color: #009688;
}
}
}
.login_btn {
width: 100%;
height: 60px;
background: #F1F1F1;
border-radius: 33px;
border: 3px solid #00BCC3;
font-size: 24px;
color: #00BCC3;
}
.login_ws_setting {
width: 100%;
.login_ws_input {
margin-top: 8px;
.el-input { width: 100%; }
}
.login_ws_tip {
display: block;
font-size: 12px;
color: #909399;
margin-top: 4px;
}
}
}
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
&_login {
font-size: 20px;
}
}
.title {
font-size: 26px;
font-weight: 400;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
}
</style>