🐛 add interface access permissions

This commit is contained in:
landaiqing
2024-09-04 19:00:21 +08:00
parent 9b3a6d37de
commit ec6b0a9c9f
12 changed files with 94 additions and 54 deletions

View File

@@ -15,3 +15,20 @@ export const getUserDevice = (userId: string) => {
} }
); );
}; };
/**
* 生成客户端id
*/
export const generateClientId = () => {
return service.Get('/api/client/generate_client_id',
{
meta: {
ignoreToken: true,
},
cacheFor: {
mode: "restore",
expire: 1000 * 60 * 60 * 24 * 30 // 30天
}
}
);
};

View File

@@ -1,21 +1,5 @@
import {service} from "@/utils/alova/service.ts"; import {service} from "@/utils/alova/service.ts";
/**
* 生成客户端id
*/
export const generateClientId = () => {
return service.Get('/api/oauth/wechat/generate_client_id',
{
meta: {
ignoreToken: true,
},
cacheFor: {
mode: "restore",
expire: 1000 * 60 * 60 * 24 * 30 // 30天
}
}
);
};
/** /**
* 获取临时二维码 * 获取临时二维码
* @param clientId * @param clientId

View File

@@ -55,6 +55,7 @@ export const phoneLoginApi = (param: PhoneLogin) => {
return service.Post('/api/user/phone_login', { return service.Post('/api/user/phone_login', {
phone: param.phone, phone: param.phone,
captcha: param.captcha, captcha: param.captcha,
auto_login: param.auto_login
}, },
{ {
meta: { meta: {
@@ -72,6 +73,7 @@ export const accountLoginApi = (param: AccountLogin) => {
return service.Post('/api/user/login', { return service.Post('/api/user/login', {
account: param.account, account: param.account,
password: param.password, password: param.password,
auto_login: param.auto_login
}, },
{ {
meta: { meta: {
@@ -99,3 +101,18 @@ export const resetPasswordApi = (param: ResetPassword) => {
} }
); );
}; };
/**
* 获取用户权限
* @param user_id
*/
export const getUserPermissions = (user_id: string) => {
return service.Get('/api/auth/permission/get_user_permissions', {
params: {
user_id: user_id
},
meta: {
ignoreToken: false,
}
}
);
};

View File

@@ -77,6 +77,6 @@ export default {
authTokenExpired: "认证过期,请重新登录!", authTokenExpired: "认证过期,请重新登录!",
loginExpired: "登录已过期!", loginExpired: "登录已过期!",
pleaseLogin: "请先登录!", pleaseLogin: "请先登录!",
loginExpiredDesc: "该账号在其他地方登录,请重新登录!" loginExpiredDesc: "该账号在其他地方登录,请刷新后重新登录!"
} }
}; };

View File

@@ -28,11 +28,13 @@ const router: Router = createRouter({
router.beforeEach((to, _from, next) => { router.beforeEach((to, _from, next) => {
start(); start();
const user = useStore().user; const user = useStore().user;
const client = useStore().client;
const token: string | undefined = user.user.refreshToken; const token: string | undefined = user.user.refreshToken;
const userId: string | undefined = user.user.userId; const userId: string | undefined = user.user.userId;
const clientId: string | undefined = client.getClientId();
// 检查用户是否已登录 // 检查用户是否已登录
const isLoggedIn: boolean = token !== "" && userId !== ""; const isLoggedIn: boolean = token !== "" && userId !== "" && clientId !== "";
if (to.path === '/login' || to.path === '/qrlogin' || to.path === '/resetpass') { if (to.path === '/login' || to.path === '/qrlogin' || to.path === '/resetpass') {
if (isLoggedIn) { if (isLoggedIn) {

View File

@@ -35,13 +35,13 @@ const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication
} else { } else {
message.error(i18n.global.t('error.loginExpired')); message.error(i18n.global.t('error.loginExpired'));
localStorage.removeItem('user'); localStorage.removeItem('user');
await router.push('/login'); router.push('/login').then();
} }
} catch (error: any) { } catch (error: any) {
console.error(error); console.error(error);
message.error(i18n.global.t('error.loginExpired')); message.error(i18n.global.t('error.loginExpired'));
localStorage.removeItem('user'); localStorage.removeItem('user');
await router.push('/login'); router.push('/login').then();
} }
} }
} }
@@ -68,27 +68,33 @@ export const service = createAlova({
} }
const lang = useStore().lang; const lang = useStore().lang;
method.config.headers['Accept-Language'] = lang.lang || 'zh'; method.config.headers['Accept-Language'] = lang.lang || 'zh';
const client = useStore().client;
method.config.headers['X-Request-Id'] = client.getClientId() || '';
}), }),
// 响应拦截器 // 响应拦截器
responded: onResponseRefreshToken({ responded: onResponseRefreshToken({
onSuccess: async (response: AxiosResponse, _method: any) => { onSuccess: async (response: AxiosResponse, _method: any) => {
if (response.data instanceof Blob) { if (response.data instanceof Blob) {
return response; return response;
} else { }
if (response.data.code === 403) { const {code} = response.data;
if (code === 403) {
notification.error({ notification.error({
placement: 'topRight', placement: 'topRight',
duration: 5,
message: i18n.global.t('error.loginExpired'), message: i18n.global.t('error.loginExpired'),
description: i18n.global.t('error.loginExpiredDesc'), description: i18n.global.t('error.loginExpiredDesc'),
onClose: () => { onClose: () => {
localStorage.removeItem('user'); localStorage.removeItem('user');
router.push('/login'); router.push('/login').then();
} }
}); });
throw new Error('Authentication Expired');
} else { } else {
return response.data; return response.data;
} }
}
}, },
onError: onError:
(error: AxiosError, _method: any) => { (error: AxiosError, _method: any) => {

View File

@@ -6,6 +6,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.400"), content: i18n.global.t("error.400"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -14,6 +15,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.401"), content: i18n.global.t("error.401"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -22,6 +24,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.403"), content: i18n.global.t("error.403"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -30,6 +33,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.404"), content: i18n.global.t("error.404"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -38,6 +42,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.408"), content: i18n.global.t("error.408"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -46,6 +51,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.500"), content: i18n.global.t("error.500"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -54,6 +60,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.501"), content: i18n.global.t("error.501"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -62,6 +69,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.502"), content: i18n.global.t("error.502"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -70,6 +78,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.503"), content: i18n.global.t("error.503"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -78,6 +87,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.504"), content: i18n.global.t("error.504"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -86,6 +96,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.505"), content: i18n.global.t("error.505"),
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();
@@ -94,6 +105,7 @@ export function handleCode(code: number): void {
message message
.open({ .open({
content: i18n.global.t("error.other") + `(${code})`, content: i18n.global.t("error.other") + `(${code})`,
duration: 5,
type: "error", type: "error",
}) })
.then(); .then();

View File

@@ -27,10 +27,9 @@ import {getGiteeUrl} from "@/api/oauth/gitee.ts";
import useStore from "@/store"; import useStore from "@/store";
import {message} from "ant-design-vue"; import {message} from "ant-design-vue";
import gitee from "@/assets/svgs/gitee.svg"; import gitee from "@/assets/svgs/gitee.svg";
import {generateClientId} from "@/api/oauth/wechat.ts";
import {getQQUrl} from "@/api/oauth/qq.ts"; import {getQQUrl} from "@/api/oauth/qq.ts";
import {useDebounceFn} from "@vueuse/core"; import {useDebounceFn} from "@vueuse/core";
import {getUserDevice} from "@/api/oauth"; import {generateClientId, getUserDevice} from "@/api/oauth";
const router = useRouter(); const router = useRouter();
const {t} = useI18n(); const {t} = useI18n();

View File

@@ -333,7 +333,7 @@ async function sendCaptcha() {
/** /**
* 账号登录 防抖 * 账号登录 防抖
*/ */
const accountLoginSubmitDebounce = useDebounceFn(accountLoginSubmit, 3000); const accountLoginSubmitDebounce = useDebounceFn(accountLoginSubmit, 1000);
/** /**
* 账号登录提交 * 账号登录提交
@@ -354,7 +354,7 @@ async function accountLoginSubmit() {
/** /**
* 手机登录提交 防抖 * 手机登录提交 防抖
*/ */
const phoneLoginSubmitDebounce = useDebounceFn(phoneLoginSubmit, 3000); const phoneLoginSubmitDebounce = useDebounceFn(phoneLoginSubmit, 1000);
/** /**
* 手机登录提交 * 手机登录提交

View File

@@ -1,19 +1,23 @@
<template> <template>
<div> <div>
<h1>Welcome to Main Page</h1> <h1>Welcome to Main Page</h1>
<!-- <AButton @click="handleClick">获取用户数据</AButton>--> <AButton @click="handleClick">获取登录用户角色</AButton>
{{ data }}
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
// import {useRequest} from "alova/client"; import {useRequest} from "alova/client";
// import {getUserInfo} from "@/api/user"; import {getUserPermissions} from "@/api/user";
// import useStore from "@/store";
// const {data, send} = useRequest(getUserInfo, {
// immediate: false const {data, send} = useRequest(getUserPermissions, {
// }); immediate: false
// const handleClick = () => { });
// send(); const handleClick = () => {
// }; const userInfo = useStore().user;
const userId: string = userInfo.user.uid;
send(userId);
};
</script> </script>
<style scoped> <style scoped>

View File

@@ -57,13 +57,13 @@ import {useI18n} from "vue-i18n";
import BoxDog from "@/components/BoxDog/BoxDog.vue"; import BoxDog from "@/components/BoxDog/BoxDog.vue";
import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue"; import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue";
import {useRouter} from 'vue-router'; import {useRouter} from 'vue-router';
import {generateClientId, generateQrCode} from "@/api/oauth/wechat.ts"; import {generateQrCode} from "@/api/oauth/wechat.ts";
import {onMounted, onUnmounted, ref} from "vue"; import {onMounted, onUnmounted, ref} from "vue";
import logo from "@/assets/svgs/logo-schisandra.svg"; import logo from "@/assets/svgs/logo-schisandra.svg";
import useWebSocket from "@/utils/websocket/websocket.ts"; import useWebSocket from "@/utils/websocket/websocket.ts";
import useStore from "@/store"; import useStore from "@/store";
import {message} from "ant-design-vue"; import {message} from "ant-design-vue";
import {getUserDevice} from "@/api/oauth"; import {generateClientId, getUserDevice} from "@/api/oauth";
const {t} = useI18n(); const {t} = useI18n();
@@ -94,7 +94,7 @@ async function getQrCode() {
await getClientId(); await getClientId();
await getQrCode(); await getQrCode();
} else { } else {
const res: any = await generateQrCode(client.getClientId() as string); const res: any = await generateQrCode(client.getClientId() || "");
if (res.code === 0 && res.data) { if (res.code === 0 && res.data) {
status.value = 'active'; status.value = 'active';
qrcode.value = res.data; qrcode.value = res.data;
@@ -118,7 +118,7 @@ function getLocalClientId() {
} }
const wsOptions = { const wsOptions = {
url: import.meta.env.VITE_WEB_SOCKET_URL as string + "?client_id=" + getLocalClientId(), url: import.meta.env.VITE_WEB_SOCKET_URL + "?client_id=" + getLocalClientId(),
}; };
const {open, close, on} = useWebSocket(wsOptions); const {open, close, on} = useWebSocket(wsOptions);

View File

@@ -27,10 +27,9 @@ import {getGiteeUrl} from "@/api/oauth/gitee.ts";
import useStore from "@/store"; import useStore from "@/store";
import {message} from "ant-design-vue"; import {message} from "ant-design-vue";
import gitee from "@/assets/svgs/gitee.svg"; import gitee from "@/assets/svgs/gitee.svg";
import {generateClientId} from "@/api/oauth/wechat.ts";
import {getQQUrl} from "@/api/oauth/qq.ts"; import {getQQUrl} from "@/api/oauth/qq.ts";
import {useDebounceFn} from "@vueuse/core"; import {useDebounceFn} from "@vueuse/core";
import {getUserDevice} from "@/api/oauth"; import {generateClientId, getUserDevice} from "@/api/oauth";
const router = useRouter(); const router = useRouter();
const {t} = useI18n(); const {t} = useI18n();