diff --git a/internal/handler/settings_handler.go b/internal/handler/settings_handler.go index bf3fd03..2e38eee 100644 --- a/internal/handler/settings_handler.go +++ b/internal/handler/settings_handler.go @@ -17,18 +17,22 @@ func GetSettings(c *gin.Context) { currentSettings := settingsManager.GetSettings() settingsInfo := config.GenerateSettingsMetadata(¤tSettings) - // Group settings by category + // Group settings by category while preserving order categorized := make(map[string][]models.SystemSettingInfo) + var categoryOrder []string for _, s := range settingsInfo { + if _, exists := categorized[s.Category]; !exists { + categoryOrder = append(categoryOrder, s.Category) + } categorized[s.Category] = append(categorized[s.Category], s) } - // Create the response structure + // Create the response structure in the correct order var responseData []models.CategorizedSettings - for categoryName, settings := range categorized { + for _, categoryName := range categoryOrder { responseData = append(responseData, models.CategorizedSettings{ CategoryName: categoryName, - Settings: settings, + Settings: categorized[categoryName], }) } diff --git a/web/src/App.vue b/web/src/App.vue index fd635fa..f0cf0b3 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -1,7 +1,7 @@ - - - - - - + + + + diff --git a/web/src/api/settings.ts b/web/src/api/settings.ts new file mode 100644 index 0000000..16b9df1 --- /dev/null +++ b/web/src/api/settings.ts @@ -0,0 +1,27 @@ +import http from "@/utils/http"; + +export interface Setting { + key: string; + name: string; + value: string | number; + type: "int" | "string"; + min_value?: number; + description: string; +} + +export interface SettingCategory { + category_name: string; + settings: Setting[]; +} + +export type SettingsUpdatePayload = Record; + +export const settingsApi = { + getSettings: async (): Promise => { + const response = await http.get("/settings"); + return response.data || []; + }, + updateSettings: (data: SettingsUpdatePayload): Promise => { + return http.put("/settings", data); + }, +}; diff --git a/web/src/components/GlobalProviders.vue b/web/src/components/GlobalProviders.vue new file mode 100644 index 0000000..2226fb3 --- /dev/null +++ b/web/src/components/GlobalProviders.vue @@ -0,0 +1,51 @@ + + + + + + + + + + + + + diff --git a/web/src/types/env.d.ts b/web/src/types/env.d.ts new file mode 100644 index 0000000..ecce22d --- /dev/null +++ b/web/src/types/env.d.ts @@ -0,0 +1,9 @@ +/// + +import type { MessageApiInjection } from "naive-ui/es/message/src/MessageProvider"; + +declare global { + interface Window { + $message: MessageApiInjection; + } +} diff --git a/web/src/utils/app-state.ts b/web/src/utils/app-state.ts new file mode 100644 index 0000000..e3f8cb2 --- /dev/null +++ b/web/src/utils/app-state.ts @@ -0,0 +1,9 @@ +import { reactive } from "vue"; + +interface AppState { + loading: boolean; +} + +export const appState = reactive({ + loading: false, +}); diff --git a/web/src/utils/http.ts b/web/src/utils/http.ts index bc2760e..57ae6b6 100644 --- a/web/src/utils/http.ts +++ b/web/src/utils/http.ts @@ -1,5 +1,6 @@ import { useAuthService } from "@/services/auth"; import axios from "axios"; +import { appState } from "./app-state"; const http = axios.create({ baseURL: "/api", @@ -9,6 +10,7 @@ const http = axios.create({ // 请求拦截器 http.interceptors.request.use(config => { + appState.loading = true; const authKey = localStorage.getItem("authKey"); if (authKey) { config.headers.Authorization = `Bearer ${authKey}`; @@ -18,12 +20,30 @@ http.interceptors.request.use(config => { // 响应拦截器 http.interceptors.response.use( - response => response.data, + response => { + appState.loading = false; + if (response.config.method !== "get") { + window.$message.success("操作成功"); + } + return response.data; + }, error => { - if (error.response && error.response.status === 401) { - const { logout } = useAuthService(); - logout(); - window.location.href = "/login"; + appState.loading = false; + if (error.response) { + // The request was made and the server responded with a status code + // that falls out of the range of 2xx + if (error.response.status === 401) { + const { logout } = useAuthService(); + logout(); + window.location.href = "/login"; + } + window.$message.error(error.response.data?.message || `请求失败: ${error.response.status}`); + } else if (error.request) { + // The request was made but no response was received + window.$message.error("网络错误,请检查您的连接"); + } else { + // Something happened in setting up the request that triggered an Error + window.$message.error("请求设置错误"); } console.error("API Error:", error); return Promise.reject(error); diff --git a/web/src/views/Settings.vue b/web/src/views/Settings.vue index 77799ab..e201694 100644 --- a/web/src/views/Settings.vue +++ b/web/src/views/Settings.vue @@ -1,37 +1,19 @@ - - + + + + + + {{ item.name }} + + {{ item.description }} + + - + 保存设置