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;
});