diff --git a/.env.development b/.env.development index f32b048..1a6b152 100644 --- a/.env.development +++ b/.env.development @@ -1 +1 @@ -VITE_API=https://api.imyeyu.dev \ No newline at end of file +VITE_API=http://localhost:8091 diff --git a/src/Root.vue b/src/Root.vue index 61f1429..476bcfc 100644 --- a/src/Root.vue +++ b/src/Root.vue @@ -23,3 +23,16 @@ watch( { immediate: true } ); + + diff --git a/src/api/file.ts b/src/api/file.ts new file mode 100644 index 0000000..9bac2aa --- /dev/null +++ b/src/api/file.ts @@ -0,0 +1,102 @@ +import axios, { AxiosError } from "axios"; +import { useSettingStore } from "@/store/settingStore"; +import type { ServerFile } from "@/pages/file/fileExplorer.shared"; + +interface ApiResponse { + code?: number | string; + data?: T; + list?: T; + msg?: string; + message?: string; +} + +export async function listServerFiles(pathSegments: string[]): Promise { + const response = await axios.get | ServerFile[]>(buildListURL(pathSegments), { + params: buildQueryParams(), + timeout: 15000 + }); + + return unwrapServerFileList(response.data); +} + +export function resolveRequestErrorMessage(error: unknown): string { + if (error instanceof AxiosError) { + const message = resolveApiMessage(error.response?.data); + if (message) { + return message; + } + + if (error.message) { + return error.message; + } + } + + if (error instanceof Error && error.message) { + return error.message; + } + + return "请求失败,请稍后重试"; +} + +function buildListURL(pathSegments: string[]): string { + const path = pathSegments.length ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}` : ""; + return `${resolveBaseURL()}/system/file/list${path}`; +} + +function resolveBaseURL(): string { + const settingStore = useSettingStore(); + const connect = settingStore.connect; + const envBaseURL = typeof import.meta.env.VITE_API === "string" ? import.meta.env.VITE_API.trim() : ""; + + if (connect.host && connect.port) { + return `${connect.protocol}://${connect.host}:${connect.port}`; + } + + return envBaseURL.replace(/\/+$/, ""); +} + +function buildQueryParams(): Record { + const settingStore = useSettingStore(); + const token = settingStore.connect.token.trim(); + + if (!token) { + return {}; + } + + return { + token + }; +} + +function unwrapServerFileList(payload: ApiResponse | ServerFile[]): ServerFile[] { + if (Array.isArray(payload)) { + return payload; + } + + if (Array.isArray(payload.data)) { + return payload.data; + } + + if (Array.isArray(payload.list)) { + return payload.list; + } + + throw new Error(resolveApiMessage(payload) || "文件列表返回格式不正确"); +} + +function resolveApiMessage(payload: unknown): string { + if (!payload || typeof payload !== "object") { + return ""; + } + + const { msg, message } = payload as ApiResponse; + if (typeof msg === "string" && msg.trim()) { + return msg.trim(); + } + + if (typeof message === "string" && message.trim()) { + return message.trim(); + } + + return ""; +} diff --git a/src/components/PageTransition.vue b/src/components/PageTransition.vue index f6207fa..f046c2a 100644 --- a/src/components/PageTransition.vue +++ b/src/components/PageTransition.vue @@ -100,6 +100,7 @@ onUnmounted(() => { .page-transition { width: 100%; + height: 100%; display: grid; min-height: 100%; position: relative; @@ -108,6 +109,7 @@ onUnmounted(() => { .pages { grid-area: 1 / 1; width: 100%; + height: 100%; min-height: 100%; position: relative; background: v-bind(pageBackground); @@ -120,6 +122,7 @@ onUnmounted(() => { .push-right-leave-active { grid-area: 1 / 1; width: 100%; + height: 100%; min-height: 100%; transition: transform @duration @easing, opacity .2s linear; backface-visibility: hidden; diff --git a/src/layout/MainLayout.vue b/src/layout/MainLayout.vue index b72fea5..2630780 100644 --- a/src/layout/MainLayout.vue +++ b/src/layout/MainLayout.vue @@ -27,7 +27,7 @@ :disabled="!tabBarStore.isShowing" @change="onChangeTab" > - + @@ -88,6 +88,10 @@ const navBarPadding = computed(() => { return "0"; }); +const topPadding = computed(() => { + return `calc(${navBarPadding.value} + var(--safe-top))`; +}); + // ---------- Tab 切换 ---------- const tabVal = ref(route.path); @@ -138,17 +142,22 @@ const isContentFixedHeight = computed(() => { }); const bodyHeight = computed(() => { - return `calc(100vh - ${navBarPadding.value} - ${tabBarPadding.value})`; + return `calc(100vh - ${tabBarPadding.value})`; +}); + +const contentHeight = computed(() => { + return bodyHeight.value; });