refactor: 项目优化和对接新后端框架
Former-commit-id: 11bd4366f6f0f9f3fb2213606f61cdb7b4c635a1
This commit is contained in:
@@ -1,38 +0,0 @@
|
|||||||
import { Captcha, LoginFormData, LoginResponseData } from '@/types/api/login';
|
|
||||||
import request from '@/utils/request';
|
|
||||||
import { AxiosPromise } from 'axios';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export function login(data: LoginFormData): AxiosPromise<LoginResponseData> {
|
|
||||||
return request({
|
|
||||||
url: '/youlai-auth/oauth/token',
|
|
||||||
method: 'post',
|
|
||||||
params: data,
|
|
||||||
headers: {
|
|
||||||
Authorization: 'Basic bWFsbC1hZG1pbi13ZWI6MTIzNDU2' // 客户端信息Base64明文:mall-admin-web:123456
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注销
|
|
||||||
*/
|
|
||||||
export function logout() {
|
|
||||||
return request({
|
|
||||||
url: '/youlai-auth/oauth/logout',
|
|
||||||
method: 'delete'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取图片验证码
|
|
||||||
*/
|
|
||||||
export function getCaptcha(): AxiosPromise<Captcha> {
|
|
||||||
return request({
|
|
||||||
url: '/captcha?t=' + new Date().getTime().toString(),
|
|
||||||
method: 'get'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,34 @@ import {
|
|||||||
UserFormData,
|
UserFormData,
|
||||||
UserInfo,
|
UserInfo,
|
||||||
UserPageResult,
|
UserPageResult,
|
||||||
UserQueryParam
|
UserQueryParam,
|
||||||
|
LoginFormData
|
||||||
} from '@/types/api/user';
|
} from '@/types/api/user';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*/
|
||||||
|
export function login(data: LoginFormData): AxiosPromise {
|
||||||
|
return request({
|
||||||
|
url: '/youlai-auth/oauth2/token',
|
||||||
|
method: 'post',
|
||||||
|
params: data,
|
||||||
|
headers: {
|
||||||
|
Authorization: 'Basic dnVlMy1lbGVtZW50LWFkbWluOnNlY3JldA==' // 客户端信息Base64明文:vue3-element-admin:secret
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销
|
||||||
|
*/
|
||||||
|
export function logout() {
|
||||||
|
return request({
|
||||||
|
url: '/youlai-auth/oauth/logout',
|
||||||
|
method: 'delete'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录成功后获取用户信息(昵称、头像、权限集合和角色集合)
|
* 登录成功后获取用户信息(昵称、头像、权限集合和角色集合)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import useStore from '@/store';
|
import useStore from '@/store';
|
||||||
import { hasLogin } from '@/utils/auth';
|
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
NProgress.configure({ showSpinner: false }); // 进度环显示/隐藏
|
NProgress.configure({ showSpinner: false }); // 进度环显示/隐藏
|
||||||
@@ -12,8 +11,8 @@ const whiteList = ['/login'];
|
|||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
const { user, permission } = useStore();
|
const { user, permission } = useStore();
|
||||||
|
const hasToken = user.token;
|
||||||
if (hasLogin()) {
|
if (hasToken) {
|
||||||
// 登录成功,跳转到首页
|
// 登录成功,跳转到首页
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
next({ path: '/' });
|
next({ path: '/' });
|
||||||
@@ -29,7 +28,7 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
await user.getUserInfo();
|
await user.getUserInfo();
|
||||||
const roles = user.roles;
|
const roles = user.roles || ['ROOT'];
|
||||||
const accessRoutes: any = await permission.generateRoutes(roles);
|
const accessRoutes: any = await permission.generateRoutes(roles);
|
||||||
accessRoutes.forEach((route: any) => {
|
accessRoutes.forEach((route: any) => {
|
||||||
router.addRoute(route);
|
router.addRoute(route);
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { LoginFormData } from '@/types/api/login';
|
import { LoginFormData } from '@/types/api/user';
|
||||||
import { UserState } from '@/types/store/user';
|
import { UserState } from '@/types/store/user';
|
||||||
|
|
||||||
import { localStorage } from '@/utils/storage';
|
import { localStorage } from '@/utils/storage';
|
||||||
import { login, logout } from '@/api/login';
|
import { getUserInfo, login, logout } from '@/api/user';
|
||||||
import { getUserInfo } from '@/api/user';
|
|
||||||
import { resetRouter } from '@/router';
|
import { resetRouter } from '@/router';
|
||||||
|
|
||||||
const useUserStore = defineStore({
|
const useUserStore = defineStore({
|
||||||
@@ -21,19 +20,18 @@ const useUserStore = defineStore({
|
|||||||
this.$reset();
|
this.$reset();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录 login
|
||||||
*/
|
*/
|
||||||
login(loginData: LoginFormData) {
|
login(loginData: LoginFormData) {
|
||||||
const { username, password, code, uuid } = loginData;
|
const { username, password } = loginData;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login({
|
login({
|
||||||
|
grant_type: 'password',
|
||||||
username: username.trim(),
|
username: username.trim(),
|
||||||
password: password,
|
password: password
|
||||||
grant_type: 'captcha',
|
|
||||||
code: code,
|
|
||||||
uuid: uuid
|
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
console.log('response.data', response.data);
|
||||||
const { access_token, token_type } = response.data;
|
const { access_token, token_type } = response.data;
|
||||||
const accessToken = token_type + ' ' + access_token;
|
const accessToken = token_type + ' ' + access_token;
|
||||||
localStorage.set('token', accessToken);
|
localStorage.set('token', accessToken);
|
||||||
|
|||||||
26
src/types/api/login.d.ts
vendored
26
src/types/api/login.d.ts
vendored
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* 登录表单类型声明
|
|
||||||
*/
|
|
||||||
export interface LoginFormData {
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
grant_type: string;
|
|
||||||
code: string;
|
|
||||||
uuid: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录响应类型声明
|
|
||||||
*/
|
|
||||||
export interface LoginResponseData {
|
|
||||||
access_token: string;
|
|
||||||
token_type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码类型声明
|
|
||||||
*/
|
|
||||||
export interface Captcha {
|
|
||||||
img: string;
|
|
||||||
uuid: string;
|
|
||||||
}
|
|
||||||
21
src/types/api/user.d.ts
vendored
21
src/types/api/user.d.ts
vendored
@@ -1,7 +1,24 @@
|
|||||||
import { PageQueryParam, PageResult } from './base';
|
import { PageQueryParam, PageResult } from './base';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录用户类型声明
|
* 登录表单
|
||||||
|
*/
|
||||||
|
export interface LoginFormData {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
grant_type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录响应
|
||||||
|
*/
|
||||||
|
export interface LoginResponseData {
|
||||||
|
access_token: string;
|
||||||
|
token_type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录用户信息
|
||||||
*/
|
*/
|
||||||
export interface UserInfo {
|
export interface UserInfo {
|
||||||
nickname: string;
|
nickname: string;
|
||||||
@@ -11,7 +28,7 @@ export interface UserInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户查询参数类型声明
|
* 用户查询参数
|
||||||
*/
|
*/
|
||||||
export interface UserQueryParam extends PageQueryParam {
|
export interface UserQueryParam extends PageQueryParam {
|
||||||
keywords: string;
|
keywords: string;
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
import Cookies from 'js-cookie';
|
|
||||||
|
|
||||||
const SESSION_ID_KEY = 'GATEWAY_SESSION_ID';
|
|
||||||
|
|
||||||
export const hasLogin = () => {
|
|
||||||
const sessionId = Cookies.get(SESSION_ID_KEY);
|
|
||||||
console.log('sessionId', sessionId);
|
|
||||||
if (sessionId) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -33,19 +33,21 @@ service.interceptors.request.use(
|
|||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response: AxiosResponse) => {
|
(response: AxiosResponse) => {
|
||||||
const { code, msg } = response.data;
|
const { code, msg } = response.data;
|
||||||
if (code === '00000') {
|
if (code) {
|
||||||
return response.data;
|
// 有状态码判断是否为00000,除此皆为异常响应
|
||||||
} else {
|
if (code === '00000') {
|
||||||
// 响应数据为二进制流处理(Excel导出)
|
return response.data;
|
||||||
if (response.data instanceof ArrayBuffer) {
|
} else {
|
||||||
return response;
|
ElMessage({
|
||||||
|
message: response.data.msg || '系统出错',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
return Promise.reject(new Error(msg || 'Error'));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
ElMessage({
|
// 无状态码响应直接返回
|
||||||
message: msg || '系统出错',
|
console.log('response', response);
|
||||||
type: 'error'
|
return response;
|
||||||
});
|
|
||||||
return Promise.reject(new Error(msg || 'Error'));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
@@ -53,7 +55,6 @@ service.interceptors.response.use(
|
|||||||
if (code === 'A0230') {
|
if (code === 'A0230') {
|
||||||
// token 过期
|
// token 过期
|
||||||
localStorage.clear(); // 清除浏览器全部缓存
|
localStorage.clear(); // 清除浏览器全部缓存
|
||||||
//window.location.href = '/'; // 跳转登录页
|
|
||||||
ElMessageBox.alert('当前页面已失效,请重新登录', '提示', {});
|
ElMessageBox.alert('当前页面已失效,请重新登录', '提示', {});
|
||||||
} else {
|
} else {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
|
|||||||
@@ -58,28 +58,6 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<!-- 验证码 -->
|
|
||||||
<el-form-item prop="code">
|
|
||||||
<span class="svg-container">
|
|
||||||
<svg-icon icon-class="valid_code" />
|
|
||||||
</span>
|
|
||||||
<el-input
|
|
||||||
v-model="loginForm.code"
|
|
||||||
auto-complete="off"
|
|
||||||
:placeholder="$t('login.code')"
|
|
||||||
style="width: 65%"
|
|
||||||
@keyup.enter="handleLogin"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="captcha">
|
|
||||||
<img
|
|
||||||
:src="captchaBase64"
|
|
||||||
@click="handleCaptchaGenerate"
|
|
||||||
height="38px"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-button
|
<el-button
|
||||||
size="default"
|
size="default"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@@ -120,9 +98,8 @@ import SvgIcon from '@/components/SvgIcon/index.vue';
|
|||||||
import useStore from '@/store';
|
import useStore from '@/store';
|
||||||
|
|
||||||
// API依赖
|
// API依赖
|
||||||
import { getCaptcha } from '@/api/login';
|
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { LoginFormData } from '@/types/api/login';
|
import { LoginFormData } from '@/types/api/user';
|
||||||
|
|
||||||
const { user } = useStore();
|
const { user } = useStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -134,9 +111,7 @@ const state = reactive({
|
|||||||
redirect: '',
|
redirect: '',
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: 'admin',
|
username: 'admin',
|
||||||
password: '123456',
|
password: '123456'
|
||||||
code: '',
|
|
||||||
uuid: ''
|
|
||||||
} as LoginFormData,
|
} as LoginFormData,
|
||||||
loginRules: {
|
loginRules: {
|
||||||
username: [{ required: true, trigger: 'blur' }],
|
username: [{ required: true, trigger: 'blur' }],
|
||||||
@@ -144,7 +119,6 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
passwordType: 'password',
|
passwordType: 'password',
|
||||||
captchaBase64: '',
|
|
||||||
// 大写提示禁用
|
// 大写提示禁用
|
||||||
capslockTooltipDisabled: true,
|
capslockTooltipDisabled: true,
|
||||||
otherQuery: {},
|
otherQuery: {},
|
||||||
@@ -166,10 +140,8 @@ const {
|
|||||||
loginRules,
|
loginRules,
|
||||||
loading,
|
loading,
|
||||||
passwordType,
|
passwordType,
|
||||||
captchaBase64,
|
|
||||||
capslockTooltipDisabled,
|
capslockTooltipDisabled,
|
||||||
showCopyright,
|
showCopyright
|
||||||
showDialog
|
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
function checkCapslock(e: any) {
|
function checkCapslock(e: any) {
|
||||||
@@ -179,10 +151,10 @@ function checkCapslock(e: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showPwd() {
|
function showPwd() {
|
||||||
if (state.passwordType === 'password') {
|
if (passwordType.value === 'password') {
|
||||||
state.passwordType = '';
|
passwordType.value = '';
|
||||||
} else {
|
} else {
|
||||||
state.passwordType = 'password';
|
passwordType.value = 'password';
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
passwordRef.value.focus();
|
passwordRef.value.focus();
|
||||||
@@ -190,7 +162,7 @@ function showPwd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* login
|
* 登录处理
|
||||||
*/
|
*/
|
||||||
function handleLogin() {
|
function handleLogin() {
|
||||||
loginFormRef.value.validate((valid: boolean) => {
|
loginFormRef.value.validate((valid: boolean) => {
|
||||||
@@ -204,9 +176,6 @@ function handleLogin() {
|
|||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|
||||||
// 生成验证码
|
|
||||||
handleCaptchaGenerate();
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -214,17 +183,6 @@ function handleLogin() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取验证码
|
|
||||||
*/
|
|
||||||
function handleCaptchaGenerate() {
|
|
||||||
getCaptcha().then(({ data }) => {
|
|
||||||
const { img, uuid } = data;
|
|
||||||
state.captchaBase64 = img;
|
|
||||||
state.loginForm.uuid = uuid;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
route,
|
route,
|
||||||
() => {
|
() => {
|
||||||
@@ -249,7 +207,6 @@ function getOtherQuery(query: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleCaptchaGenerate();
|
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
if (state.clientHeight > document.documentElement.clientHeight) {
|
if (state.clientHeight > document.documentElement.clientHeight) {
|
||||||
state.showCopyright = false;
|
state.showCopyright = false;
|
||||||
@@ -261,9 +218,6 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/* 修复input 背景不协调 和光标变色 */
|
|
||||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
|
||||||
|
|
||||||
$bg: #283443;
|
$bg: #283443;
|
||||||
$light_gray: #fff;
|
$light_gray: #fff;
|
||||||
$cursor: #fff;
|
$cursor: #fff;
|
||||||
|
|||||||
Reference in New Issue
Block a user