diff --git a/internal/apps/mysql/app.go b/internal/apps/mysql/app.go index 48948932..73868a3b 100644 --- a/internal/apps/mysql/app.go +++ b/internal/apps/mysql/app.go @@ -37,7 +37,7 @@ func (s *App) Route(r chi.Router) { r.Get("/load", s.Load) r.Get("/config", s.GetConfig) r.Post("/config", s.UpdateConfig) - r.Post("/clear_error_log", s.ClearErrorLog) + r.Post("/clear_log", s.ClearLog) r.Get("/slow_log", s.SlowLog) r.Post("/clear_slow_log", s.ClearSlowLog) r.Get("/root_password", s.GetRootPassword) @@ -159,8 +159,8 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) { service.Success(w, load) } -// ClearErrorLog 清空错误日志 -func (s *App) ClearErrorLog(w http.ResponseWriter, r *http.Request) { +// ClearLog 清空日志 +func (s *App) ClearLog(w http.ResponseWriter, r *http.Request) { if err := systemctl.LogClear("mysqld"); err != nil { service.Error(w, http.StatusInternalServerError, "%v", err) return diff --git a/internal/apps/php/app.go b/internal/apps/php/app.go index a4078081..874272d1 100644 --- a/internal/apps/php/app.go +++ b/internal/apps/php/app.go @@ -46,9 +46,9 @@ func (s *App) Route(version uint) func(r chi.Router) { r.Get("/fpm_config", php.GetFPMConfig) r.Post("/fpm_config", php.UpdateFPMConfig) r.Get("/load", php.Load) - r.Get("/error_log", php.ErrorLog) + r.Get("/log", php.Log) r.Get("/slow_log", php.SlowLog) - r.Post("/clear_error_log", php.ClearErrorLog) + r.Post("/clear_log", php.ClearLog) r.Post("/clear_slow_log", php.ClearSlowLog) r.Get("/extensions", php.ExtensionList) r.Post("/extensions", php.InstallExtension) @@ -169,7 +169,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) { service.Success(w, loads) } -func (s *App) ErrorLog(w http.ResponseWriter, r *http.Request) { +func (s *App) Log(w http.ResponseWriter, r *http.Request) { service.Success(w, fmt.Sprintf("%s/server/php/%d/var/log/php-fpm.log", app.Root, s.version)) } @@ -177,7 +177,7 @@ func (s *App) SlowLog(w http.ResponseWriter, r *http.Request) { service.Success(w, fmt.Sprintf("%s/server/php/%d/var/log/slow.log", app.Root, s.version)) } -func (s *App) ClearErrorLog(w http.ResponseWriter, r *http.Request) { +func (s *App) ClearLog(w http.ResponseWriter, r *http.Request) { if _, err := shell.Execf("cat /dev/null > %s/server/php/%d/var/log/php-fpm.log", app.Root, s.version); err != nil { service.Error(w, http.StatusInternalServerError, "%v", err) return diff --git a/internal/http/request/app.go b/internal/http/request/app.go index 84d6794f..15066eb8 100644 --- a/internal/http/request/app.go +++ b/internal/http/request/app.go @@ -9,6 +9,10 @@ type AppSlug struct { Slug string `json:"slug" form:"slug" validate:"required"` } +type AppSlugs struct { + Slugs string `json:"slugs" form:"slugs" validate:"required"` +} + type AppUpdateShow struct { Slug string `json:"slug" form:"slug" validate:"required|exists:apps,slug"` Show bool `json:"show" form:"show"` diff --git a/internal/service/app.go b/internal/service/app.go index bb4bdd9f..1828eaa0 100644 --- a/internal/service/app.go +++ b/internal/service/app.go @@ -2,6 +2,7 @@ package service import ( "net/http" + "strings" "github.com/leonelquinteros/gotext" "github.com/libtnb/chix" @@ -144,28 +145,27 @@ func (s *AppService) UpdateShow(w http.ResponseWriter, r *http.Request) { } func (s *AppService) IsInstalled(w http.ResponseWriter, r *http.Request) { - req, err := Bind[request.AppSlug](r) + req, err := Bind[request.AppSlugs](r) if err != nil { Error(w, http.StatusUnprocessableEntity, "%v", err) return } - app, err := s.appRepo.Get(req.Slug) - if err != nil { - Error(w, http.StatusInternalServerError, "%v", err) - return + flag := false + slugs := strings.Split(req.Slugs, ",") + for _, item := range slugs { + installed, err := s.appRepo.IsInstalled(item) + if err != nil { + Error(w, http.StatusInternalServerError, "%v", err) + return + } + if installed { + flag = true + break + } } - installed, err := s.appRepo.IsInstalled(req.Slug) - if err != nil { - Error(w, http.StatusInternalServerError, "%v", err) - return - } - - Success(w, chix.M{ - "name": app.Name, - "installed": installed, - }) + Success(w, flag) } func (s *AppService) UpdateCache(w http.ResponseWriter, r *http.Request) { diff --git a/internal/service/monitor.go b/internal/service/monitor.go index ab31fcca..d13a9a04 100644 --- a/internal/service/monitor.go +++ b/internal/service/monitor.go @@ -68,6 +68,10 @@ func (s *MonitorService) List(w http.ResponseWriter, r *http.Request) { Error(w, http.StatusInternalServerError, "%v", err) return } + if len(monitors) == 0 { + Success(w, types.MonitorData{}) + return + } var list types.MonitorData var bytesSent uint64 diff --git a/renovate.json b/renovate.json index 4afcdae2..27077a70 100644 --- a/renovate.json +++ b/renovate.json @@ -29,5 +29,7 @@ "automerge": true } ], - "ignoreDeps": [] + "ignoreDeps": [ + "monaco-editor" + ] } diff --git a/web/index.html b/web/index.html index 294b95c5..29a01472 100644 --- a/web/index.html +++ b/web/index.html @@ -23,7 +23,6 @@
<%= title %>
- diff --git a/web/package.json b/web/package.json index e4db4a25..b0b5d412 100644 --- a/web/package.json +++ b/web/package.json @@ -65,6 +65,7 @@ "@types/luxon": "^3.6.2", "@types/node": "^22.15.21", "@types/node-forge": "^1.3.11", + "@typescript/native-preview": "7.0.0-dev.20250904.1", "@unocss/eslint-config": "^66.1.2", "@vitejs/plugin-vue": "^6.0.0", "@vue/eslint-config-prettier": "^10.2.0", @@ -75,7 +76,7 @@ "eslint": "^9.27.0", "eslint-plugin-vue": "^10.1.0", "md-editor-v3": "^6.0.0", - "monaco-editor": "^0.53.0", + "monaco-editor": "0.52.2", "naive-ui": "^2.41.0", "npm-run-all2": "^8.0.4", "prettier": "^3.5.3", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 3e98657f..ffa4ea91 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: 5.2.7 '@guolao/vue-monaco-editor': specifier: ^1.5.5 - version: 1.5.5(monaco-editor@0.53.0)(vue@3.5.21(typescript@5.9.2)) + version: 1.5.5(monaco-editor@0.52.2)(vue@3.5.21(typescript@5.9.2)) '@vavt/copy2clipboard': specifier: ^1.0.3 version: 1.0.3 @@ -123,6 +123,9 @@ importers: '@types/node-forge': specifier: ^1.3.11 version: 1.3.14 + '@typescript/native-preview': + specifier: 7.0.0-dev.20250904.1 + version: 7.0.0-dev.20250904.1 '@unocss/eslint-config': specifier: ^66.1.2 version: 66.5.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) @@ -154,8 +157,8 @@ importers: specifier: ^6.0.0 version: 6.0.1(vue@3.5.21(typescript@5.9.2)) monaco-editor: - specifier: ^0.53.0 - version: 0.53.0 + specifier: 0.52.2 + version: 0.52.2 naive-ui: specifier: ^2.41.0 version: 2.43.1(vue@3.5.21(typescript@5.9.2)) @@ -1063,9 +1066,6 @@ packages: '@types/node@22.18.4': resolution: {integrity: sha512-UJdblFqXymSBhmZf96BnbisoFIr8ooiiBRMolQgg77Ea+VM37jXw76C2LQr9n8wm9+i/OvlUlW6xSvqwzwqznw==} - '@types/trusted-types@1.0.6': - resolution: {integrity: sha512-230RC8sFeHoT6sSUlRO6a8cAnclO06eeiq1QDfiv2FGCLWFvvERWgwIQD4FWqD9A69BN7Lzee4OXwoMVnnsWDw==} - '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} @@ -1128,6 +1128,53 @@ packages: resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-1rt4DhERW1VM4OwWYVIrCp1k1S4kpZAxzbCnprNinVJInhHexY2K0FFD9IGXKWSRANHg/OmJRQYTEoDKM6pqNw==} + engines: {node: '>=20.6.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-d2DMQnsXAkZDDk9bU/FhY/D74tbMAkboIGb+hq7kIIgOVcxOswhwLFZ/ajW/9NTesktz8Z14t40Ber+/Pny25A==} + engines: {node: '>=20.6.0'} + cpu: [x64] + os: [darwin] + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-+fv13RDSk+7wFYY846q5ig7X6G07JT7wbajk6p4rELXTIfS1c6gRHGhODETCfFVaPziP4IlvqyinNP8F8wc9uQ==} + engines: {node: '>=20.6.0'} + cpu: [arm64] + os: [linux] + + '@typescript/native-preview-linux-arm@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-YyfTK1SGmfeDJv6G3vSmVxjM914Xio7O57NzRKOyEQnmBT5tdXTzeWgkjrUh1jE8wCUu0f0ZZ+xDTwgys+E2ug==} + engines: {node: '>=20.6.0'} + cpu: [arm] + os: [linux] + + '@typescript/native-preview-linux-x64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-BjWJI42cUUilIyQHZpQQeSjC/Ifj/UaIf4oj6lRHDcg5qgLHWe5bAUxuNjE6i7wi+TTN9YxUvBDkMAcm/hI8wg==} + engines: {node: '>=20.6.0'} + cpu: [x64] + os: [linux] + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-rPv/mVaneZTuFESk/zDg3dFiZjpdipVMcLaF10Ns1fIyWdZ0ja79Ufm1eCFbk8KFNEX2dEx+vFEvD9n4bhEneg==} + engines: {node: '>=20.6.0'} + cpu: [arm64] + os: [win32] + + '@typescript/native-preview-win32-x64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-+twwqKYEv5UdZX5FRaBo0bDQgw/uPQjU3hqaqaO0Dhp1Ou8Ce4oi5hgwauB1j29JwBbvOi9/yoEcjsjT2Wsaxw==} + engines: {node: '>=20.6.0'} + cpu: [x64] + os: [win32] + + '@typescript/native-preview@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-IzPzhumNsWsIg4Kmt0y+0b2BBtsvD17rDmKj78yNeU3AsuA6xignQ5eDkFtRmLdGPVZwa8Yg5zPcJRFln98Ocw==} + engines: {node: '>=20.6.0'} + hasBin: true + '@unocss/astro@66.5.1': resolution: {integrity: sha512-f17+xfyBZ9prFx4jda3D9ngOigjO8btHsR3uG7WeDQPW6OBdhETfIGdXs8WD99J/3A3LJtk7J0u9p121S+RE8Q==} peerDependencies: @@ -2561,8 +2608,8 @@ packages: resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==} hasBin: true - monaco-editor@0.53.0: - resolution: {integrity: sha512-0WNThgC6CMWNXXBxTbaYYcunj08iB5rnx4/G56UOPeL9UVIUGGHA1GR0EWIh9Ebabj7NpCRawQ5b0hfN1jQmYQ==} + monaco-editor@0.52.2: + resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==} mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} @@ -4133,10 +4180,10 @@ snapshots: '@fontsource-variable/jetbrains-mono@5.2.7': {} - '@guolao/vue-monaco-editor@1.5.5(monaco-editor@0.53.0)(vue@3.5.21(typescript@5.9.2))': + '@guolao/vue-monaco-editor@1.5.5(monaco-editor@0.52.2)(vue@3.5.21(typescript@5.9.2))': dependencies: '@monaco-editor/loader': 1.5.0 - monaco-editor: 0.53.0 + monaco-editor: 0.52.2 vue: 3.5.21(typescript@5.9.2) vue-demi: 0.14.10(vue@3.5.21(typescript@5.9.2)) @@ -4506,8 +4553,6 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/trusted-types@1.0.6': {} - '@types/web-bluetooth@0.0.21': {} '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': @@ -4603,6 +4648,37 @@ snapshots: '@typescript-eslint/types': 8.43.0 eslint-visitor-keys: 4.2.1 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-linux-arm@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-linux-x64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-win32-x64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview@7.0.0-dev.20250904.1': + optionalDependencies: + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20250904.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20250904.1 + '@unocss/astro@66.5.1(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(tsx@4.20.5))': dependencies: '@unocss/core': 66.5.1 @@ -6242,9 +6318,7 @@ snapshots: dependencies: commander: 14.0.1 - monaco-editor@0.53.0: - dependencies: - '@types/trusted-types': 1.0.6 + monaco-editor@0.52.2: {} mrmime@2.0.1: {} diff --git a/web/public/loading/index.css b/web/public/loading/index.css index efab6c21..f07128ba 100644 --- a/web/public/loading/index.css +++ b/web/public/loading/index.css @@ -42,7 +42,7 @@ position: absolute; height: 16px; width: 16px; - background-color: var(--primary-color); + background-color: #333333; border-radius: 8px; -webkit-animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; diff --git a/web/public/loading/index.js b/web/public/loading/index.js deleted file mode 100644 index 2f35ef88..00000000 --- a/web/public/loading/index.js +++ /dev/null @@ -1,9 +0,0 @@ -function addThemeColorCssVars() { - const key = '__THEME_COLOR__' - const defaultColor = '#00BFFF' - const themeColor = window.localStorage.getItem(key) || defaultColor - const cssVars = `--primary-color: ${themeColor}` - document.documentElement.style.cssText = cssVars -} - -addThemeColorCssVars() diff --git a/web/settings/theme.json b/web/settings/theme.json index 017eb2a7..a8d46296 100644 --- a/web/settings/theme.json +++ b/web/settings/theme.json @@ -14,13 +14,6 @@ "visible": true, "height": 60 }, - "primaryColor": "#00BFFF", - "otherColor": { - "info": "#2080F0", - "success": "#18A058", - "warning": "#F0A020", - "error": "#D03050" - }, "locale": "zh_CN", "name": "AcePanel" } diff --git a/web/src/api/apps/mysql/index.ts b/web/src/api/apps/mysql/index.ts index 5f76e241..508d64c1 100644 --- a/web/src/api/apps/mysql/index.ts +++ b/web/src/api/apps/mysql/index.ts @@ -7,8 +7,8 @@ export default { config: (): any => http.Get('/apps/mysql/config'), // 保存配置 saveConfig: (config: string): any => http.Post('/apps/mysql/config', { config }), - // 清空错误日志 - clearErrorLog: (): any => http.Post('/apps/mysql/clear_error_log'), + // 清空日志 + clearLog: (): any => http.Post('/apps/mysql/clear_log'), // 获取慢查询日志 slowLog: (): any => http.Get('/apps/mysql/slow_log'), // 清空慢查询日志 diff --git a/web/src/api/apps/php/index.ts b/web/src/api/apps/php/index.ts index 8c105060..5f488c62 100644 --- a/web/src/api/apps/php/index.ts +++ b/web/src/api/apps/php/index.ts @@ -15,10 +15,10 @@ export default { http.Post(`/apps/php${version}/fpm_config`, { config }), // 负载状态 load: (version: number): any => http.Get(`/apps/php${version}/load`), - // 获取错误日志 - errorLog: (version: number): any => http.Get(`/apps/php${version}/error_log`), - // 清空错误日志 - clearErrorLog: (version: number): any => http.Post(`/apps/php${version}/clear_error_log`), + // 获取日志 + log: (version: number): any => http.Get(`/apps/php${version}/log`), + // 清空日志 + clearLog: (version: number): any => http.Post(`/apps/php${version}/clear_log`), // 获取慢日志 slowLog: (version: number): any => http.Get(`/apps/php${version}/slow_log`), // 清空慢日志 diff --git a/web/src/api/panel/app/index.ts b/web/src/api/panel/app/index.ts index 840f79d6..416b925e 100644 --- a/web/src/api/panel/app/index.ts +++ b/web/src/api/panel/app/index.ts @@ -13,7 +13,7 @@ export default { // 设置首页显示 updateShow: (slug: string, show: boolean): any => http.Post('/app/update_show', { slug, show }), // 应用是否已安装 - isInstalled: (slug: string): any => http.Get('/app/is_installed', { params: { slug } }), + isInstalled: (slugs: string): any => http.Get('/app/is_installed', { params: { slugs } }), // 更新缓存 updateCache: (): any => http.Get('/app/update_cache') } diff --git a/web/src/assets/images/logo.png b/web/src/assets/images/logo.png index a7b17565..63f1c08d 100755 Binary files a/web/src/assets/images/logo.png and b/web/src/assets/images/logo.png differ diff --git a/web/src/components/common/AppProvider.vue b/web/src/components/common/AppProvider.vue index 10f03ee5..d7f7b28c 100644 --- a/web/src/components/common/AppProvider.vue +++ b/web/src/components/common/AppProvider.vue @@ -1,26 +1,8 @@ - - diff --git a/web/src/layout/sidebar/components/SideMenu.vue b/web/src/layout/sidebar/components/SideMenu.vue index d0af9d6f..2dccf225 100644 --- a/web/src/layout/sidebar/components/SideMenu.vue +++ b/web/src/layout/sidebar/components/SideMenu.vue @@ -3,11 +3,12 @@ import { translateTitle } from '@/locales/menu' import { usePermissionStore, useTabStore, useThemeStore } from '@/store' import { isUrl, renderIcon } from '@/utils' -import type { MenuInst, MenuOption } from 'naive-ui' +import { MenuInst, MenuOption, useThemeVars } from 'naive-ui' import type { VNodeChild } from 'vue' import { RouterLink } from 'vue-router' import type { Meta, RouteType } from '~/types/router' +const themeVars = useThemeVars() const router = useRouter() const currentRoute = useRoute() const permissionStore = usePermissionStore() @@ -142,8 +143,8 @@ function handleMenuSelect(key: string, item: MenuOption) { .n-menu-item-content--child-active, .n-menu-item-content--selected { .n-menu-item-content__icon { - border-color: var(--primary-color); - background-color: var(--primary-color); + border-color: v-bind('themeVars.primaryColor'); + background-color: v-bind('themeVars.primaryColor'); i { color: #fff; diff --git a/web/src/layout/tab/IndexView.vue b/web/src/layout/tab/IndexView.vue index 714d1a73..03b46a3d 100644 --- a/web/src/layout/tab/IndexView.vue +++ b/web/src/layout/tab/IndexView.vue @@ -2,8 +2,10 @@ import { translateTitle } from '@/locales/menu' import type { TabItem } from '@/store' import { useTabStore } from '@/store' +import { useThemeVars } from 'naive-ui' import ContextMenu from './components/ContextMenu.vue' +const themeVars = useThemeVars() const router = useRouter() const tabStore = useTabStore() @@ -88,13 +90,12 @@ async function handleContextMenu(e: MouseEvent, tabItem: TabItem) { margin-right: 4px; &:hover { - border: 1px solid var(--primary-color) !important; + border: 1px solid v-bind('themeVars.primaryColor') !important; } } .n-tabs-tab--active { - border: 1px solid var(--primary-color) !important; - background-color: var(--selected-bg) !important; + border: 1px solid v-bind('themeVars.primaryColor') !important; } .n-tabs-pad, diff --git a/web/src/router/guard/app-install-guard.ts b/web/src/router/guard/app-install-guard.ts index a5631169..7093b8d0 100644 --- a/web/src/router/guard/app-install-guard.ts +++ b/web/src/router/guard/app-install-guard.ts @@ -1,13 +1,27 @@ import app from '@/api/panel/app' import type { Router } from 'vue-router' +// 防止重复显示错误消息 +let lastErrorMsg = '' +let lastErrorTime = 0 +const ERROR_COOLDOWN = 2000 + +function showErrorMessage(message: string) { + const now = Date.now() + if (lastErrorMsg !== message || now - lastErrorTime > ERROR_COOLDOWN) { + window.$message.error(message) + lastErrorMsg = message + lastErrorTime = now + } +} + export function createAppInstallGuard(router: Router) { router.beforeEach(async (to) => { const slug = to.path.split('/').pop() if (to.path.startsWith('/apps/') && slug) { - useRequest(app.isInstalled(slug)).onSuccess(({ data }) => { - if (!data.installed) { - window.$message.error(`应用 ${data.name} 未安装`) + await useRequest(app.isInstalled(slug)).onSuccess(({ data }) => { + if (!data) { + showErrorMessage(`应用未安装`) return router.push({ name: 'app-index' }) } }) @@ -15,9 +29,9 @@ export function createAppInstallGuard(router: Router) { // 网站 if (to.path.startsWith('/website')) { - useRequest(app.isInstalled('nginx')).onSuccess(({ data }) => { - if (!data.installed) { - window.$message.error(`Web 服务器 ${data.name} 未安装`) + await useRequest(app.isInstalled('nginx')).onSuccess(({ data }) => { + if (!data) { + showErrorMessage(`Web 服务器未安装`) return router.push({ name: 'app-index' }) } }) @@ -25,14 +39,10 @@ export function createAppInstallGuard(router: Router) { // 容器 if (to.path.startsWith('/container')) { - useRequest(app.isInstalled('docker')).onSuccess(({ data }) => { - if (!data.installed) { - useRequest(app.isInstalled('podman')).onSuccess(({ data }) => { - if (!data.installed) { - window.$message.error(`容器引擎 Docker / Podman 未安装`) - return router.push({ name: 'app-index' }) - } - }) + await useRequest(app.isInstalled('docker,podman')).onSuccess(({ data }) => { + if (!data) { + showErrorMessage(`容器引擎未安装`) + return router.push({ name: 'app-index' }) } }) } diff --git a/web/src/store/modules/theme/helpers.ts b/web/src/store/modules/theme/helpers.ts index 572dd145..ce0504a8 100644 --- a/web/src/store/modules/theme/helpers.ts +++ b/web/src/store/modules/theme/helpers.ts @@ -1,17 +1,5 @@ -import { addColorAlpha, getColorPalette } from '@/utils' -import type { GlobalThemeOverrides } from 'naive-ui' import themeSetting from '~/settings/theme.json' -type ColorType = 'primary' | 'info' | 'success' | 'warning' | 'error' -type ColorScene = '' | 'Suppl' | 'Hover' | 'Pressed' | 'Active' -type ColorKey = `${ColorType}Color${ColorScene}` -type ThemeColor = Partial> - -interface ColorAction { - scene: ColorScene - handler: (color: string) => string -} - /** 初始化主题配置 */ export function defaultSettings(): Theme.Setting { const isMobile = themeSetting.isMobile || false @@ -23,62 +11,8 @@ export function defaultSettings(): Theme.Setting { } const header = themeSetting.header || { visible: true, height: 60 } const tab = themeSetting.tab || { visible: true, height: 50 } - const primaryColor = themeSetting.primaryColor || '#00BFFF' - const otherColor = themeSetting.otherColor || { - info: '#0099ad', - success: '#52c41a', - warning: '#faad14', - error: '#f5222d' - } const locale = themeSetting.locale || 'zh_CN' const name = themeSetting.name || import.meta.env.VITE_APP_TITLE const logo = '' - return { isMobile, darkMode, sider, header, tab, primaryColor, otherColor, locale, name, logo } -} - -/** 获取naive的主题颜色 */ -export function getNaiveThemeOverrides(colors: Record): GlobalThemeOverrides { - const { primary, info, success, warning, error } = colors - - const themeColors = getThemeColors([ - ['primary', primary], - ['info', info], - ['success', success], - ['warning', warning], - ['error', error] - ]) - - const colorLoading = primary - - return { - common: { - ...themeColors - }, - LoadingBar: { - colorLoading - } - } -} - -/** 获取主题颜色的各种场景对应的颜色 */ -function getThemeColors(colors: [ColorType, string][]) { - const colorActions: ColorAction[] = [ - { scene: '', handler: (color) => color }, - { scene: 'Suppl', handler: (color) => color }, - { scene: 'Hover', handler: (color) => getColorPalette(color, 5) }, - { scene: 'Pressed', handler: (color) => getColorPalette(color, 7) }, - { scene: 'Active', handler: (color) => addColorAlpha(color, 0.1) } - ] - - const themeColor: ThemeColor = {} - - colors.forEach((color) => { - colorActions.forEach((action) => { - const [colorType, colorValue] = color - const colorKey: ColorKey = `${colorType}Color${action.scene}` - themeColor[colorKey] = action.handler(colorValue) - }) - }) - - return themeColor + return { isMobile, darkMode, sider, header, tab, locale, name, logo } } diff --git a/web/src/store/modules/theme/index.ts b/web/src/store/modules/theme/index.ts index 241bf76a..eea3c062 100644 --- a/web/src/store/modules/theme/index.ts +++ b/web/src/store/modules/theme/index.ts @@ -1,8 +1,8 @@ -import type { GlobalThemeOverrides, NDateLocale, NLocale } from 'naive-ui' +import type { NDateLocale, NLocale } from 'naive-ui' import { darkTheme, dateEnUS, dateJaJP, dateZhCN, dateZhTW, enUS, jaJP, zhCN, zhTW } from 'naive-ui' import type { BuiltInGlobalTheme } from 'naive-ui/es/themes/interface' -import { defaultSettings, getNaiveThemeOverrides } from './helpers' +import { defaultSettings } from './helpers' type ThemeState = Theme.Setting @@ -16,12 +16,6 @@ const locales: Record = { export const useThemeStore = defineStore('theme', { state: (): ThemeState => defaultSettings(), getters: { - naiveThemeOverrides(): GlobalThemeOverrides { - return getNaiveThemeOverrides({ - primary: this.primaryColor, - ...this.otherColor - }) - }, naiveTheme(): BuiltInGlobalTheme | undefined { return this.darkMode ? darkTheme : undefined }, @@ -52,10 +46,6 @@ export const useThemeStore = defineStore('theme', { setCollapsed(collapsed: boolean) { this.sider.collapsed = collapsed }, - /** 设置主题色 */ - setPrimaryColor(color: string) { - this.primaryColor = color - }, /** 设置语言 */ setLocale(locale: string) { this.locale = locale diff --git a/web/src/styles/index.scss b/web/src/styles/index.scss index d443de5f..f27b8949 100644 --- a/web/src/styles/index.scss +++ b/web/src/styles/index.scss @@ -71,9 +71,5 @@ body { &::-webkit-scrollbar-thumb { background: #bfbfbf; } - - &::-webkit-scrollbar-thumb:hover { - background: var(--primary-color); - } } } diff --git a/web/src/utils/common/naiveTools.ts b/web/src/utils/common/naiveTools.ts index 44ee0151..82825e91 100644 --- a/web/src/utils/common/naiveTools.ts +++ b/web/src/utils/common/naiveTools.ts @@ -5,8 +5,7 @@ import * as NaiveUI from 'naive-ui' export async function setupNaiveDiscreteApi() { const themeStore = useThemeStore() const configProviderProps = computed(() => ({ - theme: themeStore.naiveTheme, - themeOverrides: themeStore.naiveThemeOverrides + theme: themeStore.naiveTheme })) const { message, dialog, notification, loadingBar } = NaiveUI.createDiscreteApi( ['message', 'dialog', 'notification', 'loadingBar'], diff --git a/web/src/views/app/IndexView.vue b/web/src/views/app/IndexView.vue index 83ffb30b..619ff6a0 100644 --- a/web/src/views/app/IndexView.vue +++ b/web/src/views/app/IndexView.vue @@ -27,8 +27,7 @@ const columns: any = [ render(row: any) { return h(TheIcon, { icon: row.icon, - size: 26, - color: `var(--primary-color)` + size: 26 }) } }, @@ -211,12 +210,12 @@ onMounted(() => {