2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 04:22:33 +08:00

feat: 设置页面初步完善及前端import lint

This commit is contained in:
耗子
2024-09-30 19:00:26 +08:00
parent 67055a5aac
commit dc0174c64e
116 changed files with 1380 additions and 237 deletions

View File

@@ -1,6 +1,7 @@
package biz
import (
"context"
"time"
"github.com/TheTNB/panel/internal/http/request"
@@ -34,6 +35,6 @@ type SettingRepo interface {
Get(key SettingKey, defaultValue ...string) (string, error)
Set(key SettingKey, value string) error
Delete(key SettingKey) error
GetPanelSetting() (*request.PanelSetting, error)
GetPanelSetting(ctx context.Context) (*request.PanelSetting, error)
UpdatePanelSetting(setting *request.PanelSetting) error
}

View File

@@ -1,13 +1,17 @@
package data
import (
"context"
"errors"
"path/filepath"
"github.com/spf13/cast"
"gorm.io/gorm"
"github.com/TheTNB/panel/internal/app"
"github.com/TheTNB/panel/internal/biz"
"github.com/TheTNB/panel/internal/http/request"
"github.com/TheTNB/panel/pkg/io"
)
type settingRepo struct{}
@@ -50,16 +54,50 @@ func (r *settingRepo) Delete(key biz.SettingKey) error {
return nil
}
func (r *settingRepo) GetPanelSetting() (*request.PanelSetting, error) {
setting := new(biz.Setting)
if err := app.Orm.Where("key = ?", biz.SettingKeyName).First(setting).Error; err != nil {
func (r *settingRepo) GetPanelSetting(ctx context.Context) (*request.PanelSetting, error) {
name := new(biz.Setting)
if err := app.Orm.Where("key = ?", biz.SettingKeyName).First(name).Error; err != nil {
return nil, err
}
websitePath := new(biz.Setting)
if err := app.Orm.Where("key = ?", biz.SettingKeyWebsitePath).First(websitePath).Error; err != nil {
return nil, err
}
backupPath := new(biz.Setting)
if err := app.Orm.Where("key = ?", biz.SettingKeyBackupPath).First(backupPath).Error; err != nil {
return nil, err
}
// TODO fix
userID := cast.ToUint(ctx.Value("user_id"))
if userID == 0 {
return nil, errors.New("获取用户 ID 失败")
}
user := new(biz.User)
if err := app.Orm.Where("id = ?", userID).First(user).Error; err != nil {
return nil, err
}
cert, err := io.Read(filepath.Join(app.Root, "panel/storage/cert.pem"))
if err != nil {
return nil, err
}
key, err := io.Read(filepath.Join(app.Root, "panel/storage/cert.key"))
if err != nil {
return nil, err
}
return &request.PanelSetting{
Name: setting.Value,
Name: name.Value,
Locale: app.Conf.String("app.locale"),
Entrance: app.Conf.String("http.entrance"),
WebsitePath: websitePath.Value,
BackupPath: backupPath.Value,
Username: user.Username,
Email: user.Email,
Port: app.Conf.Int("http.port"),
HTTPS: app.Conf.Bool("http.tls"),
Cert: cert,
Key: key,
}, nil
}
@@ -67,8 +105,14 @@ func (r *settingRepo) UpdatePanelSetting(setting *request.PanelSetting) error {
if err := r.Set(biz.SettingKeyName, setting.Name); err != nil {
return err
}
if err := r.Set(biz.SettingKeyWebsitePath, setting.WebsitePath); err != nil {
return err
}
if err := r.Set(biz.SettingKeyBackupPath, setting.BackupPath); err != nil {
return err
}
// TODO fix
// TODO fix other settings
return nil
}

View File

@@ -2,14 +2,14 @@ package request
type PanelSetting struct {
Name string `json:"name"`
Language string `json:"language"`
Locale string `json:"locale"`
Entrance string `json:"entrance"`
WebsitePath string `json:"website_path"`
BackupPath string `json:"backup_path"`
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
Port string `json:"port"`
Port int `json:"port"`
HTTPS bool `json:"https"`
Cert string `json:"cert"`
Key string `json:"key"`

View File

@@ -19,7 +19,7 @@ func NewSettingService() *SettingService {
}
func (s *SettingService) Get(w http.ResponseWriter, r *http.Request) {
setting, err := s.settingRepo.GetPanelSetting()
setting, err := s.settingRepo.GetPanelSetting(r.Context())
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
return

View File

@@ -3,6 +3,16 @@ require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
plugins: ['import'],
rules: {
'import/order': [
'error',
{
groups: [['builtin', 'external', 'internal']],
'newlines-between': 'always'
}
]
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',

View File

@@ -4,5 +4,8 @@
"tabWidth": 2,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
"trailingComma": "none",
"plugins": [
"prettier-plugin-organize-imports"
]
}

View File

@@ -1,4 +1,5 @@
import type { ProxyOptions } from 'vite'
import { getProxyConfig } from '../../settings/proxy-config'
export function createViteProxy(isUseProxy = true, proxyType: ProxyType) {

View File

@@ -1,14 +1,8 @@
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
/**
* * unplugin-icons应用自动引入iconify图标
* usage: https://github.com/antfu/unplugin-icons
* 图标库: https://icones.js.org/
*/
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import Icons from 'unplugin-icons/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite'
export default [
AutoImport({

View File

@@ -31,6 +31,7 @@
"install": "^0.13.0",
"lodash-es": "^4.17.21",
"pinia": "^2.2.2",
"remove": "^0.1.5",
"vue": "^3.5.5",
"vue-echarts": "^7.0.3",
"vue-i18n": "^10.0.1",
@@ -50,12 +51,14 @@
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/tsconfig": "^0.5.1",
"colord": "^2.9.3",
"eslint": "^8.57.0",
"eslint": "^8.57.1",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-vue": "^9.28.0",
"monaco-editor": "^0.52.0",
"naive-ui": "^2.39.0",
"npm-run-all2": "^6.2.3",
"prettier": "^3.3.3",
"prettier-plugin-organize-imports": "^4.1.0",
"sass": "^1.78.0",
"typescript": "^5.5.4",
"unocss": "^0.63.0",

980
web/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,5 +21,5 @@
"warning": "#F0A020",
"error": "#D03050"
},
"language": "zh_CN"
"locale": "zh_CN"
}

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 保护列表
jails: (page: number, limit: number): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取配置
config: (service: string): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取配置
config: (): Promise<AxiosResponse<any>> => request.get('/apps/gitea/config'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 负载状态
load: (): Promise<AxiosResponse<any>> => request.get('/apps/mysql/load'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 负载状态
load: (): Promise<AxiosResponse<any>> => request.get('/apps/openresty/load'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 负载状态
load: (version: number): Promise<AxiosResponse<any>> => request.get(`/apps/php/${version}/load`),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取信息
info: (): Promise<AxiosResponse<any>> => request.get('/apps/phpmyadmin/info'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取注册表配置
registryConfig: (): Promise<AxiosResponse<any>> => request.get('/apps/podman/registryConfig'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 负载状态
load: (): Promise<AxiosResponse<any>> => request.get('/apps/postgresql/load'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 列表
list: (page: number, limit: number): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 负载状态
load: (): Promise<AxiosResponse<any>> => request.get('/apps/redis/load'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取配置
config: (): Promise<AxiosResponse<any>> => request.get('/apps/rsync/config'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 列表
list: (page: number, limit: number): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 服务名称
service: (): Promise<AxiosResponse<any>> => request.get('/apps/supervisor/service'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// DNS
dns: (): Promise<AxiosResponse<any>> => request.get('/apps/toolbox/dns'),

View File

@@ -1,19 +1,18 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取应用列表
list: (page: number, limit: number): Promise<AxiosResponse<any>> =>
request.get('/app/list', { params: { page, limit } }),
// 安装应用
install: (slug: string): Promise<AxiosResponse<any>> =>
request.post('/app/install', { slug }),
install: (slug: string): Promise<AxiosResponse<any>> => request.post('/app/install', { slug }),
// 卸载应用
uninstall: (slug: string): Promise<AxiosResponse<any>> =>
request.post('/app/uninstall', { slug }),
// 更新应用
update: (slug: string): Promise<AxiosResponse<any>> =>
request.post('/app/update', { slug }),
update: (slug: string): Promise<AxiosResponse<any>> => request.post('/app/update', { slug }),
// 设置首页显示
updateShow: (slug: string, show: boolean): Promise<AxiosResponse<any>> =>
request.post('/app/updateShow', { slug, show }),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// CA 供应商列表
caProviders: (): Promise<AxiosResponse<any>> => request.get('/cert/caProviders'),
@@ -19,8 +20,7 @@ export default {
userUpdate: (id: number, data: any): Promise<AxiosResponse<any>> =>
request.put(`/cert/users/${id}`, data),
// ACME 用户删除
userDelete: (id: number): Promise<AxiosResponse<any>> =>
request.delete(`/cert/users/${id}`),
userDelete: (id: number): Promise<AxiosResponse<any>> => request.delete(`/cert/users/${id}`),
// DNS 记录列表
dns: (page: number, limit: number): Promise<AxiosResponse<any>> =>
request.get('/cert/dns', { params: { page, limit } }),
@@ -44,15 +44,13 @@ export default {
certUpdate: (id: number, data: any): Promise<AxiosResponse<any>> =>
request.put(`/cert/certs/${id}`, data),
// 证书删除
certDelete: (id: number): Promise<AxiosResponse<any>> =>
request.delete(`/cert/certs/${id}`),
certDelete: (id: number): Promise<AxiosResponse<any>> => request.delete(`/cert/certs/${id}`),
// 签发
obtain: (id: number): Promise<AxiosResponse<any>> => request.post(`/cert/obtain`, { id }),
// 续签
renew: (id: number): Promise<AxiosResponse<any>> => request.post(`/cert/renew`, { id }),
// 获取 DNS 记录
manualDNS: (id: number): Promise<AxiosResponse<any>> =>
request.post(`/cert/manualDNS`, { id }),
manualDNS: (id: number): Promise<AxiosResponse<any>> => request.post(`/cert/manualDNS`, { id }),
// 部署
deploy: (id: number, website_id: number): Promise<AxiosResponse<any>> =>
request.post(`/cert/deploy`, { id, website_id })

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取容器列表
containerList: (page: number, limit: number): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取任务列表
list: (page: number, limit: number): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 创建文件/文件夹
create: (path: string, dir: boolean): Promise<AxiosResponse<any>> =>
@@ -12,8 +13,7 @@ export default {
save: (path: string, content: string): Promise<AxiosResponse<any>> =>
request.post('/file/save', { path, content }),
// 删除文件
delete: (path: string): Promise<AxiosResponse<any>> =>
request.post('/file/delete', { path }),
delete: (path: string): Promise<AxiosResponse<any>> => request.post('/file/delete', { path }),
// 上传文件
upload: (path: string, formData: FormData, onProgress: any): Promise<AxiosResponse<any>> => {
formData.append('path', path)
@@ -42,8 +42,7 @@ export default {
mode: string,
owner: string,
group: string
): Promise<AxiosResponse<any>> =>
request.post('/file/permission', { path, mode, owner, group }),
): Promise<AxiosResponse<any>> => request.post('/file/permission', { path, mode, owner, group }),
// 压缩文件
archive: (paths: string[], file: string): Promise<AxiosResponse<any>> =>
request.post('/file/archive', { paths, file }),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 面板信息
panel: (): Promise<Response> => fetch('/api/info/panel'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 开关
switch: (monitor: boolean): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取防火墙状态
firewallStatus: (): Promise<AxiosResponse<any>> => request.get('/safe/firewallStatus'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取设置
list: (): Promise<AxiosResponse<any>> => request.get('/setting'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取信息
info: (): Promise<AxiosResponse<any>> => request.get('/ssh/info'),

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 服务状态
status: (service: string): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 获取状态
status: (): Promise<AxiosResponse<any>> => request.get('/task/status'),
@@ -8,8 +9,7 @@ export default {
list: (page: number, limit: number): Promise<AxiosResponse<any>> =>
request.get('/task/list', { params: { page, limit } }),
// 获取任务日志
log: (id: number): Promise<AxiosResponse<any>> =>
request.get('/task/log', { params: { id } }),
log: (id: number): Promise<AxiosResponse<any>> => request.get('/task/log', { params: { id } }),
// 删除任务
delete: (id: number): Promise<AxiosResponse<any>> => request.post('/task/delete', { id })
}

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 登录
login: (username: string, password: string): Promise<AxiosResponse<any>> =>

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils'
import type { AxiosResponse } from 'axios'
import { request } from '@/utils'
export default {
// 列表
list: (page: number, limit: number): Promise<AxiosResponse<any>> =>

View File

@@ -1,7 +1,8 @@
<script lang="ts" setup>
import { kebabCase } from 'lodash-es'
import { useCssVar } from '@vueuse/core'
import { kebabCase } from 'lodash-es'
import type { GlobalThemeOverrides } from 'naive-ui'
import { useThemeStore } from '@/store'
type ThemeVars = Exclude<GlobalThemeOverrides['common'], undefined>

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import file from '@/api/panel/file'
import { languageByPath } from '@/utils/file'

View File

@@ -227,7 +227,7 @@
"label": "Panel name",
"placeholder": "Rat Panel"
},
"language": {
"locale": {
"label": "Language",
"placeholder": "Select language"
},

View File

@@ -1,9 +1,10 @@
import type { App } from 'vue'
import { createI18n } from 'vue-i18n'
import type { Composer } from 'vue-i18n'
import { createI18n } from 'vue-i18n'
import { useThemeStore } from '@/store'
import en from './en.json'
import zh_CN from './zh_CN.json'
import { useThemeStore } from '@/store'
let i18n: ReturnType<typeof createI18n>
@@ -12,7 +13,7 @@ export function setupI18n(app: App) {
i18n = createI18n({
legacy: false,
globalInjection: true,
locale: themeStore.language,
locale: themeStore.locale,
fallbackLocale: 'zh_CN',
messages: {
en: en,

View File

@@ -227,7 +227,7 @@
"label": "面板名称",
"placeholder": "耗子面板"
},
"language": {
"locale": {
"label": "语言",
"placeholder": "选择语言"
},

View File

@@ -1,10 +1,9 @@
<script lang="ts" setup>
import SideBar from './sidebar/IndexView.vue'
import AppHeader from './header/IndexView.vue'
import AppTab from './tab/IndexView.vue'
import AppMain from './AppMain.vue'
import { useThemeStore } from '@/store'
import AppMain from './AppMain.vue'
import AppHeader from './header/IndexView.vue'
import SideBar from './sidebar/IndexView.vue'
import AppTab from './tab/IndexView.vue'
const themeStore = useThemeStore()
</script>

View File

@@ -1,10 +1,10 @@
<script lang="ts" setup>
import BreadCrumb from './components/BreadCrumb.vue'
import MenuCollapse from './components/MenuCollapse.vue'
import FullScreen from './components/FullScreen.vue'
import UserAvatar from './components/UserAvatar.vue'
import ThemeMode from './components/ThemeMode.vue'
import ReloadPage from '@/layout/header/components/ReloadPage.vue'
import BreadCrumb from './components/BreadCrumb.vue'
import FullScreen from './components/FullScreen.vue'
import MenuCollapse from './components/MenuCollapse.vue'
import ThemeMode from './components/ThemeMode.vue'
import UserAvatar from './components/UserAvatar.vue'
</script>
<template>

View File

@@ -1,7 +1,8 @@
<script lang="ts" setup>
import { useI18n } from 'vue-i18n'
import { renderIcon } from '@/utils'
import type { Meta } from '~/types/router'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const router = useRouter()

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { router } from '@/router'
import { useUserStore } from '@/store'
import { renderIcon } from '@/utils'
import { router } from '@/router'
const userStore = useUserStore()

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { useThemeStore } from '@/store'
import logo from '@/assets/images/logo.png'
import { title } from '@/main'
import { useThemeStore } from '@/store'
const themeStore = useThemeStore()
</script>

View File

@@ -1,11 +1,12 @@
<script lang="ts" setup>
import type { MenuInst, MenuOption } from 'naive-ui'
import type { Meta, RouteType } from '~/types/router'
import { useAppStore, usePermissionStore, useThemeStore } from '@/store'
import { isUrl, renderIcon } from '@/utils'
import type { VNodeChild } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppStore, usePermissionStore, useThemeStore } from '@/store'
import { isUrl, renderIcon } from '@/utils'
import type { Meta, RouteType } from '~/types/router'
const { t } = useI18n()
const router = useRouter()
const currentRoute = useRoute()

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import ContextMenu from './components/ContextMenu.vue'
import type { TabItem } from '@/store'
import { useTabStore } from '@/store'
import ContextMenu from './components/ContextMenu.vue'
const route = useRoute()
const router = useRouter()

View File

@@ -1,15 +1,16 @@
import '@/styles/reset.css'
import '@/styles/index.scss'
import '@/styles/reset.css'
import 'uno.css'
import { createApp } from 'vue'
import App from './App.vue'
import { setupStore, useThemeStore } from './store'
import { setupRouter } from './router'
import { setupI18n } from '@/i18n/i18n'
import { setupNaiveDiscreteApi } from './utils'
import { install as VueMonacoEditorPlugin } from '@guolao/vue-monaco-editor'
import { createApp } from 'vue'
import info from '@/api/panel/info'
import { setupI18n } from '@/i18n/i18n'
import App from './App.vue'
import { setupRouter } from './router'
import { setupStore, useThemeStore } from './store'
import { setupNaiveDiscreteApi } from './utils'
async function setupApp() {
const app = createApp(App)
@@ -39,7 +40,7 @@ const setupPanel = async () => {
.then((response) => response.json())
.then((data) => {
title.value = data.data.name || import.meta.env.VITE_APP_TITLE
themeStore.setLanguage(data.data.language || 'zh_CN')
themeStore.setLocale(data.data.locale || 'zh_CN')
})
.catch((err) => {
console.error(err)

View File

@@ -1,4 +1,5 @@
import type { Router } from 'vue-router'
import app from '@/api/panel/app'
export function createAppInstallGuard(router: Router) {

View File

@@ -1,7 +1,8 @@
import type { Router } from 'vue-router'
import { createAppInstallGuard } from './app-install-guard'
import { createPageLoadingGuard } from './page-loading-guard'
import { createPageTitleGuard } from './page-title-guard'
import { createAppInstallGuard } from './app-install-guard'
export function setupRouterGuard(router: Router) {
createPageLoadingGuard(router)

View File

@@ -1,7 +1,7 @@
import type { Router } from 'vue-router'
import { title } from '@/main'
import { trans } from '@/i18n/i18n'
import { title } from '@/main'
export function createPageTitleGuard(router: Router) {
router.afterEach((to) => {

View File

@@ -1,9 +1,10 @@
import type { App } from 'vue'
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import { setupRouterGuard } from './guard'
import { basicRoutes, EMPTY_ROUTE, NOT_FOUND_ROUTE } from './routes'
import { usePermissionStore } from '@/store'
import type { RoutesType, RouteType } from '~/types/router'
import { setupRouterGuard } from './guard'
import { basicRoutes, EMPTY_ROUTE, NOT_FOUND_ROUTE } from './routes'
const isHash = import.meta.env.VITE_USE_HASH === 'true'
export const router = createRouter({

View File

@@ -1,7 +1,8 @@
import { defineStore } from 'pinia'
import { filterAsyncRoutes } from './helpers'
import { asyncRoutes, basicRoutes } from '@/router/routes'
import type { RoutesType } from '~/types/router'
import { filterAsyncRoutes } from './helpers'
export const usePermissionStore = defineStore('permission', {
state() {

View File

@@ -1,7 +1,8 @@
import { defineStore } from 'pinia'
import { activeTab, tabs, WITHOUT_TAB_PATHS } from './helpers'
import { router } from '@/router'
import { setSession } from '@/utils'
import { activeTab, tabs, WITHOUT_TAB_PATHS } from './helpers'
export interface TabItem {
name: string

View File

@@ -1,6 +1,7 @@
import type { GlobalThemeOverrides } from 'naive-ui'
import themeSetting from '~/settings/theme.json'
import { addColorAlpha, getColorPalette } from '@/utils'
import themeSetting from '~/settings/theme.json'
type ColorType = 'primary' | 'info' | 'success' | 'warning' | 'error'
type ColorScene = '' | 'Suppl' | 'Hover' | 'Pressed' | 'Active'
@@ -30,8 +31,8 @@ export function initThemeSettings(): Theme.Setting {
warning: '#faad14',
error: '#f5222d'
}
const language = themeSetting.language || 'zh_CN'
return { isMobile, darkMode, sider, header, tab, primaryColor, otherColor, language }
const locale = themeSetting.locale || 'zh_CN'
return { isMobile, darkMode, sider, header, tab, primaryColor, otherColor, locale }
}
/** 获取naive的主题颜色 */

View File

@@ -1,4 +1,5 @@
import {
darkTheme,
dateEnUS,
dateZhCN,
enUS,
@@ -7,9 +8,9 @@ import {
type NLocale,
zhCN
} from 'naive-ui'
import { darkTheme } from 'naive-ui'
import type { BuiltInGlobalTheme } from 'naive-ui/es/themes/interface'
import { defineStore } from 'pinia'
import { getNaiveThemeOverrides, initThemeSettings } from './helpers'
type ThemeState = Theme.Setting
@@ -32,10 +33,10 @@ export const useThemeStore = defineStore('theme-store', {
return this.darkMode ? darkTheme : undefined
},
naiveLocale(): NLocale {
return locales[this.language].locale
return locales[this.locale].locale
},
naiveDateLocale(): NDateLocale {
return locales[this.language].dateLocale
return locales[this.locale].dateLocale
}
},
actions: {
@@ -63,8 +64,8 @@ export const useThemeStore = defineStore('theme-store', {
this.primaryColor = color
},
/** 设置语言 */
setLanguage(language: string) {
this.language = language
setLocale(language: string) {
this.locale = language
}
}
})

View File

@@ -1,8 +1,9 @@
import { defineStore } from 'pinia'
import { toLogin } from '@/utils'
import { usePermissionStore, useTabStore } from '@/store'
import { resetRouter } from '@/router'
import user from '@/api/panel/user'
import { resetRouter } from '@/router'
import { usePermissionStore, useTabStore } from '@/store'
import { toLogin } from '@/utils'
interface UserInfo {
id?: string

View File

@@ -1,6 +1,6 @@
import { h } from 'vue'
import { Icon } from '@iconify/vue'
import { NIcon } from 'naive-ui'
import { h } from 'vue'
interface Props {
size?: number

View File

@@ -1,5 +1,5 @@
export * from './common'
export * from './color'
export * from './common'
export * from './crypto'
export * from './icon'
export * from './is'

View File

@@ -1,4 +1,5 @@
import * as NaiveUI from 'naive-ui'
import { useThemeStore } from '@/store'
export async function setupNaiveDiscreteApi() {

View File

@@ -315,15 +315,15 @@ const lastDirectory = (path: string) => {
}
export {
getExt,
getBase,
getIconByExt,
languageByPath,
checkName,
checkPath,
getFilename,
isArchive,
formatPercent,
formatBytes,
formatPercent,
getBase,
getExt,
getFilename,
getIconByExt,
isArchive,
languageByPath,
lastDirectory
}

View File

@@ -1,5 +1,5 @@
import type { ErrorResolveResponse } from '~/types/axios'
import { useUserStore } from '@/store'
import type { ErrorResolveResponse } from '~/types/axios'
/** 自定义错误 */
export class AxiosRejectError extends Error {

View File

@@ -1,4 +1,5 @@
import axios from 'axios'
import { reqReject, reqResolve, resReject, resResolve } from './interceptors'
export function createAxios(options = {}) {

View File

@@ -1,6 +1,7 @@
import type { AxiosError, AxiosResponse } from 'axios'
import { AxiosRejectError, resolveResError } from './helpers'
import type { RequestConfig } from '~/types/axios'
import { AxiosRejectError, resolveResError } from './helpers'
/** 请求拦截 */
export function reqResolve(config: RequestConfig) {

View File

@@ -1,6 +1,6 @@
export * from './auth'
export * from './common'
export * from './event'
export * from './http'
export * from './file'
export * from './http'
export * from './storage'

View File

@@ -1,11 +1,12 @@
<script setup lang="ts">
import type { App } from '@/views/app/types'
import { NButton, NDataTable, NPopconfirm, NSwitch } from 'naive-ui'
import app from '../../api/panel/app'
import { renderIcon } from '@/utils'
import { router } from '@/router'
import { useI18n } from 'vue-i18n'
import { router } from '@/router'
import { renderIcon } from '@/utils'
import type { App } from '@/views/app/types'
import app from '../../api/panel/app'
const { t } = useI18n()
const columns: any = [

View File

@@ -1,10 +1,11 @@
<script setup lang="ts">
import { NButton, NDataTable, NInput, NPopconfirm, NSwitch } from 'naive-ui'
import fail2ban from '@/api/apps/fail2ban'
import service from '@/api/panel/system/service'
import website from '@/api/panel/website'
import { renderIcon } from '@/utils'
import type { Jail } from '@/views/apps/fail2ban/types'
import website from '@/api/panel/website'
const currentTab = ref('status')
const status = ref(false)

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { NButton, NPopconfirm } from 'naive-ui'
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NPopconfirm } from 'naive-ui'
import frp from '@/api/apps/frp'
import service from '@/api/panel/system/service'

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { NButton, NPopconfirm } from 'naive-ui'
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NPopconfirm } from 'naive-ui'
import gitea from '@/api/apps/gitea'
import service from '@/api/panel/system/service'

View File

@@ -1,11 +1,12 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import type { MessageReactive, UploadFileInfo } from 'naive-ui'
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import mysql from '@/api/apps/mysql'
import service from '@/api/panel/system/service'
import { generateRandomString, renderIcon } from '@/utils'
import type { Backup, Database, User } from '@/views/apps/mysql/types'
import type { UploadFileInfo, MessageReactive } from 'naive-ui'
import Editor from '@guolao/vue-monaco-editor'
let messageReactive: MessageReactive | null = null

View File

@@ -1,8 +1,9 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NPopconfirm } from 'naive-ui'
import openresty from '@/api/apps/openresty'
import service from '@/api/panel/system/service'
import Editor from '@guolao/vue-monaco-editor'
const currentTab = ref('status')
const status = ref(false)

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NPopconfirm } from 'naive-ui'
import php from '@/api/apps/php'
import service from '@/api/panel/system/service'
import { renderIcon } from '@/utils'
import Editor from '@guolao/vue-monaco-editor'
const route = useRoute()
const currentTab = ref('status')

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { NButton } from 'naive-ui'
import phpmyadmin from '@/api/apps/phpmyadmin'
import Editor from '@guolao/vue-monaco-editor'
import { NButton } from 'naive-ui'
import phpmyadmin from '@/api/apps/phpmyadmin'
const currentTab = ref('status')
const hostname = ref(window.location.hostname)

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { NButton, NPopconfirm } from 'naive-ui'
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NPopconfirm } from 'naive-ui'
import podman from '@/api/apps/podman'
import service from '@/api/panel/system/service'

View File

@@ -1,11 +1,12 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import type { MessageReactive, UploadFileInfo } from 'naive-ui'
import { NButton, NDataTable, NFlex, NInput, NPopconfirm, NTag } from 'naive-ui'
import postgresql from '@/api/apps/postgresql'
import service from '@/api/panel/system/service'
import { generateRandomString, renderIcon } from '@/utils'
import type { Backup, Database, Role } from '@/views/apps/postgresql/types'
import type { UploadFileInfo, MessageReactive } from 'naive-ui'
import Editor from '@guolao/vue-monaco-editor'
let messageReactive: MessageReactive | null = null

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import { generateRandomString, renderIcon } from '@/utils'
import type { User } from '@/views/apps/pureftpd/types'
import pureftpd from '@/api/apps/pureftpd'
import service from '@/api/panel/system/service'
import { generateRandomString, renderIcon } from '@/utils'
import type { User } from '@/views/apps/pureftpd/types'
const currentTab = ref('status')
const status = ref(false)

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { NButton, NDataTable, NPopconfirm } from 'naive-ui'
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NPopconfirm } from 'naive-ui'
import redis from '@/api/apps/redis'
import service from '@/api/panel/system/service'

View File

@@ -1,10 +1,11 @@
<script setup lang="ts">
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import { generateRandomString, renderIcon } from '@/utils'
import Editor from '@guolao/vue-monaco-editor'
import type { Module } from '@/views/apps/rsync/types'
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import rsync from '@/api/apps/rsync'
import service from '@/api/panel/system/service'
import { generateRandomString, renderIcon } from '@/utils'
import type { Module } from '@/views/apps/rsync/types'
const currentTab = ref('status')
const status = ref(false)

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import s3fs from '@/api/apps/s3fs'
import { renderIcon } from '@/utils'
import type { S3fs } from '@/views/apps/s3fs/types'

View File

@@ -1,10 +1,11 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import supervisor from '@/api/apps/supervisor'
import service from '@/api/panel/system/service'
import { renderIcon } from '@/utils'
import type { Process } from '@/views/apps/supervisor/types'
import Editor from '@guolao/vue-monaco-editor'
const currentTab = ref('status')
const serviceName = ref('supervisor')

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { NButton } from 'naive-ui'
import toolbox from '@/api/apps/toolbox'
import Editor from '@guolao/vue-monaco-editor'
import { NButton } from 'naive-ui'
import toolbox from '@/api/apps/toolbox'
const currentTab = ref('dns')
const dns1 = ref('')

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import { NButton, NDataTable, NPopconfirm, NSpace, NSwitch, NTable, NTag } from 'naive-ui'
import cert from '@/api/panel/cert'
import type { Cert } from '@/views/cert/types'
import website from '@/api/panel/website'
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NPopconfirm, NSpace, NSwitch, NTable, NTag } from 'naive-ui'
import cert from '@/api/panel/cert'
import website from '@/api/panel/website'
import type { Cert } from '@/views/cert/types'
let messageReactive: any
const addCertModel = ref<any>({

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { NButton, NDataTable, NInput, NPopconfirm, NSpace, NTag } from 'naive-ui'
import cert from '@/api/panel/cert'
import type { DNS } from '@/views/cert/types'

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import CertView from '@/views/cert/CertView.vue'
import UserView from '@/views/cert/UserView.vue'
import DNSView from '@/views/cert/DNSView.vue'
import UserView from '@/views/cert/UserView.vue'
const currentTab = ref('cert')
</script>

View File

@@ -8,6 +8,7 @@ import {
NSpace,
NTag
} from 'naive-ui'
import cert from '@/api/panel/cert'
import type { User } from '@/views/cert/types'

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import { NButton, NDataTable, NSwitch, NDropdown, NInput } from 'naive-ui'
import type { ContainerList } from '@/views/container/types'
import container from '@/api/panel/container'
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NDropdown, NInput, NSwitch } from 'naive-ui'
import container from '@/api/panel/container'
import ContainerCreate from '@/views/container/ContainerCreate.vue'
import type { ContainerList } from '@/views/container/types'
const data = ref<ContainerList[]>([] as ContainerList[])

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { NButton, NDataTable, NFlex, NInput, NPopconfirm, NTag } from 'naive-ui'
import type { ImageList } from '@/views/container/types'
import container from '@/api/panel/container'
import type { ImageList } from '@/views/container/types'
const pullModel = ref({
name: '',

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { NButton, NDataTable, NFlex, NInput, NPopconfirm, NTag } from 'naive-ui'
import type { NetworkList } from '@/views/container/types'
import container from '@/api/panel/container'
import type { NetworkList } from '@/views/container/types'
const createModel = ref({
name: '',

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui'
import type { VolumeList } from '@/views/container/types'
import container from '@/api/panel/container'
import type { VolumeList } from '@/views/container/types'
const createModel = ref({
name: '',

View File

@@ -1,11 +1,12 @@
<script setup lang="ts">
import Editor from '@guolao/vue-monaco-editor'
import { NButton, NDataTable, NInput, NPopconfirm, NSwitch } from 'naive-ui'
import cron from '@/api/panel/cron'
import info from '@/api/panel/info'
import website from '@/api/panel/website'
import cron from '@/api/panel/cron'
import { NButton, NDataTable, NInput, NPopconfirm, NSwitch } from 'naive-ui'
import type { CronTask } from '@/views/cron/types'
import { renderIcon } from '@/utils'
import Editor from '@guolao/vue-monaco-editor'
import type { CronTask } from '@/views/cron/types'
const addModel = ref({
name: '',

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { NButton, NInput } from 'naive-ui'
import { generateRandomString, getBase } from '@/utils'
import * as api from '@/api/panel/file'
import { generateRandomString, getBase } from '@/utils'
import EventBus from '@/utils/event'
const show = defineModel<boolean>('show', { type: Boolean, required: true })

View File

@@ -1,10 +1,10 @@
<script setup lang="ts">
import PathInput from '@/views/file/PathInput.vue'
import ToolBar from '@/views/file/ToolBar.vue'
import ListTable from '@/views/file/ListTable.vue'
import type { Marked } from '@/views/file/types'
import ArchiveModal from '@/views/file/ArchiveModal.vue'
import ListTable from '@/views/file/ListTable.vue'
import PathInput from '@/views/file/PathInput.vue'
import PermissionModal from '@/views/file/PermissionModal.vue'
import ToolBar from '@/views/file/ToolBar.vue'
import type { Marked } from '@/views/file/types'
const path = ref('/www')
const selected = ref<string[]>([])

View File

@@ -2,11 +2,12 @@
import type { DataTableColumns } from 'naive-ui'
import { NButton, NInput, NPopconfirm, NPopselect, NSpace } from 'naive-ui'
import type { RowData } from 'naive-ui/es/data-table/src/interface'
import file from '@/api/panel/file'
import TheIcon from '@/components/custom/TheIcon.vue'
import EventBus from '@/utils/event'
import { checkName, checkPath, getExt, getFilename, getIconByExt, isArchive } from '@/utils/file'
import EditModal from '@/views/file/EditModal.vue'
import EventBus from '@/utils/event'
import type { Marked } from '@/views/file/types'
const loading = ref(false)

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import type { InputInst } from 'naive-ui'
import EventBus from '@/utils/event'
import { onUnmounted } from 'vue'
import EventBus from '@/utils/event'
import { checkPath } from '@/utils/file'
const path = defineModel<string>('path', { type: String, required: true })

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { NButton, NInput } from 'naive-ui'
import file from '@/api/panel/file'
import EventBus from '@/utils/event'

Some files were not shown because too many files have changed in this diff Show More