mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-14 02:20:53 +08:00
【同步】前端项目源码
【修复】工作流兼容问题
This commit is contained in:
77
frontend/apps/allin-ssl/src/views/layout/index.module.css
Normal file
77
frontend/apps/allin-ssl/src/views/layout/index.module.css
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 布局容器样式 */
|
||||
.layoutContainer {
|
||||
@apply min-h-screen flex flex-col;
|
||||
}
|
||||
|
||||
/* 侧边栏样式 */
|
||||
.sider {
|
||||
@apply h-screen dark:bg-gray-800 shadow-lg z-10 transition-all duration-300 ease-in-out;
|
||||
}
|
||||
|
||||
/* Logo容器样式 */
|
||||
.logoContainer {
|
||||
@apply flex items-center px-[2rem] h-[var(--n-sider-login-height)] border-b dark:border-gray-700 relative;
|
||||
border-color: var(--n-border-color);
|
||||
}
|
||||
|
||||
/* Logo容器激活样式 */
|
||||
.logoContainer span {
|
||||
@apply text-nowrap overflow-hidden overflow-ellipsis w-[10rem];
|
||||
}
|
||||
|
||||
/* Logo容器文本样式 */
|
||||
.logoContainerText {
|
||||
@apply flex items-center w-[20rem];
|
||||
}
|
||||
|
||||
/* Logo容器激活样式 */
|
||||
.logoContainerActive {
|
||||
@apply flex items-center justify-center px-[0];
|
||||
}
|
||||
|
||||
/* 折叠图标激活样式 */
|
||||
.collapsedIconActive {
|
||||
@apply !relative left-0 px-[1rem];
|
||||
}
|
||||
|
||||
/* 折叠按钮样式 */
|
||||
.collapsedIcon {
|
||||
@apply w-[4.2rem] h-[3.6rem] hover:bg-gray-200 hover:text-gray-500 hover:dark:bg-gray-500 absolute right-[1rem] rounded-[.4rem] flex items-center justify-center cursor-pointer transition-all duration-300;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
@apply h-[var(--n-header-height)] bg-[var(--n-header-color)] border-b dark:border-gray-700 shadow-sm z-10 transition-all duration-300 ease-in-out flex items-center justify-end px-6;
|
||||
border-color: var(--n-border-color);
|
||||
}
|
||||
|
||||
/* 系统信息样式 */
|
||||
.systemInfo {
|
||||
@apply flex items-center space-x-4 text-[1.2rem] text-gray-600 dark:text-gray-300;
|
||||
}
|
||||
|
||||
/* 内容区域样式 */
|
||||
.content {
|
||||
@apply flex-1 transition-all duration-300 ease-in-out bg-slate-50 dark:bg-gray-900 p-[var(--n-content-padding)] h-[calc(100vh-var(--n-main-diff-height))] overflow-y-auto;
|
||||
transition: padding 0s;
|
||||
}
|
||||
|
||||
/* 折叠按钮样式 */
|
||||
.collapseButton {
|
||||
@apply absolute right-0 top-1/2 -translate-y-1/2 translate-x-1/2 dark:bg-gray-800 rounded-full p-2 shadow-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 transition-all duration-300;
|
||||
}
|
||||
|
||||
/* 子路由导航样式 */
|
||||
.subRouteNav {
|
||||
@apply mb-4 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm;
|
||||
}
|
||||
|
||||
/* 子路由标题样式 */
|
||||
.subRouteTitle {
|
||||
@apply text-lg font-medium mb-2 text-gray-700 dark:text-gray-300;
|
||||
}
|
||||
|
||||
/* 子路由面包屑样式 */
|
||||
.breadcrumb {
|
||||
@apply bg-white dark:bg-gray-800 p-3 rounded-lg shadow-sm mb-4;
|
||||
}
|
||||
86
frontend/apps/allin-ssl/src/views/layout/index.tsx
Normal file
86
frontend/apps/allin-ssl/src/views/layout/index.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Transition, type Component as ComponentType, h } from 'vue'
|
||||
import { NBadge, NIcon, NLayout, NLayoutContent, NLayoutHeader, NLayoutSider, NMenu, NTooltip } from 'naive-ui'
|
||||
import { RouterView } from 'vue-router'
|
||||
|
||||
import { $t } from '@locales/index'
|
||||
import { useThemeCssVar } from '@baota/naive-ui/theme'
|
||||
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@vicons/antd'
|
||||
import { useController } from './useController'
|
||||
|
||||
import styles from './index.module.css'
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
// 获取控制器中的状态和方法
|
||||
const { menuItems, menuActive, isCollapsed, toggleCollapse, handleExpand, handleCollapse, updateMenuActive } =
|
||||
useController()
|
||||
|
||||
// 获取主题变量
|
||||
const cssVars = useThemeCssVar(['cardColor', 'headerColor'])
|
||||
|
||||
return () => (
|
||||
<NLayout class={styles.layoutContainer} hasSider style={cssVars.value}>
|
||||
<NLayoutSider
|
||||
width={200}
|
||||
collapsed={isCollapsed.value}
|
||||
collapse-mode="width"
|
||||
collapsed-width={60}
|
||||
onCollapse={handleCollapse}
|
||||
onExpand={handleExpand}
|
||||
class={styles.sider}
|
||||
bordered
|
||||
>
|
||||
<div class={styles.logoContainer + ' ' + (isCollapsed.value ? styles.logoContainerActive : '')}>
|
||||
{!isCollapsed.value ? (
|
||||
<div class={styles.logoContainerText}>
|
||||
<img src="/static/images/logo.png" alt="logo" class="h-8 w-8" />
|
||||
<span class="ml-4 text-[1.6rem] font-bold">{$t('t_1_1744164835667')}</span>
|
||||
</div>
|
||||
) : null}
|
||||
<NTooltip placement="right" trigger="hover">
|
||||
{{
|
||||
trigger: () => (
|
||||
<div
|
||||
class={styles.collapsedIcon + ' ' + (isCollapsed.value ? styles.collapsedIconActive : '')}
|
||||
onClick={() => toggleCollapse()}
|
||||
>
|
||||
<NIcon size={18}>{isCollapsed.value ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}</NIcon>
|
||||
</div>
|
||||
),
|
||||
default: () => <span>{isCollapsed.value ? $t('t_3_1744098802647') : $t('t_4_1744098802046')}</span>,
|
||||
}}
|
||||
</NTooltip>
|
||||
</div>
|
||||
<NMenu
|
||||
value={menuActive.value}
|
||||
onUpdateValue={updateMenuActive}
|
||||
options={menuItems.value}
|
||||
class="border-none"
|
||||
collapsed={isCollapsed.value}
|
||||
collapsed-width={60}
|
||||
collapsed-icon-size={20}
|
||||
/>
|
||||
</NLayoutSider>
|
||||
|
||||
<NLayout>
|
||||
<NLayoutHeader class={styles.header}>
|
||||
<div class={styles.systemInfo}>
|
||||
<NBadge value={1} show={false} dot>
|
||||
<span class="px-[.5rem] cursor-pointer">v1.0</span>
|
||||
</NBadge>
|
||||
</div>
|
||||
</NLayoutHeader>
|
||||
<NLayoutContent class={styles.content}>
|
||||
<RouterView>
|
||||
{({ Component }: { Component: ComponentType }) => (
|
||||
<Transition name="route-slide" mode="out-in">
|
||||
{Component && h(Component)}
|
||||
</Transition>
|
||||
)}
|
||||
</RouterView>
|
||||
</NLayoutContent>
|
||||
</NLayout>
|
||||
</NLayout>
|
||||
)
|
||||
},
|
||||
})
|
||||
146
frontend/apps/allin-ssl/src/views/layout/types.d.ts
vendored
Normal file
146
frontend/apps/allin-ssl/src/views/layout/types.d.ts
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @file 布局组件类型定义文件
|
||||
* @description 此文件包含布局组件及相关接口的 TypeScript 类型定义,
|
||||
* 包括布局属性、系统信息、公司信息、菜单项以及布局状态管理等类型定义。
|
||||
* @module views/layout/types
|
||||
*/
|
||||
|
||||
/**
|
||||
* 布局组件的Props接口定义
|
||||
* @interface LayoutProps
|
||||
* @property {VNode[]} [children] - 子节点列表
|
||||
*/
|
||||
export interface LayoutProps {
|
||||
children?: VNode[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统信息接口定义
|
||||
* @interface SystemInfo
|
||||
* @property {string} version - 系统版本号
|
||||
* @property {boolean} updateAvailable - 是否有可用更新
|
||||
* @property {boolean} isPro - 是否为专业版
|
||||
*/
|
||||
export interface SystemInfo {
|
||||
username: string
|
||||
version: string
|
||||
secret: string
|
||||
id: string
|
||||
server_id: string
|
||||
uid: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付信息接口定义
|
||||
* @interface PayAuthInfo
|
||||
* @property {string} auth - 支付类型
|
||||
* @property {number} count - 支付数量
|
||||
* @property {string} endtime - 支付结束时间
|
||||
*/
|
||||
export interface PayAuthInfo {
|
||||
auth: string
|
||||
count: number
|
||||
endtime: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新信息接口定义
|
||||
* @interface UpdateInfo
|
||||
* @property {string} currentVersion - 当前版本
|
||||
* @property {string} currentVersionDate - 当前版本发布时间
|
||||
* @property {string} newVersion - 新版本
|
||||
* @property {string} newVersionDate - 新版本发布时间
|
||||
* @property {string[]} upgradeLog - 更新日志
|
||||
*/
|
||||
export interface UpdateInfo {
|
||||
currentVersion: string
|
||||
currentVersionDate: string
|
||||
newVersion: string
|
||||
newVersionDate: string
|
||||
upgradeLog: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司信息接口定义
|
||||
* @interface CompanyInfo
|
||||
* @property {string} name - 公司名称
|
||||
* @property {string} copyright - 版权信息
|
||||
* @property {number} year - 年份
|
||||
*/
|
||||
export interface CompanyInfo {
|
||||
name: string
|
||||
copyright: string
|
||||
year: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单项接口定义
|
||||
* @interface MenuItem
|
||||
* @property {string} key - 菜单项唯一标识
|
||||
* @property {() => VNode} [icon] - 菜单图标渲染函数
|
||||
* @property {string} label - 菜单显示文本
|
||||
* @property {MenuItem[]} [children] - 子菜单项列表
|
||||
* @property {string} [path] - 菜单路由路径
|
||||
*/
|
||||
export interface MenuItem {
|
||||
key: string
|
||||
icon?: () => VNode
|
||||
label: string
|
||||
children?: MenuItem[]
|
||||
path?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 布局状态存储接口定义
|
||||
* @interface LayoutStoreState
|
||||
* @property {Ref<boolean>} collapsed - 侧边栏折叠状态
|
||||
* @property {Ref<SystemInfo>} systemInfo - 系统信息
|
||||
* @property {Ref<CompanyInfo>} companyInfo - 公司信息
|
||||
* @property {Ref<MenuItem[]>} menuItems - 菜单项列表
|
||||
* @property {Ref<string>} menuActive - 当前激活的菜单项
|
||||
* @property {Ref<string>} title - 页面标题
|
||||
* @property {() => void} openPayModal - 打开支付弹窗方法
|
||||
*/
|
||||
export interface LayoutStoreState {
|
||||
collapsed: Ref<boolean>
|
||||
systemInfo: Ref<SystemInfo>
|
||||
companyInfo: Ref<CompanyInfo>
|
||||
menuItems: Ref<MenuItem[]>
|
||||
menuActive: Ref<string>
|
||||
title: Ref<string>
|
||||
openPayModal: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* 布局状态管理方法接口定义
|
||||
* @interface LayoutStoreMethods
|
||||
* @property {() => void} toggleCollapse - 切换侧边栏折叠状态
|
||||
* @property {() => Promise<void>} fetchSystemInfo - 获取系统信息
|
||||
* @property {(info: Partial<CompanyInfo>) => void} updateCompanyInfo - 更新公司信息
|
||||
* @property {(title: string) => void} updateTitle - 更新页面标题
|
||||
*/
|
||||
export interface LayoutStoreMethods {
|
||||
toggleCollapse: () => void
|
||||
fetchSystemInfo: () => Promise<void>
|
||||
updateCompanyInfo: (info: Partial<CompanyInfo>) => void
|
||||
updateTitle: (title: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* 布局状态管理完整类型定义
|
||||
* @type {LayoutStoreState & LayoutStoreMethods}
|
||||
*/
|
||||
export type LayoutStoreType = LayoutStoreState & LayoutStoreMethods
|
||||
|
||||
/**
|
||||
* @description 路由名称类型定义
|
||||
*/
|
||||
export type RouteName =
|
||||
| 'logout'
|
||||
| 'settings'
|
||||
| 'home'
|
||||
| 'monitor'
|
||||
| 'certApply'
|
||||
| 'autoDeploy'
|
||||
| 'authApiManage'
|
||||
| 'certManage'
|
||||
183
frontend/apps/allin-ssl/src/views/layout/useController.tsx
Normal file
183
frontend/apps/allin-ssl/src/views/layout/useController.tsx
Normal file
@@ -0,0 +1,183 @@
|
||||
import { NIcon } from 'naive-ui'
|
||||
import { RouterLink, useRoute } from 'vue-router'
|
||||
import { useMessage, useDialog } from '@baota/naive-ui/hooks'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import { signOut } from '@api/public'
|
||||
import { routes } from '@router/index'
|
||||
import { $t } from '@locales/index'
|
||||
import { useStore } from './useStore'
|
||||
|
||||
import { SettingsOutline, LogOutOutline } from '@vicons/ionicons5'
|
||||
import { CloudMonitoring, Home, Flow } from '@vicons/carbon'
|
||||
import { Certificate20Regular, AddSquare24Regular } from '@vicons/fluent'
|
||||
import { ApiOutlined } from '@vicons/antd'
|
||||
|
||||
import type { MenuOption } from 'naive-ui/es/menu/src/interface'
|
||||
import type { RouteName } from './types'
|
||||
|
||||
/**
|
||||
* @description 图标映射类型
|
||||
*/
|
||||
type IconMap = Record<RouteName, Component>
|
||||
|
||||
/**
|
||||
* @description 布局控制器
|
||||
* @returns 返回布局相关状态和方法
|
||||
*/
|
||||
export const useController = () => {
|
||||
const store = useStore()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const message = useMessage()
|
||||
// const { useFormInput } = useFormHooks()
|
||||
const { handleError } = useError()
|
||||
const { resetDataInfo, menuActive, updateMenuActive } = store
|
||||
|
||||
/**
|
||||
* 当前路由是否为子路由
|
||||
*/
|
||||
const isChildRoute = ref(false)
|
||||
|
||||
/**
|
||||
* 当前子路由配置
|
||||
*/
|
||||
const childRouteConfig = ref<Record<string, any>>({})
|
||||
|
||||
/**
|
||||
* ==================== 弹窗相关功能 ====================
|
||||
*/
|
||||
|
||||
// ==============================
|
||||
// 图标渲染方法
|
||||
// ==============================
|
||||
|
||||
/**
|
||||
* @description 渲染导航图标
|
||||
* @param name - 路由名称
|
||||
* @returns 对应的图标组件
|
||||
*/
|
||||
const renderIcon = (name: RouteName) => {
|
||||
const iconObj: IconMap = {
|
||||
certManage: Certificate20Regular,
|
||||
autoDeploy: Flow,
|
||||
home: Home,
|
||||
certApply: AddSquare24Regular,
|
||||
monitor: CloudMonitoring,
|
||||
settings: SettingsOutline,
|
||||
logout: LogOutOutline,
|
||||
authApiManage: ApiOutlined,
|
||||
}
|
||||
return () => h(NIcon, null, () => h(iconObj[name] || 'div'))
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// 菜单相关方法
|
||||
// ==============================
|
||||
const menuItems = computed(() => {
|
||||
const routeMenuItems: MenuOption[] = routes.map((route) => ({
|
||||
key: route.name as RouteName,
|
||||
label: () => <RouterLink to={route.path}>{route?.meta?.title as string}</RouterLink>,
|
||||
icon: renderIcon(route.name as RouteName),
|
||||
}))
|
||||
return [
|
||||
...routeMenuItems,
|
||||
{
|
||||
key: 'logout',
|
||||
label: () => <a onClick={handleLogout}>{$t('t_0_1744168657526')}</a>,
|
||||
icon: renderIcon('logout'),
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 检查当前路由是否为子路由
|
||||
* @returns {void}
|
||||
*/
|
||||
const checkIsChildRoute = () => {
|
||||
// 获取当前路由路径
|
||||
const currentPath = route.path
|
||||
// 检查路由是否包含 /children/ 标识子路由
|
||||
isChildRoute.value = currentPath.includes('/children/')
|
||||
|
||||
// 如果是子路由,获取子路由配置
|
||||
if (isChildRoute.value) {
|
||||
// 获取当前激活的主路由
|
||||
const parentRoute = routes.find((route) => route.name === menuActive.value)
|
||||
// 如果找到了父路由,且父路由有子路由配置
|
||||
if (parentRoute && parentRoute.children) {
|
||||
// 查找当前的子路由
|
||||
const currentChild = parentRoute.children.find((child) => route.path.includes(child.path))
|
||||
childRouteConfig.value = currentChild || {}
|
||||
} else {
|
||||
childRouteConfig.value = {}
|
||||
}
|
||||
} else {
|
||||
childRouteConfig.value = {}
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
() => {
|
||||
if (route.name !== menuActive.value) {
|
||||
// 更新当前激活的菜单项
|
||||
updateMenuActive(route.name as RouteName)
|
||||
}
|
||||
// 检查是否为子路由
|
||||
checkIsChildRoute()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
/**
|
||||
* ==================== 用户操作功能 ====================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description 退出登录
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await useDialog({
|
||||
title: $t('t_15_1745457484292'),
|
||||
content: $t('t_16_1745457491607'),
|
||||
onPositiveClick: async () => {
|
||||
try {
|
||||
message.success($t('t_17_1745457488251'))
|
||||
await signOut().fetch()
|
||||
setTimeout(() => {
|
||||
// 重置数据信息
|
||||
resetDataInfo()
|
||||
// 删除会话存储
|
||||
sessionStorage.clear()
|
||||
// 路由跳转
|
||||
router.push('/login')
|
||||
}, 1000)
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
}
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ==================== 初始化逻辑 ====================
|
||||
*/
|
||||
|
||||
onMounted(async () => {
|
||||
// 初始化时检查是否为子路由
|
||||
checkIsChildRoute()
|
||||
})
|
||||
|
||||
return {
|
||||
...store,
|
||||
handleLogout,
|
||||
menuItems,
|
||||
isChildRoute,
|
||||
childRouteConfig,
|
||||
}
|
||||
}
|
||||
173
frontend/apps/allin-ssl/src/views/layout/useStore.tsx
Normal file
173
frontend/apps/allin-ssl/src/views/layout/useStore.tsx
Normal file
@@ -0,0 +1,173 @@
|
||||
import { useError } from '@baota/hooks/error'
|
||||
|
||||
import type { RouteName } from './types'
|
||||
import { DnsProviderOption, NotifyProviderOption } from '@/types/setting'
|
||||
import { getReportList } from '@api/setting'
|
||||
import { getAccessAllList } from '@api/index'
|
||||
|
||||
/**
|
||||
* @description 布局相关的状态管理
|
||||
* @warn 包含部分硬编码的业务数据,需要从API获取
|
||||
*/
|
||||
export const useLayoutStore = defineStore('layout-store', () => {
|
||||
const { handleError } = useError()
|
||||
|
||||
// ==============================
|
||||
// 状态定义
|
||||
// ==============================
|
||||
|
||||
/**
|
||||
* @description UI 相关状态
|
||||
*/
|
||||
const isCollapsed = useLocalStorage<boolean>('layout-collapsed', false)
|
||||
|
||||
/**
|
||||
* @description 消息通知
|
||||
*/
|
||||
const notifyProvider = ref<NotifyProviderOption[]>([])
|
||||
|
||||
/**
|
||||
* @description DNS提供商
|
||||
*/
|
||||
const dnsProvider = ref<DnsProviderOption[]>([])
|
||||
|
||||
/**
|
||||
* @description 导航状态
|
||||
*/
|
||||
const menuActive = useLocalStorage<RouteName>('menu-active', 'home')
|
||||
|
||||
/**
|
||||
* @description 布局内边距
|
||||
*/
|
||||
const layoutPadding = computed(() => {
|
||||
return menuActive.value !== 'home' ? 'var(--n-content-padding)' : '0'
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 语言
|
||||
*/
|
||||
const locales = useLocalStorage<string>('locales-active', 'zhCN')
|
||||
|
||||
// ==============================
|
||||
// UI 交互方法
|
||||
// ==============================
|
||||
|
||||
/**
|
||||
* @description 切换侧边栏折叠状态
|
||||
*/
|
||||
const toggleCollapse = (): void => {
|
||||
isCollapsed.value = !isCollapsed.value
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 展开侧边栏
|
||||
*/
|
||||
const handleCollapse = () => {
|
||||
isCollapsed.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 收起侧边栏
|
||||
*/
|
||||
|
||||
const handleExpand = () => {
|
||||
isCollapsed.value = false
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 更新菜单激活状态
|
||||
* @param active - 激活状态
|
||||
*/
|
||||
const updateMenuActive = (active: RouteName): void => {
|
||||
if (active === 'logout') return
|
||||
menuActive.value = active
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 重置数据信息
|
||||
*/
|
||||
const resetDataInfo = (): void => {
|
||||
menuActive.value = 'home'
|
||||
localStorage.removeItem('menu-active')
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// API 请求方法
|
||||
// ==============================
|
||||
|
||||
/**
|
||||
* @description 获取消息通知提供商
|
||||
* @returns 消息通知提供商
|
||||
*/
|
||||
const fetchNotifyProvider = async (): Promise<void> => {
|
||||
try {
|
||||
notifyProvider.value = []
|
||||
const { data } = await getReportList({ p: 1, search: '', limit: 1000 }).fetch()
|
||||
notifyProvider.value = data?.map((item) => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id.toString(),
|
||||
type: item.type,
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取DNS提供商
|
||||
* @param type - 类型
|
||||
* @returns DNS提供商
|
||||
*/
|
||||
const fetchDnsProvider = async (
|
||||
type: 'btpanel' | 'aliyun' | 'ssh' | 'tencentcloud' | '1panel' | 'dns' | '' = '',
|
||||
): Promise<void> => {
|
||||
try {
|
||||
dnsProvider.value = []
|
||||
const { data } = await getAccessAllList({ type }).fetch()
|
||||
console.timeEnd('loadDnsProviders')
|
||||
dnsProvider.value =
|
||||
data?.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id.toString(),
|
||||
type: item.type,
|
||||
})) || []
|
||||
console.timeEnd('loadDnsProviders')
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// 表单处理方法
|
||||
// ==============================
|
||||
|
||||
return {
|
||||
// 状态
|
||||
locales,
|
||||
notifyProvider,
|
||||
dnsProvider,
|
||||
isCollapsed,
|
||||
layoutPadding,
|
||||
menuActive,
|
||||
|
||||
// 方法
|
||||
resetDataInfo,
|
||||
updateMenuActive,
|
||||
toggleCollapse,
|
||||
handleCollapse,
|
||||
handleExpand,
|
||||
fetchNotifyProvider,
|
||||
fetchDnsProvider,
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 辅助函数:获取布局相关的状态和方法
|
||||
* @returns 组合了store实例和响应式引用的对象
|
||||
*/
|
||||
export const useStore = () => {
|
||||
const store = useLayoutStore()
|
||||
return { ...store, ...storeToRefs(store) }
|
||||
}
|
||||
Reference in New Issue
Block a user