2025-12-09 14:31:11 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="app-container">
|
2025-12-10 14:34:29 +08:00
|
|
|
<d-header class="dheader">
|
|
|
|
|
<Header />
|
|
|
|
|
</d-header>
|
2025-12-09 14:31:11 +08:00
|
|
|
<d-layout class="main-layout">
|
|
|
|
|
<d-aside class="sidebar">
|
|
|
|
|
<div class="user-profile">
|
|
|
|
|
<div class="avatar-area">
|
|
|
|
|
<span class="username">用户名</span>
|
|
|
|
|
<d-icon name="edit" size="14px" color="#666" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="user-email">免费计划 · 123456@gmail.com</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="nav-menu">
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'overview' }"
|
|
|
|
|
@click="activeMenu = 'overview'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-end-new"></i> 概述
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'setting' }"
|
|
|
|
|
@click="activeMenu = 'setting'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-setting"></i> 设置
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
|
|
|
|
|
|
|
<div class="nav-menu">
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'integration' }"
|
|
|
|
|
@click="activeMenu = 'integration'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-assembly-new"></i> 集成
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'proxy' }"
|
|
|
|
|
@click="activeMenu = 'proxy'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-cloud"></i> 云代理
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-12-10 14:34:29 +08:00
|
|
|
<!-- <div class="spacer"></div>-->
|
2025-12-09 14:31:11 +08:00
|
|
|
|
|
|
|
|
<div class="nav-menu bottom-menu">
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'usage' }"
|
|
|
|
|
@click="activeMenu = 'usage'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-chart"></i> 用法
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'expense' }"
|
|
|
|
|
@click="activeMenu = 'expense'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-time"></i> 开支
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'billing' }"
|
|
|
|
|
@click="activeMenu = 'billing'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-remove-member"></i> 账单和发票
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
|
|
|
|
|
|
|
<div class="nav-menu">
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'docs' }"
|
|
|
|
|
@click="activeMenu = 'docs'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-doc"></i> 文档
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="menu-item"
|
|
|
|
|
:class="{ active: activeMenu === 'contact' }"
|
|
|
|
|
@click="activeMenu = 'contact'"
|
|
|
|
|
>
|
|
|
|
|
<i class="icon-mail"></i> 联系我们
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</d-aside>
|
|
|
|
|
|
|
|
|
|
<!-- 动态内容区域 -->
|
|
|
|
|
<component :is="currentComponent" />
|
|
|
|
|
|
|
|
|
|
</d-layout>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { ref, computed } from 'vue';
|
2025-12-10 14:34:29 +08:00
|
|
|
import OverView from './overview/index.vue';
|
2025-12-10 16:11:05 +08:00
|
|
|
import Setting from './setting/index.vue';
|
2025-12-09 14:31:11 +08:00
|
|
|
import Integration from './Integration.vue';
|
|
|
|
|
import Proxy from './proxy.vue';
|
|
|
|
|
import Usage from './usage.vue';
|
|
|
|
|
import Expense from './expense.vue';
|
|
|
|
|
import Billing from './billing.vue';
|
2025-12-10 14:34:29 +08:00
|
|
|
import Header from './Header.vue';
|
2025-12-09 14:31:11 +08:00
|
|
|
|
|
|
|
|
// 定义菜单映射关系
|
|
|
|
|
const menuComponents = {
|
|
|
|
|
overview: OverView,
|
|
|
|
|
setting: Setting,
|
|
|
|
|
integration: Integration,
|
|
|
|
|
proxy: Proxy,
|
|
|
|
|
usage: Usage,
|
|
|
|
|
expense: Expense,
|
|
|
|
|
billing: Billing,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 选中的菜单
|
|
|
|
|
const activeMenu = ref('overview');
|
|
|
|
|
|
|
|
|
|
// 根据选中的菜单获取当前组件
|
|
|
|
|
const currentComponent = computed(() => {
|
|
|
|
|
return menuComponents[activeMenu.value] || OverView;
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
/* 全局暗黑重置 */
|
|
|
|
|
.app-container {
|
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
2025-12-10 14:34:29 +08:00
|
|
|
background-color: rgb(20, 18, 11);
|
2025-12-09 14:31:11 +08:00
|
|
|
color: #fff;
|
2025-12-10 14:34:29 +08:00
|
|
|
//min-height: 100vh;
|
|
|
|
|
height: 100%;
|
2025-12-09 14:31:11 +08:00
|
|
|
width: 100%;
|
2025-12-10 14:34:29 +08:00
|
|
|
overflow-y: auto;
|
2025-12-09 14:31:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-layout {
|
2025-12-10 14:34:29 +08:00
|
|
|
min-height: calc(100% - 56px);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
margin-right: auto;
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 1344px;
|
|
|
|
|
padding-top: 2rem;
|
|
|
|
|
padding-bottom: 2rem;
|
2025-12-09 14:31:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sidebar {
|
2025-12-10 14:34:29 +08:00
|
|
|
background-color: rgb(20, 18, 11);
|
2025-12-09 14:31:11 +08:00
|
|
|
width: 260px;
|
|
|
|
|
border-right: 1px solid #252525;
|
|
|
|
|
padding: 20px 16px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.user-profile {
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
.username {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
color: #e5e5e5;
|
|
|
|
|
}
|
|
|
|
|
.user-email {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #888;
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-menu {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.menu-item {
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #999;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
background-color: #252525;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
background-color: #252525;
|
|
|
|
|
color: #fff;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
/* 简单的 CSS 图标模拟 */
|
|
|
|
|
width: 14px;
|
|
|
|
|
height: 14px;
|
|
|
|
|
border: 1px solid currentColor;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 不同图标的特殊样式 */
|
|
|
|
|
.icon-overview {
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
background-color: currentColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-setting {
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-cube {
|
|
|
|
|
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-cloud {
|
|
|
|
|
border-radius: 50% 50% 0 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-chart {
|
|
|
|
|
position: relative;
|
|
|
|
|
&::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 2px;
|
|
|
|
|
background-color: currentColor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-time {
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
position: relative;
|
|
|
|
|
&::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 50%;
|
|
|
|
|
left: 50%;
|
|
|
|
|
width: 40%;
|
|
|
|
|
height: 2px;
|
|
|
|
|
background-color: currentColor;
|
|
|
|
|
transform-origin: left center;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-bill {
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-doc {
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
position: relative;
|
|
|
|
|
&::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 3px;
|
|
|
|
|
right: 3px;
|
|
|
|
|
width: 4px;
|
|
|
|
|
height: 4px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background-color: currentColor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-mail {
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
position: relative;
|
|
|
|
|
&::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 2px;
|
|
|
|
|
left: 2px;
|
|
|
|
|
width: 60%;
|
|
|
|
|
height: 2px;
|
|
|
|
|
background-color: currentColor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.divider {
|
|
|
|
|
height: 1px;
|
|
|
|
|
background-color: #252525;
|
|
|
|
|
margin: 16px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.spacer {
|
|
|
|
|
flex-grow: 1;
|
|
|
|
|
}
|
|
|
|
|
</style>
|