Files
effekt-interface-frontend/src/components/User/Login.vue
qiaoxinjiu 6e9673f7dd feat(plan): 计划自动化执行、结果列表与鉴权请求优化
- 新增 automationApi、PlanAutomationRun、PlanAutomationExecutionList
- 计划构建/列表/执行/进度等接入自动化与路由
- request 与 authToken 处理 token 刷新与错误码

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 14:27:55 +08:00

277 lines
5.8 KiB
Vue

<template>
<div id="backgroud">
<div class="content_right">
<div class="login-body-title">
<h2>登录</h2>
</div>
<div class="messge">
<span>{{ msg }}</span>
</div>
<div class="cr_top">
<div class="ct_input" style="height: 60px;width: 254px">
<span class="ct-img-yhm">&nbsp;</span>
<input
id="username"
v-model.trim="username"
name="username"
class="input_text"
tabindex="1"
accesskey="n"
type="text"
size="25"
autocomplete="off"
placeholder="用户名"
@keyup.enter="handleLogin">
</div>
<div class="ct_input" style="height:60px;width: 254px">
<span class="ct_img_mm">&nbsp;</span>
<input
id="password"
v-model="password"
name="password"
class="input_text"
tabindex="2"
accesskey="p"
type="password"
size="25"
autocomplete="off"
placeholder="密码"
@keyup.enter="handleLogin">
</div>
<input class="btn_login" value="登录" @click="handleLogin">
</div>
<div class="account-oprate clearfix">
<router-link :to="{ name: 'register' }" class="regist-btn">注册</router-link>
</div>
</div>
</div>
</template>
<script>
import { Login } from '@/api/Userapi'
import { getRoleList, parseMenusFromRoleListResponse } from '@/api/rbacApi'
export default {
name: 'Login',
data() {
return {
msg: '',
username: '',
password: ''
}
},
methods: {
handleLogin() {
if (!this.username || !this.password) {
this.msg = 'username、password 为必传参数'
return
}
Login({
username: this.username,
password: this.password
}).then(res => {
if (res && res.code === 20000) {
const data = res.data || {}
const user = {
id: data.id,
username: data.username,
realName: data.real_name,
mobile: data.mobile,
email: data.email,
avatar: data.avatar,
status: data.status,
lastLoginTime: data.last_login_time,
createdBy: data.created_by,
createdTime: data.created_time,
updatedTime: data.updated_time,
roleIds: data.role_ids || []
}
localStorage.setItem('authUser', JSON.stringify(user))
if (data.token) {
localStorage.setItem('accessToken', data.token)
} else {
localStorage.removeItem('accessToken')
}
const rt = data.refresh_token || data.refreshToken
if (rt) {
localStorage.setItem('refreshToken', rt)
} else {
localStorage.removeItem('refreshToken')
}
this.$store.commit('SetCurrentUser', user)
this.$store.commit('SetRole', user.roleIds)
this.$store.commit('SetUserMenus', [])
this.loadUserMenus(user)
this.msg = ''
this.$message.success('登录成功')
this.$router.push({ path: '/effekt' })
} else {
this.msg = (res && res.message) || '用户名或密码错误!'
}
})
},
loadUserMenus(user) {
const roleId = user && user.roleIds && user.roleIds.length ? user.roleIds[0] : undefined
if (!roleId) {
return
}
getRoleList({ roleId }).then(res => {
this.$store.commit('SetUserMenus', parseMenusFromRoleListResponse(res))
}).catch(() => {})
}
}
}
</script>
<style scoped>
@import "../../assets/css/Form.css";
.content_right {
padding: 20px 0;
background: #fff;
color: #333;
border-radius: 3px;
border-color: rgba(250, 255, 251, .8);
box-shadow: inset 0 0 5px rgba(0, 0, 0, .1), 0 0 8px rgba(140, 141, 140, .6);
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
outline: 0;
width: 300px;
height: 300px;
text-align: center;
}
.cr_top .ct_input {
position: relative;
}
.account-oprate .regist-btn {
float: right;
font-size: 14px;
color: #333;
}
.messge {
font-size: 12px;
margin-top: 10px;
height: 20px;
text-align: left;
padding-left: 24px;
color: #D60909;
}
.content_right .cr_top {
position: relative;
margin: 0 23px 0;
}
.content_right .input_text {
margin-bottom: 18px;
background: #fff;
}
.account-oprate {
width: 252px;
margin-left: 24px;
}
.ct_img_mm,
.ct-img-yhm {
position: absolute;
top: 14px;
left: 8px;
width: 16px;
height: 16px;
background-image: url("https://t4.chei.com.cn/passport/images/login2014/icon_input.png");
}
.ct-img-yhm {
background-position: -16px 0;
}
.input_text {
display: inline-block;
width: 224px;
height: 24px;
padding: 8px 0 8px 28px;
font-size: 14px;
color: #000;
border: 1px solid #ccc;
border-radius: 3px;
vertical-align: middle;
}
.input_text:hover {
border-color: rgba(82, 168, 236, .8);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .1), 0 0 8px rgba(82, 168, 236, .6);
outline: 0;
}
.btn_login:hover {
background-color: #3e82dc;
}
.btn_login {
text-align: center;
box-sizing: border-box;
width: 254px;
height: 37px;
font-size: 16px;
cursor: pointer;
border-radius: 3px;
color: #fff;
border: 1px solid #4591f5;
background-color: #4591f5;
margin-bottom: 14px;
-webkit-appearance: none;
}
button,
input,
optgroup,
option,
select,
textarea {
font-family: inherit;
font-size: inherit;
font-style: inherit;
font-weight: inherit;
resize: none;
}
blockquote,
body,
button,
code,
dd,
div,
dl,
dt,
fieldset,
form,
h1,
h2,
h3,
h4,
h5,
h6,
input,
legend,
li,
ol,
p,
pre,
td,
textarea,
th,
ul {
margin: 0;
padding: 0;
font-family: '\5FAE\8F6F\96C5\9ED1', '\5B8B\4F53', Arial, Helvetica, sans-serif;
}
</style>