Skip to content

feat login #407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import request from '../utils/request';

interface LoginParams {
account: string;
password: string;
}

export const fetchLogin = (data: LoginParams) => {
return request({
url: '/auth/login',
method: 'post',
data: data
})
}
Binary file added src/assets/img/login-bg-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/utils/authToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 管理登录token
const TOKEN_KEY = 'authToken';

export const getToken = () => {
return localStorage.getItem(TOKEN_KEY);
};

export const saveToken = (token) => {
localStorage.setItem(TOKEN_KEY, token);
};

export const removeToken = () => {
localStorage.removeItem(TOKEN_KEY);
};
8 changes: 7 additions & 1 deletion src/utils/request.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import axios, { AxiosInstance, AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { getToken } from '@/utils/authToken';

const service: AxiosInstance = axios.create({
timeout: 5000
timeout: 5000,
baseURL: 'http://8.141.28.90:80',
headers: {
// 传递 token
token: getToken(),
},
});

service.interceptors.request.use(
Expand Down
277 changes: 164 additions & 113 deletions src/views/pages/login.vue
Original file line number Diff line number Diff line change
@@ -1,171 +1,222 @@
<template>
<div class="login-bg">
<div class="login-container">
<div class="login-header">
<img class="logo mr10" src="../../assets/img/logo.svg" alt="" />
<div class="login-title">后台管理系统</div>
</div>
<el-form :model="param" :rules="rules" ref="login" size="large">
<el-form-item prop="username">
<el-input v-model="param.username" placeholder="用户名">
<template #prepend>
<el-icon>
<User />
</el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="密码"
v-model="param.password"
@keyup.enter="submitForm(login)"
>
<template #prepend>
<el-icon>
<Lock />
</el-icon>
</template>
</el-input>
</el-form-item>
<div class="pwd-tips">
<el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" />
<el-link type="primary" @click="$router.push('/reset-pwd')">忘记密码</el-link>
</div>
<el-button class="login-btn" type="primary" size="large" @click="submitForm(login)">登录</el-button>
<p class="login-tips">Tips : 用户名和密码随便填。</p>
<div class="login-bg">
<div>
<div class="sys-name">
<div class="">智慧设备监控平台</div>
</div>
<div class="login-container">
<div class="login-header">
<!-- <img class="logo mr10" src="../../assets/img/logo.svg" alt="" /> -->
<div class="login-title">管理员登录</div>
</div>
<el-form :model="param" :rules="rules" ref="login" size="large">
<el-form-item prop="username">
<el-input v-model="param.username" placeholder="用户名">
<template #prepend>
<el-icon>
<User />
</el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="密码"
v-model="param.password"
show-password
@keyup.enter="submitForm(login)"
>
<template #prepend>
<el-icon>
<Lock />
</el-icon>
</template>
</el-input>
</el-form-item>
<div class="pwd-tips">
<el-checkbox
style="color: #0e83fc"
class="pwd-checkbox"
v-model="checked"
label="记住密码"
/>
<el-link
style="color: #0e83fc"
type="primary"
@click="$router.push('/reset-pwd')"
>忘记密码</el-link
>
</div>
<el-button
class="login-btn"
type="primary"
size="large"
@click="submitForm(login)"
>登录</el-button
>
<!-- <p class="login-tips">Tips : 用户名和密码随便填。</p>
<p class="login-text">
没有账号?<el-link type="primary" @click="$router.push('/register')">立即注册</el-link>
</p>
</el-form>
</div>
</p> -->
</el-form>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue';
import { useTabsStore } from '@/store/tabs';
import { usePermissStore } from '@/store/permiss';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus';

interface LoginInfo {
username: string;
password: string;
}

const lgStr = localStorage.getItem('login-param');
const defParam = lgStr ? JSON.parse(lgStr) : null;
const checked = ref(lgStr ? true : false);

const router = useRouter();
const param = reactive<LoginInfo>({
import { ref, reactive } from 'vue'
import { useTabsStore } from '@/store/tabs'
import { usePermissStore } from '@/store/permiss'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { fetchLogin } from '@/api/auth'
import { saveToken } from '@/utils/authToken'

interface LoginForm {
username: string
password: string
}

const lgStr = localStorage.getItem('login-param')
const defParam = lgStr ? JSON.parse(lgStr) : null
const checked = ref(lgStr ? true : false)

const router = useRouter()
const param = reactive<LoginForm>({
username: defParam ? defParam.username : '',
password: defParam ? defParam.password : '',
});
})

const rules: FormRules = {
const rules: FormRules = {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur',
},
{
required: true,
message: '请输入用户名',
trigger: 'blur',
},
],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
};
const permiss = usePermissStore();
const login = ref<FormInstance>();
const submitForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
}
const permiss = usePermissStore()
const login = ref<FormInstance>()
const submitForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.validate((valid: boolean) => {
if (valid) {
ElMessage.success('登录成功');
localStorage.setItem('vuems_name', param.username);
const keys = permiss.defaultList[param.username == 'admin' ? 'admin' : 'user'];
permiss.handleSet(keys);
router.push('/');
if (checked.value) {
localStorage.setItem('login-param', JSON.stringify(param));
} else {
localStorage.removeItem('login-param');
if (valid) {
fetchLogin({ account: param.username, password: param.password })
.then((res) => {
if (res.code != 200) return ElMessage.error('登录失败')
else {
ElMessage.success('登录成功')
// 存储token
saveToken(res.data.token)
// 存储用户名
localStorage.setItem('vuems_name', param.username)
// 设置权限
const keys =
permiss.defaultList[
param.username == 'admin' ? 'admin' : 'user'
]
permiss.handleSet(keys)

router.push('/')
// 记住密码
if (checked.value) {
localStorage.setItem('login-param', JSON.stringify(param))
} else {
localStorage.removeItem('login-param')
}
}
} else {
ElMessage.error('登录失败');
return false;
}
});
};

const tabs = useTabsStore();
tabs.clearTabs();
})
.catch(() => {
ElMessage.error('登录失败')
})
} else {
ElMessage.error('登录失败')
return false
}
})
}

const tabs = useTabsStore()
tabs.clearTabs()
</script>

<style scoped>
.login-bg {
.login-bg {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background: url(../../assets/img/login-bg.jpg) center/cover no-repeat;
}
background: url(../../assets/img/login-bg-1.jpg) center/cover no-repeat;
}

.login-header {
.login-header {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 40px;
}
}

.logo {
.logo {
width: 35px;
}
}

.login-title {
.login-title {
font-size: 22px;
color: #333;
font-weight: bold;
}
/* font-weight: bold; */
}

.login-container {
width: 450px;
.login-container {
width: 350px;
border-radius: 5px;
background: #fff;
padding: 40px 50px 50px;
background: rgba(255, 255, 255, 0.5);
padding: 40px 24px 50px;
box-sizing: border-box;
}
}

.pwd-tips {
.pwd-tips {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
margin: -10px 0 10px;
color: #787878;
}
}

.pwd-checkbox {
.pwd-checkbox {
height: auto;
}
}

.login-btn {
.login-btn {
display: block;
width: 100%;
}
background: #0e83fc;
}

.login-tips {
.login-tips {
font-size: 12px;
color: #999;
}
}

.login-text {
.login-text {
display: flex;
align-items: center;
margin-top: 20px;
font-size: 14px;
color: #787878;
}
}

.sys-name {
font-size: 30px;
font-weight: bold;
text-align: center;
margin-bottom: 50px;
color: #fff;
}
</style>