diff --git a/.env.development b/.env.development index dd13e1d..75d0217 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,4 @@ VITE_APP_TITLE=member.ose.tw (dev) VITE_API_BASE_URL=http://127.0.0.1:8000 +VITE_ADMIN_CLIENT_KEY=admin-frontend +VITE_ADMIN_API_KEY=dev-admin-key-123 diff --git a/.env.example b/.env.example index 2cb3449..e2ae621 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,5 @@ # member.ose.tw frontend env VITE_APP_TITLE=member.ose.tw VITE_API_BASE_URL=https://memberapi.ose.tw +VITE_ADMIN_CLIENT_KEY= +VITE_ADMIN_API_KEY= diff --git a/src/api/http.js b/src/api/http.js index d3c74b1..5d56a5b 100644 --- a/src/api/http.js +++ b/src/api/http.js @@ -2,6 +2,8 @@ import axios from 'axios' import router from '@/router' const BASE_URL = import.meta.env.VITE_API_BASE_URL +const ENV_ADMIN_CLIENT_KEY = import.meta.env.VITE_ADMIN_CLIENT_KEY +const ENV_ADMIN_API_KEY = import.meta.env.VITE_ADMIN_API_KEY // 使用者 API:帶 Bearer token export const userHttp = axios.create({ baseURL: BASE_URL }) @@ -29,8 +31,14 @@ userHttp.interceptors.response.use( export const adminHttp = axios.create({ baseURL: BASE_URL }) adminHttp.interceptors.request.use(config => { - const clientKey = sessionStorage.getItem('admin_client_key') - const apiKey = sessionStorage.getItem('admin_api_key') + const clientKey = sessionStorage.getItem('admin_client_key') || ENV_ADMIN_CLIENT_KEY + const apiKey = sessionStorage.getItem('admin_api_key') || ENV_ADMIN_API_KEY + if (clientKey && !sessionStorage.getItem('admin_client_key')) { + sessionStorage.setItem('admin_client_key', clientKey) + } + if (apiKey && !sessionStorage.getItem('admin_api_key')) { + sessionStorage.setItem('admin_api_key', apiKey) + } if (clientKey) config.headers['X-Client-Key'] = clientKey if (apiKey) config.headers['X-API-Key'] = apiKey return config diff --git a/src/pages/admin/CompaniesPage.vue b/src/pages/admin/CompaniesPage.vue index 5229fff..167ed8f 100644 --- a/src/pages/admin/CompaniesPage.vue +++ b/src/pages/admin/CompaniesPage.vue @@ -65,10 +65,12 @@ async function load() { error.value = false try { const res = await getCompanies() - companies.value = res.data || [] + companies.value = res.data?.items || [] } catch (err) { error.value = true - errorMsg.value = '載入失敗,請稍後再試' + errorMsg.value = err.response?.status === 422 + ? '缺少管理員 API 認證,請檢查前端 .env.development' + : '載入失敗,請稍後再試' } finally { loading.value = false } diff --git a/src/pages/admin/MembersPage.vue b/src/pages/admin/MembersPage.vue index 8bc2693..ac0f18b 100644 --- a/src/pages/admin/MembersPage.vue +++ b/src/pages/admin/MembersPage.vue @@ -40,10 +40,12 @@ async function load() { error.value = false try { const res = await getMembers() - members.value = res.data || [] + members.value = res.data?.items || [] } catch (err) { error.value = true - errorMsg.value = '載入失敗,請稍後再試' + errorMsg.value = err.response?.status === 422 + ? '缺少管理員 API 認證,請檢查前端 .env.development' + : '載入失敗,請稍後再試' } finally { loading.value = false } diff --git a/src/pages/admin/ModulesPage.vue b/src/pages/admin/ModulesPage.vue index 9982f54..379952b 100644 --- a/src/pages/admin/ModulesPage.vue +++ b/src/pages/admin/ModulesPage.vue @@ -70,10 +70,12 @@ async function load() { error.value = false try { const res = await getModules() - modules.value = res.data || [] + modules.value = res.data?.items || [] } catch (err) { error.value = true - errorMsg.value = '載入失敗,請稍後再試' + errorMsg.value = err.response?.status === 422 + ? '缺少管理員 API 認證,請檢查前端 .env.development' + : '載入失敗,請稍後再試' } finally { loading.value = false } diff --git a/src/pages/admin/PermissionGroupsPage.vue b/src/pages/admin/PermissionGroupsPage.vue index e6dd9c9..b8786a9 100644 --- a/src/pages/admin/PermissionGroupsPage.vue +++ b/src/pages/admin/PermissionGroupsPage.vue @@ -145,8 +145,12 @@ async function loadGroups() { loadingGroups.value = true try { const res = await getPermissionGroups() - groups.value = res.data || [] + groups.value = res.data?.items || [] } catch (err) { + if (err.response?.status === 422) { + ElMessage.error('缺少管理員 API 認證,請檢查前端 .env.development') + return + } ElMessage.error('載入群組失敗') } finally { loadingGroups.value = false diff --git a/src/pages/admin/SitesPage.vue b/src/pages/admin/SitesPage.vue index 0b4c6e2..ce939d9 100644 --- a/src/pages/admin/SitesPage.vue +++ b/src/pages/admin/SitesPage.vue @@ -70,10 +70,12 @@ async function load() { error.value = false try { const res = await getSites() - sites.value = res.data || [] + sites.value = res.data?.items || [] } catch (err) { error.value = true - errorMsg.value = '載入失敗,請稍後再試' + errorMsg.value = err.response?.status === 422 + ? '缺少管理員 API 認證,請檢查前端 .env.development' + : '載入失敗,請稍後再試' } finally { loading.value = false } diff --git a/src/pages/admin/SystemsPage.vue b/src/pages/admin/SystemsPage.vue index adc9c9d..d6755e6 100644 --- a/src/pages/admin/SystemsPage.vue +++ b/src/pages/admin/SystemsPage.vue @@ -65,10 +65,12 @@ async function load() { error.value = false try { const res = await getSystems() - systems.value = res.data || [] + systems.value = res.data?.items || [] } catch (err) { error.value = true - errorMsg.value = '載入失敗,請稍後再試' + errorMsg.value = err.response?.status === 422 + ? '缺少管理員 API 認證,請檢查前端 .env.development' + : '載入失敗,請稍後再試' } finally { loading.value = false } diff --git a/src/stores/permission.js b/src/stores/permission.js index 4aea251..6debe10 100644 --- a/src/stores/permission.js +++ b/src/stores/permission.js @@ -5,8 +5,17 @@ import { grantPermission, revokePermission } from '@/api/permission-admin' export const usePermissionStore = defineStore('permission', () => { const snapshot = ref(null) - const adminClientKey = ref(sessionStorage.getItem('admin_client_key') || '') - const adminApiKey = ref(sessionStorage.getItem('admin_api_key') || '') + const envClientKey = import.meta.env.VITE_ADMIN_CLIENT_KEY || '' + const envApiKey = import.meta.env.VITE_ADMIN_API_KEY || '' + const adminClientKey = ref(sessionStorage.getItem('admin_client_key') || envClientKey) + const adminApiKey = ref(sessionStorage.getItem('admin_api_key') || envApiKey) + + if (adminClientKey.value) { + sessionStorage.setItem('admin_client_key', adminClientKey.value) + } + if (adminApiKey.value) { + sessionStorage.setItem('admin_api_key', adminApiKey.value) + } const hasAdminCreds = () => !!(adminClientKey.value && adminApiKey.value)