Add centralized API client with axios interceptors, remove vue-axios

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 12:44:33 +08:00
parent 6af7253d08
commit 147b16ca34
29 changed files with 301 additions and 270 deletions

33
src/api/auth.js Normal file
View File

@@ -0,0 +1,33 @@
import axios from 'axios';
import { getCookie, setCookie, setCookieWithoutExpiration } from '@/utils/cookieUtil.js';
/**
* Refresh the access token using the refresh token cookie.
* Uses plain axios (not apiClient) to avoid interceptor loops.
* @returns {Promise<string>} The new access token.
*/
export async function refreshTokenAndGetNew() {
const api = '/api/oauth/token';
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
const data = {
grant_type: 'refresh_token',
refresh_token: getCookie('luciaRefreshToken'),
};
const response = await axios.post(api, data, config);
const newAccessToken = response.data.access_token;
const newRefreshToken = response.data.refresh_token;
setCookieWithoutExpiration('luciaToken', newAccessToken);
// Expire in ~6 months
const expiredMs = new Date();
expiredMs.setMonth(expiredMs.getMonth() + 6);
const days = Math.ceil((expiredMs.getTime() - Date.now()) / (24 * 60 * 60 * 1000));
setCookie('luciaRefreshToken', newRefreshToken, days);
return newAccessToken;
}

78
src/api/client.js Normal file
View File

@@ -0,0 +1,78 @@
import axios from 'axios';
import { getCookie, deleteCookie } from '@/utils/cookieUtil.js';
const apiClient = axios.create();
// Request interceptor: automatically attach Authorization header
apiClient.interceptors.request.use((config) => {
const token = getCookie('luciaToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response interceptor: handle 401 by attempting token refresh
let isRefreshing = false;
let pendingRequests = [];
function onRefreshSuccess(newToken) {
pendingRequests.forEach((cb) => cb(newToken));
pendingRequests = [];
}
function onRefreshFailure(error) {
pendingRequests.forEach((cb) => cb(null, error));
pendingRequests = [];
}
apiClient.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
// Only attempt refresh on 401, and not for auth endpoints or already-retried requests
if (
error.response?.status !== 401 ||
originalRequest._retried ||
originalRequest.url === '/api/oauth/token'
) {
return Promise.reject(error);
}
if (isRefreshing) {
// Queue this request until the refresh completes
return new Promise((resolve, reject) => {
pendingRequests.push((newToken, err) => {
if (err) return reject(err);
originalRequest.headers.Authorization = `Bearer ${newToken}`;
originalRequest._retried = true;
resolve(apiClient(originalRequest));
});
});
}
isRefreshing = true;
originalRequest._retried = true;
try {
// Dynamic import to avoid circular dependency with login store
const { refreshTokenAndGetNew } = await import('@/api/auth.js');
const newToken = await refreshTokenAndGetNew();
isRefreshing = false;
onRefreshSuccess(newToken);
originalRequest.headers.Authorization = `Bearer ${newToken}`;
return apiClient(originalRequest);
} catch (refreshError) {
isRefreshing = false;
onRefreshFailure(refreshError);
// Refresh failed: clear auth and redirect to login
deleteCookie('luciaToken');
window.location.href = '/login';
return Promise.reject(refreshError);
}
}
);
export default apiClient;

View File

@@ -3,8 +3,6 @@ import { createApp, markRaw } from "vue";
import App from "./App.vue";
import router from "./router";
import pinia from '@/stores/main.js';
import axios from 'axios';
import VueAxios from 'vue-axios';
import moment from 'moment';
import mitt from 'mitt';
import ToastPlugin from 'vue-toast-notification';
@@ -49,15 +47,9 @@ import ContextMenu from 'primevue/contextmenu';
const emitter = mitt();
const app = createApp(App);
// 將 Axios 實例添加到 Vue 的應用實例中
app.config.globalProperties.$http = axios;
app.$http = axios; // 將 $http 添加到 Vue 實例中
// Pinia Set
pinia.use(({ store }) => {
store.$router = markRaw(router);
store.$axios = markRaw(axios);
store.$toast = markRaw(ToastPlugin);
store.$http = app.$http;
});
// can use `this.$moment` in Vue.js
@@ -72,7 +64,6 @@ cytoscape.use( popper((ref) => ref) );
app.use(pinia);
app.use(router);
app.use(VueAxios, axios);
app.use(VueSweetalert2);
app.use(ToastPlugin, { // use `this.$toast` in Vue.js
position: 'bottom',

View File

@@ -1,25 +1,17 @@
import router from "@/router/index";
import loadingStore from '@/stores/loading.js';
import {useToast} from 'vue-toast-notification';
import 'vue-toast-notification/dist/theme-sugar.css';
import axios from "axios";
import { deleteCookie } from "@/utils/cookieUtil.js";
// Delay loading and toast
const delay = (s = 0) => new Promise((resolve, reject) => setTimeout(resolve, s));
/**
* API catch error function
* @param {object} Error 後端 ERROR
* API catch error function.
* 401 errors are handled by the axios response interceptor in api/client.js.
* @param {object} error 後端 ERROR
* @param {string} toastMessage Toast 的提示文字
* @returns {string} Error HTTP Status
*/
export default async function apiError(error, toastMessage) {
if(error.request?.status === 401) {
delete axios.defaults.headers.common["Authorization"];
deleteCookie("luciaToken");
return router.push('/login');
}
const loading = loadingStore();
const $toast = useToast();
await delay();

View File

@@ -1,4 +1,5 @@
import { defineStore } from 'pinia';
import apiClient from '@/api/client.js';
import apiError from '@/module/apiError';
import piniaLoginStore from '@/stores/login';
import { JUST_CREATE_ACCOUNT_HOT_DURATION_MINS } from '@/constants/constants';
@@ -87,7 +88,7 @@ export default defineStore('acctMgmtStore', {
async getAllUserAccounts() {
const apiGetUserList = `/api/users`;
try {
const response = await this.$axios.get(apiGetUserList);
const response = await apiClient.get(apiGetUserList);
const customizedResponseData = await this.customizeAllUserList(response.data);
this.allUserAccoutList = await this.moveCurrentLoginUserToFirstRow(customizedResponseData);
} catch (error) {
@@ -135,7 +136,7 @@ export default defineStore('acctMgmtStore', {
const apiCreateAccount = `/api/users`;
try {
const response = await this.$axios.post(apiCreateAccount, userToCreate);
const response = await apiClient.post(apiCreateAccount, userToCreate);
if (response.status === 200) {
this.isOneAccountJustCreate = true;
this.justCreateUsername = userToCreate.username;
@@ -154,7 +155,7 @@ export default defineStore('acctMgmtStore', {
const apiDelete = `/api/users/${userToDelete}`;
try {
const response = await this.$axios.delete(apiDelete);
const response = await apiClient.delete(apiDelete);
return response.status === 200;
} catch (error) {
apiError(error, 'Failed to delete the account.');
@@ -170,7 +171,7 @@ export default defineStore('acctMgmtStore', {
const apiEdit = `/api/users/${userToEdit}`;
try {
const response = await this.$axios.put(apiEdit, {
const response = await apiClient.put(apiEdit, {
username: editDetail.newUsername ? editDetail.newUsername : editDetail.username,
password: editDetail.password,
name: editDetail.name,
@@ -186,7 +187,7 @@ export default defineStore('acctMgmtStore', {
const apiEdit = `/api/users/${userToEdit}`;
try {
const response = await this.$axios.put(apiEdit, {
const response = await apiClient.put(apiEdit, {
username: userToEdit,
name: newName,
is_active: this.currentViewingUser.is_active,
@@ -202,7 +203,7 @@ export default defineStore('acctMgmtStore', {
const apiEdit = `/api/users/${userToEdit}`;
try {
const response = await this.$axios.put(apiEdit, {
const response = await apiClient.put(apiEdit, {
username: userToEdit,
name: this.currentViewingUser.name,
password: newPwd,
@@ -223,7 +224,7 @@ export default defineStore('acctMgmtStore', {
const apiAddRole = `/api/users/${usernameToEdit}/roles/${roleCode}`;
try {
const response = await this.$axios.put(apiAddRole);
const response = await apiClient.put(apiAddRole);
return response.status === 200;
} catch (error) {
apiError(error, 'Failed to add role to the account.');
@@ -238,7 +239,7 @@ export default defineStore('acctMgmtStore', {
const apiDeleteRole = `/api/users/${usernameToEdit}/roles/${roleCode}`;
try {
const response = await this.$axios.delete(apiDeleteRole);
const response = await apiClient.delete(apiDeleteRole);
return response.status === 200;
} catch (error) {
apiError(error, 'Failed to delete a role frome the account.');
@@ -252,7 +253,7 @@ export default defineStore('acctMgmtStore', {
async getUserDetail(uniqueUsername: string): Promise<boolean> {
const apiUserDetail = `/api/users/${uniqueUsername}`;
try {
const response = await this.$axios.get(apiUserDetail);
const response = await apiClient.get(apiUserDetail);
this.currentViewingUser = response.data;
this.currentViewingUser.is_admin = response.data.roles.some(role => role.code === 'admin');
return response.status === 200;

View File

@@ -1,5 +1,6 @@
import { defineStore } from "pinia";
import moment from "moment";
import apiClient from "@/api/client.js";
import apiError from '@/module/apiError.js';
import { Decimal } from 'decimal.js';
@@ -136,7 +137,7 @@ export default defineStore('allMapDataStore', {
else api = `/api/logs/${logId}/discover`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allProcessMap = response.data.process_map;
this.allBpmn = response.data.bpmn;
this.allStats = response.data.stats;
@@ -163,10 +164,10 @@ export default defineStore('allMapDataStore', {
try {
let baseResponse;
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allTrace = response.data;
if(baseLogId) {
baseResponse = await this.$axios.get(baseApi);
baseResponse = await apiClient.get(baseApi);
this.allBaseTrace = baseResponse.data;
}
} catch(error) {
@@ -190,7 +191,7 @@ export default defineStore('allMapDataStore', {
else api = `/api/logs/${logId}/traces/${traceId}?start=${start}&page_size=20`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allTraceTaskSeq = response.data.task_seq;
this.allCase = response.data.cases;
this.allCase.forEach(c => {
@@ -229,7 +230,7 @@ export default defineStore('allMapDataStore', {
const api = `/api/logs/${logId}/traces/${traceId}?start=${start}&page_size=20`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allBaseTraceTaskSeq = response.data.task_seq;
this.allBaseCase = response.data.cases;
this.allBaseCase.forEach(c => {
@@ -266,7 +267,7 @@ export default defineStore('allMapDataStore', {
const api = `/api/filters/params?log_id=${logId}`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allFilterTask = response.data.tasks;
this.allFilterStartToEnd = response.data.sources;
this.allFilterEndToStart = response.data.sinks;
@@ -294,7 +295,7 @@ export default defineStore('allMapDataStore', {
const api = `/api/filters/has-result?log_id=${logId}`;
try {
const response = await this.$axios.post(api, this.postRuleData)
const response = await apiClient.post(api, this.postRuleData)
this.hasResultRule = response.data.result;
} catch(error) {
apiError(error, 'Failed to load the Has Result.');
@@ -308,7 +309,7 @@ export default defineStore('allMapDataStore', {
const api = `/api/temp-filters?log_id=${logId}`;
try {
const response = await this.$axios.post(api, this.postRuleData)
const response = await apiClient.post(api, this.postRuleData)
this.tempFilterId = response.data.id;
} catch(error) {
apiError(error, 'Failed to add the Temporary Filters.');
@@ -327,7 +328,7 @@ export default defineStore('allMapDataStore', {
};
try {
const response = await this.$axios.post(api, createFilterObj);
const response = await apiClient.post(api, createFilterObj);
this.createFilterId = response.data.id;
this.tempFilterId = null;
}catch(error) {
@@ -343,7 +344,7 @@ export default defineStore('allMapDataStore', {
if(createFilterId){
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.temporaryData = response.data.rules;
this.logId = response.data.log.id;
this.filterName = response.data.name;
@@ -362,7 +363,7 @@ export default defineStore('allMapDataStore', {
const data = this.postRuleData;
try {
const response = await this.$axios.put(api, data);
const response = await apiClient.put(api, data);
this.isUpdateFilter = response.status === 200;
this.tempFilterId = null;
}catch(error) {

View File

@@ -1,4 +1,5 @@
import { defineStore } from "pinia";
import apiClient from "@/api/client.js";
import apiError from '@/module/apiError.js';
export default defineStore('compareStore', {
@@ -21,7 +22,7 @@ export default defineStore('compareStore', {
const api = `/api/compare?datasets=${encodeURIComponent(queryString)}`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allCompareDashboardData = response.data;
} catch(error) {
apiError(error, 'Failed to load the Compare.');
@@ -44,7 +45,7 @@ export default defineStore('compareStore', {
break;
}
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
return response.data.stats;
} catch(error) {
@@ -58,7 +59,7 @@ export default defineStore('compareStore', {
async getFileName(id) {
id = Number(id)
try {
const response = await this.$axios.get('/api/files');
const response = await apiClient.get('/api/files');
const file = response.data.find(i => i.id === id);
if(file) return file.name;

View File

@@ -2,6 +2,7 @@ import { defineStore } from "pinia";
import moment from "moment";
import { Decimal } from 'decimal.js';
import abbreviateNumber from '@/module/abbreviateNumber.js';
import apiClient from "@/api/client.js";
import apiError from '@/module/apiError.js';
export default defineStore('conformanceStore', {
@@ -201,7 +202,7 @@ export default defineStore('conformanceStore', {
api = `/api/log-checks/params?log_id=${logId}`;
}
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allConformanceTask = response.data.tasks;
this.allCfmSeqStart = response.data.sources;
this.allCfmSeqEnd = response.data.sinks;
@@ -230,7 +231,7 @@ export default defineStore('conformanceStore', {
}
try {
const response = await this.$axios.post(api, data);
const response = await apiClient.post(api, data);
if(filterId !== null) {
this.conformanceFilterTempCheckId = response.data.id;
}
@@ -266,7 +267,7 @@ export default defineStore('conformanceStore', {
api = `/api/log-checks/${logCreateCheckId}`;
}
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
if(!getRouteFile) {
this.allConformanceTempReportData = response.data
} else {
@@ -302,7 +303,7 @@ export default defineStore('conformanceStore', {
}
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allIssueTraces = response.data.traces;
} catch(error) {
apiError(error, 'Failed to Get the detail of a temporary log conformance issue.');
@@ -336,7 +337,7 @@ export default defineStore('conformanceStore', {
}
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allTaskSeq = response.data.task_seq;
this.allCases = response.data.cases;
return response.data.cases;
@@ -366,7 +367,7 @@ export default defineStore('conformanceStore', {
else if(logCreateCheckId !== null) api = `/api/log-checks/${logCreateCheckId}/loops/${loopNo}`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allLoopTraces = response.data.traces;
} catch(error) {
apiError(error, 'Failed to Get the detail of a temporary log conformance loop.');
@@ -392,7 +393,7 @@ export default defineStore('conformanceStore', {
else if(logCreateCheckId !== null) api = `/api/log-checks/${logCreateCheckId}/loops/${loopNo}/traces/${traceId}?start=${start}&page_size=20`;
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allLoopTaskSeq = response.data.task_seq;
this.allLoopCases = response.data.cases;
return response.data.cases;
@@ -422,7 +423,7 @@ export default defineStore('conformanceStore', {
else api = `/api/log-checks?log_id=${logId}`;
try {
const response = await this.$axios.post(api, data);
const response = await apiClient.post(api, data);
if(filterId !== null) {
this.conformanceFilterCreateCheckId = response.data.id;
this.conformanceFilterTempCheckId = null;
@@ -449,7 +450,7 @@ export default defineStore('conformanceStore', {
else if(logCreateCheckId !== null) api = `/api/log-checks/${logCreateCheckId}`;
try {
const response = await this.$axios.put(api, data);
const response = await apiClient.put(api, data);
this.isUpdateConformance = response.status === 200;
this.conformanceLogTempCheckId = null;
this.conformanceFilterTempCheckId = null;

View File

@@ -1,5 +1,5 @@
import { defineStore } from "pinia";
import axios from "axios";
import apiClient from "@/api/client.js";
import moment from 'moment';
import apiError from '@/module/apiError.js';
import Swal from 'sweetalert2';
@@ -66,7 +66,7 @@ export default defineStore('filesStore', {
let parentLog = '';
try {
const response = await axios.get(api);
const response = await apiClient.get(api);
this.allEventFiles = response.data;
this.allEventFiles.forEach(o => {
@@ -119,7 +119,7 @@ export default defineStore('filesStore', {
uploadloader(); // 進度條
try {
const response = await axios.post(api, fromData, config);
const response = await apiClient.post(api, fromData, config);
this.uploadId = response.data.id;
this.$router.push({name: 'Upload'});
@@ -145,7 +145,7 @@ export default defineStore('filesStore', {
const api = `/api/logs/csv-uploads/${uploadId}`;
try {
const response = await axios.get(api);
const response = await apiClient.get(api);
this.allUploadDetail = response.data.preview;
} catch(error) {
apiError(error, 'Failed to get upload detail.');
@@ -161,7 +161,7 @@ export default defineStore('filesStore', {
uploadloader(); // 進度條
try {
const response = await axios.post(api, data);
const response = await apiClient.post(api, data);
this.uploadLogId = await response.data.id;
await Swal.close(); // 關閉進度條
@@ -211,7 +211,7 @@ export default defineStore('filesStore', {
break;
}
try {
await axios.put(api, data);
await apiClient.put(api, data);
this.uploadFileName = null;
await this.fetchAllFiles();
} catch(error) {
@@ -241,7 +241,7 @@ export default defineStore('filesStore', {
break;
}
try {
const response = await axios.get(api);
const response = await apiClient.get(api);
this.allDependentsData = response.data;
} catch(error) {
apiError(error, 'Failed to get Dependents of the files.');
@@ -276,7 +276,7 @@ export default defineStore('filesStore', {
break;
}
try {
await axios.delete(api);
await apiClient.delete(api);
await this.fetchAllFiles();
await deleteSuccess();
} catch(error) {
@@ -296,7 +296,7 @@ export default defineStore('filesStore', {
loading.isLoading = true;
api = `/api/deletion/${id}`;
try {
await axios.delete(api);
await apiClient.delete(api);
} catch(error) {
apiError(error, 'Failed to Remove a Deletion Record.')
} finally {
@@ -329,7 +329,7 @@ export default defineStore('filesStore', {
return;
}
try {
const response = await axios.get(api);
const response = await apiClient.get(api);
const csvData = response.data;
const blob = new Blob([csvData], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);

View File

@@ -1,5 +1,6 @@
import { defineStore } from "pinia";
import axios from 'axios';
import apiClient from '@/api/client.js';
import apiError from '@/module/apiError.js';
import { deleteCookie, setCookie, setCookieWithoutExpiration, getCookie } from "../utils/cookieUtil";
@@ -51,7 +52,7 @@ export default defineStore('loginStore', {
window.location.href = decodedUrl;
} else {
this.$router.push('/files');
}
}
} catch(error) {
this.isInvalid = true;
};
@@ -78,8 +79,6 @@ export default defineStore('loginStore', {
setCookieWithoutExpiration("luciaToken", newAccessToken);
setCookie("luciaRefreshToken", newRefreshToken, Math.ceil((this.expired - Date.now()) / (24 * 60 * 60 * 1000)));
axios.defaults.headers.common['Authorization'] = `Bearer ${newAccessToken}`;
}
} catch(error) {
// 若refresh token 失敗則導向至登入頁面
@@ -91,7 +90,6 @@ export default defineStore('loginStore', {
* Logout, token expired
*/
logOut() {
delete axios.defaults.headers.common["Authorization"];
deleteCookie("luciaToken");
this.isLoggedIn = false;
@@ -106,7 +104,7 @@ export default defineStore('loginStore', {
const api = '/api/my-account';
try {
const response = await axios.get(api);
const response = await apiClient.get(api);
this.userData = response.data;
} catch(error) {
@@ -120,7 +118,7 @@ export default defineStore('loginStore', {
const api = '/api/my-account';
try {
await axios.get(api);
await apiClient.get(api);
} catch(error) {
this.$router.push('/login');
};

View File

@@ -1,4 +1,5 @@
import { defineStore } from "pinia";
import apiClient from "@/api/client.js";
import apiError from '@/module/apiError.js';
export default defineStore('performanceStore', {
@@ -36,7 +37,7 @@ export default defineStore('performanceStore', {
break;
}
try {
const response = await this.$axios.get(api);
const response = await apiClient.get(api);
this.allPerformanceData = response.data;
} catch(error) {
apiError(error, 'Failed to load the Performance.');

View File

@@ -4,11 +4,3 @@ declare module '*.vue' {
const component: DefineComponent<{}, {}, any>;
export default component;
}
declare module 'vue/types/vue' {
import { AxiosInstance } from 'axios';
interface Vue {
$axios: AxiosInstance;
}
}

View File

@@ -1,7 +1,8 @@
import { AxiosInstance } from 'axios';
import 'pinia';
import { Router } from 'vue-router';
declare module 'pinia' {
export interface PiniaCustomProperties {
$axios: AxiosInstance;
$router: Router;
}
}
}

View File

@@ -1,7 +1 @@
import { AxiosInstance } from 'axios';
declare module 'vue/types/vue' {
interface Vue {
$axios: AxiosInstance;
}
}
// vue-axios type declarations removed — API client is used directly

14
src/types/vue.d.ts vendored
View File

@@ -1,15 +1 @@
import { AxiosInstance } from 'axios';
import { App } from 'vue';
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$http: AxiosInstance;
}
}
// 將類型擴展到 Vue 應用實例
declare module 'vue' {
interface App {
$http: AxiosInstance;
}
}

View File

@@ -56,8 +56,6 @@
import { onBeforeMount, computed, } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoute } from 'vue-router';
import axios from 'axios';
import { getCookie } from "@/utils/cookieUtil.js";
import LoadingStore from '@/stores/loading.js';
import AllMapDataStore from '@/stores/allMapData.js';
import ConformanceStore from '@/stores/conformance.js';
@@ -519,10 +517,6 @@
if (isCheckPage) {
const conformanceStore = ConformanceStore();
// Save token in Headers.
const token = getCookie('luciaToken');
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
switch (to.params.type) {
case 'log':
conformanceStore.conformanceLogCreateCheckId = to.params.fileId;

View File

@@ -9,13 +9,11 @@
</template>
<script>
import { storeToRefs } from 'pinia';
import axios from 'axios';
import LoadingStore from '@/stores/loading.js';
import ConformanceStore from '@/stores/conformance.js';
import StatusBar from '@/components/Discover/StatusBar.vue';
import ConformanceResults from '@/components/Discover/Conformance/ConformanceResults.vue';
import ConformanceSidebar from '@/components/Discover/Conformance/ConformanceSidebar.vue';
import { getCookie } from "@/utils/cookieUtil.js";
export default {
setup() {
@@ -99,10 +97,6 @@ export default {
// ([^;]*):捕獲 "luciaToken" 的值,直到遇到下一個分號或字符串結尾。
// .*$:匹配剩餘的字符,確保完整的提取。
// |^.*$:在找不到 "luciaToken" 的情況下,匹配整個字符串。
// 實際應用
const token = getCookie('luciaToken');
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
switch (to.params.type) {
case 'log':
conformanceStore.setConformanceLogCreateCheckId(to.params.fileId);

View File

@@ -64,8 +64,6 @@
import { onBeforeMount, computed, } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoute } from 'vue-router';
import axios from 'axios';
import { getCookie } from "@/utils/cookieUtil.js";
import LoadingStore from '@/stores/loading.js';
import AllMapDataStore from '@/stores/allMapData.js';
import ConformanceStore from '@/stores/conformance.js';
@@ -537,10 +535,6 @@ export default {
if (isCheckPage) {
const conformanceStore = ConformanceStore();
// Save token in Headers.
const token = getCookie('luciaToken');
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
switch (to.params.type) {
case 'log':
conformanceStore.conformanceLogCreateCheckId = to.params.fileId;

View File

@@ -137,7 +137,6 @@
</template>
<script>
import { storeToRefs, mapActions, } from 'pinia';
import axios from 'axios';
import moment from 'moment';
import LoadingStore from '@/stores/loading.js';
import PerformanceStore from '@/stores/performance.js';
@@ -152,7 +151,6 @@ import { simpleTimeLabel, followTimeLabel,
} from '@/module/timeLabel.js';
import FreqChart from './FreqChart.vue';
import { PRIME_VUE_TICKS_LIMIT } from '../../../constants/constants.js';
import { getCookie } from "@/utils/cookieUtil.js";
const primeVueTicksLimit = PRIME_VUE_TICKS_LIMIT;
@@ -921,10 +919,6 @@ export default {
if (isCheckPage) {
const conformanceStore = ConformanceStore();
// Save token in Headers.
const token = getCookie('luciaToken');
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
switch (to.params.type) {
case 'log':
conformanceStore.conformanceLogCreateCheckId = to.params.fileId;

View File

@@ -85,11 +85,6 @@ export default {
'refreshToken',
],),
},
created() {
// Save token in Headers.
const token = getCookie('luciaToken');
this.$http.defaults.headers.common['Authorization'] = `Bearer ${token}`;
},
// 重新整理畫面以及第一次進入網頁時beforeRouteEnter這個hook會被執行然而beforeRouteUpdate不會被執行
// PSEUDOCODE
// if (not logged in) {