diff --git a/src/assets/nav.png b/src/assets/nav.png new file mode 100644 index 0000000..5288113 Binary files /dev/null and b/src/assets/nav.png differ diff --git a/src/assets/rognqishili.png b/src/assets/rognqishili.png new file mode 100644 index 0000000..5a71841 Binary files /dev/null and b/src/assets/rognqishili.png differ diff --git a/src/router/index.ts b/src/router/index.ts index f50f1db..610cf3e 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -233,6 +233,18 @@ const routes: RouteRecordRaw[] = [ component: () => import("@/views/admin/account/cost/myOrder/index.vue"), }, + { + path: "myMoney", + name: "myMoney", + component: () => + import("@/views/admin/account/cost/myMoney/index.vue"), + }, + { + path: "myMoneyDetail", + name: "myMoneyDetail", + component: () => + import("@/views/admin/account/cost/myMoneyDetail/index.vue"), + }, { path: "voucher", name: "voucher", @@ -293,7 +305,7 @@ const router = createRouter({ // ====== 添加全局前置守卫 ====== // router.beforeEach((to, from, next) => { // console.log("Navigating to:", to.path); -// const list = ["/layout/home", "/document/introdution", "/layout/admin/home"]; +// const list = ["/layout/home","/document/introdution","/layout/admin/home"]; // if (list.indexOf(to.path) != -1) { // next(); // return; diff --git a/src/views/admin/account/cost/myMoney/index.vue b/src/views/admin/account/cost/myMoney/index.vue new file mode 100644 index 0000000..fdfa017 --- /dev/null +++ b/src/views/admin/account/cost/myMoney/index.vue @@ -0,0 +1,681 @@ + + + + + \ No newline at end of file diff --git a/src/views/admin/home/index.vue b/src/views/admin/home/index.vue index d878dff..6931e0f 100644 --- a/src/views/admin/home/index.vue +++ b/src/views/admin/home/index.vue @@ -2,21 +2,26 @@
- + - + - +
-
容器实例
-
{{ userInfo.caseNum }}
+
进行中
+
0
-
运行中
+
即将到期
+
0
+
+ +
+
自动续费
0
@@ -24,180 +29,164 @@ - +
-
+
-
-
- 即将到期 - - - -
-
0
-
-
-
- 即将释放 - - - -
-
0
-
+ warning
- - - - - - - - - -
- 查看更多问题 -
+ + + + + +
+
+
+ +
+
+
暂无邀请链接
+
+ 通过参加邀请好友,生成邀请码使用后可得等额优惠券 +
+
+
+ +
+ + + 生成邀请链接 + + + + + + 查看活动规则 + +
+
+
+ + +
- - - -
- - 炼丹会员(23天后到期) -
-
- 认证学生升级炼丹会员 - 等级与会员福利 -
-
-
成长值
- -
距离升级还需90成长值 升级攻略
- 进入成长值主页> -
-
- - +
-
我的余额
- +
我的账号
- 可用: - ¥{{ userInfo.balace }} - | - 冻结: - ¥{{ userInfo.freezeBalace }} + + + + + + 账户设置 + +
-
- - 代金券 - 暂无 + +
资产账户
+ + +
+
+ +
+
+
我的余额
+
+ {{ formatAmount(balance) }} + 去充值 +
+
+ -- + 去充值 +
+
-
- - 优惠券 - 暂无 -
-
- - 授信 - 暂无 + + +
+
+ +
+
+
我的权益
+
+ +
+
+ 算力点 +
+
+ {{ computingPoints }} + +
+
+ + +
+ + +
+
+ 可用算力券 +
+
+ {{ availableCoupons }} + +
+
+
+ + 查看全部权益 + + +
+
- - + + @@ -205,43 +194,105 @@ \ No newline at end of file diff --git a/src/views/admin/index.vue b/src/views/admin/index.vue index c169cbe..1b16844 100644 --- a/src/views/admin/index.vue +++ b/src/views/admin/index.vue @@ -27,16 +27,16 @@ import { h, reactive, computed } from 'vue'; import { useRouter } from 'vue-router'; import { HomeOutlined, - FolderOpenOutlined, ConsoleSqlOutlined, GlobalOutlined, - LaptopOutlined, MoneyCollectOutlined, TeamOutlined, AppstoreAddOutlined } from '@ant-design/icons-vue'; import type { MenuMode, MenuTheme } from 'ant-design-vue'; -import { ItemType } from 'ant-design-vue'; + +// 移除 ItemType 的导入,直接使用 Ant Design Vue 的 MenuItem 类型 +import type { MenuProps } from 'ant-design-vue'; const router = useRouter(); @@ -45,38 +45,40 @@ interface MenuItem { path: string; name: string; icon?: any; - disabled?: boolean; // 新增字段 - children?: Omit[]; // 子项不需要 icon + disabled?: boolean; + visible?: boolean; + children?: Omit[]; } const menuItems: MenuItem[] = [ - // { path: '/layout/admin/home', name: '总览', icon: HomeOutlined }, - { path: '/layout/admin/instance', name: '容器实例', icon: ConsoleSqlOutlined }, - // { path: '/layout/admin/fileStore', name: '文件存储', icon: FolderOpenOutlined }, - { path: '/layout/admin/image', name: '镜像', icon: GlobalOutlined }, - // { path: '/layout/publicData', name: '公开数据', icon: LaptopOutlined }, + { path: '/layout/admin/home', name: '总览', icon: HomeOutlined, visible: true }, + { path: '/layout/admin/instance', name: '容器实例', icon: ConsoleSqlOutlined, visible: true }, + { path: '/layout/admin/image', name: '镜像', icon: GlobalOutlined, visible: true }, { path: '', name: '费用', icon: MoneyCollectOutlined, + visible: true, children: [ - // { path: '/layout/admin/costDetail', name: '收支明细' }, - { path: '/layout/admin/myOrder', name: '我的订单' }, - { path: '/layout/admin/flow', name: '账单明细' }, - { path: '/layout/admin/coupon', name: '优惠券(待开发)', disabled: true }, - { path: '/layout/admin/invoice', name: '发票(待开发)', disabled: true }, - { path: '/layout/admin/voucher', name: '代金券(待开发)', disabled: true }, - { path: '/layout/admin/contract', name: '合同(待开发)', disabled: true }, + { path: '/layout/admin/myMoney', name: '费用总览', visible: true, disabled: false }, + // 消费明细设置为不可见 + { path: '/layout/admin/myMoneyDetail', name: '消费明细', visible: false, disabled: false }, + { path: '/layout/admin/myOrder', name: '我的订单', visible: true, disabled: false }, + { path: '/layout/admin/flow', name: '账单明细', visible: true, disabled: false }, + { path: '/layout/admin/coupon', name: '优惠券(待开发)', disabled: true, visible: true }, + { path: '/layout/admin/invoice', name: '发票(待开发)', disabled: true, visible: true }, + { path: '/layout/admin/voucher', name: '代金券(待开发)', disabled: true, visible: true }, + { path: '/layout/admin/contract', name: '合同(待开发)', disabled: true, visible: true }, ], }, { path: '', name: '账号', icon: TeamOutlined, + visible: true, children: [ - { path: '/layout/admin/security', name: '账号安全' }, - { path: '/layout/admin/history', name: '访问记录' }, - // { path: '/controlPanel/security', name: '安全设置' }, + { path: '/layout/admin/security', name: '账号安全', visible: true }, + { path: '/layout/admin/history', name: '访问记录', visible: true }, ], }, ]; @@ -89,60 +91,111 @@ const state = reactive({ openKeys: ['/controlPanel/fee', '/controlPanel/account'], }); +// 方法一:直接使用 MenuProps['items'] 类型 +// 或者自己定义 MenuItemType 类型 +type MenuItemType = NonNullable[number]; + // 工具函数:生成菜单项 function getItem( label: string, key: string, icon?: any, - children?: ItemType[], + children?: MenuItemType[], type?: 'group', - disabled?: boolean // 新增 disabled 参数 -): ItemType { + disabled?: boolean +): MenuItemType | null { return { key, icon, children, label, type, - disabled, // 应用 disabled - } as ItemType; + disabled, + } as MenuItemType; } // 将 menuItems 转为 a-menu 所需的 items const items = computed(() => { - return menuItems.map((item) => { - if (item.children && item.children.length > 0) { - const childItems = item.children.map((child) => - getItem(child.name, child.path, undefined, undefined, undefined, child.disabled) - ); - return getItem(item.name, item.path, h(item.icon), childItems, undefined, item.disabled); - } else { - return getItem(item.name, item.path, h(item.icon), undefined, undefined, item.disabled); - } - }); + return menuItems + .filter(item => item.visible !== false) + .map((item) => { + if (item.children && item.children.length > 0) { + // 过滤掉 visible 为 false 的子项 + const childItems = item.children + .filter(child => child.visible !== false) + .map((child) => + getItem( + child.name, + child.path, + undefined, + undefined, + undefined, + child.disabled + ) + ) + .filter(Boolean) as MenuItemType[]; + + // 如果子项全部被过滤掉了,则显示父项但不显示子菜单 + if (childItems.length === 0) { + return getItem( + item.name, + item.path, + h(item.icon), + undefined, // 没有子项 + undefined, + item.disabled + ); + } + + return getItem( + item.name, + item.path, + h(item.icon), + childItems, + undefined, + item.disabled + ); + } else { + return getItem( + item.name, + item.path, + h(item.icon), + undefined, + undefined, + item.disabled + ); + } + }) + .filter(Boolean) as MenuItemType[]; }); const handleMenuSelect = ({ key }: { key: string }) => { - // 防止跳转到被禁用的菜单(虽然 a-menu 不会触发 select,但加个判断更安全) - const targetItem = findMenuItemByKey(menuItems, key); - if (targetItem?.disabled) { + // 递归查找菜单项(需要包含所有项,包括隐藏的) + const allItems = flattenMenuItems(menuItems); + const targetItem = allItems.find(item => item.path === key); + + // 检查是否禁用或不可见 + if (targetItem?.disabled || targetItem?.visible === false) { return; } router.push(key); }; -// 辅助函数:递归查找菜单项 -function findMenuItemByKey(items: MenuItem[], key: string): MenuItem | undefined { - for (const item of items) { - if (item.path === key) return item; +// 辅助函数:扁平化所有菜单项 +function flattenMenuItems(items: MenuItem[]): MenuItem[] { + let result: MenuItem[] = []; + + items.forEach(item => { + result.push(item); if (item.children) { - const found = findMenuItemByKey(item.children, key); - if (found) return found; + result = result.concat(flattenMenuItems(item.children)); } - } - return undefined; + }); + + return result; } +// 其他代码保持不变 const changeMode = (checked: boolean) => { state.mode = checked ? 'vertical' : 'inline'; };