This commit is contained in:
qiuyuan 2025-12-30 14:00:43 +08:00
parent bf8c5e1cc1
commit 98ccb19fbe
3 changed files with 113 additions and 53 deletions

View File

@ -201,6 +201,12 @@ const routes: RouteRecordRaw[] = [
component: () => component: () =>
import("@/views/admin/account/cost/myMoney/index.vue"), import("@/views/admin/account/cost/myMoney/index.vue"),
}, },
{
path: "myMoneyDetail",
name: "myMoneyDetail",
component: () =>
import("@/views/admin/account/cost/myMoneyDetail/index.vue"),
},
{ {
path: "voucher", path: "voucher",
name: "voucher", name: "voucher",

View File

@ -71,6 +71,8 @@
@change="handleTableChange" @change="handleTableChange"
:loading="loading" :loading="loading"
class="bill-table" class="bill-table"
:scroll="{ x: 1200 }"
> >
<!-- 流水号列 --> <!-- 流水号列 -->
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">

View File

@ -22,15 +22,15 @@ import { h, reactive, computed } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { import {
HomeOutlined, HomeOutlined,
FolderOpenOutlined,
ConsoleSqlOutlined, ConsoleSqlOutlined,
GlobalOutlined, GlobalOutlined,
LaptopOutlined,
MoneyCollectOutlined, MoneyCollectOutlined,
TeamOutlined, TeamOutlined,
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import type { MenuMode, MenuTheme } from 'ant-design-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(); const router = useRouter();
@ -39,39 +39,40 @@ interface MenuItem {
path: string; path: string;
name: string; name: string;
icon?: any; icon?: any;
disabled?: boolean; // disabled?: boolean;
children?: Omit<MenuItem, 'icon'>[]; // icon visible?: boolean;
children?: Omit<MenuItem, 'icon'>[];
} }
const menuItems: MenuItem[] = [ const menuItems: MenuItem[] = [
{ path: '/layout/admin/home', name: '总览', icon: HomeOutlined }, { path: '/layout/admin/home', name: '总览', icon: HomeOutlined, visible: true },
{ path: '/layout/admin/instance', name: '容器实例', icon: ConsoleSqlOutlined }, { path: '/layout/admin/instance', name: '容器实例', icon: ConsoleSqlOutlined, visible: true },
// { path: '/layout/admin/fileStore', name: '', icon: FolderOpenOutlined }, { path: '/layout/admin/image', name: '镜像', icon: GlobalOutlined, visible: true },
{ path: '/layout/admin/image', name: '镜像', icon: GlobalOutlined },
// { path: '/layout/publicData', name: '', icon: LaptopOutlined },
{ {
path: '', path: '',
name: '费用', name: '费用',
icon: MoneyCollectOutlined, icon: MoneyCollectOutlined,
visible: true,
children: [ children: [
// { path: '/layout/admin/costDetail', name: '' }, { path: '/layout/admin/myMoney', name: '费用总览', visible: true, disabled: false },
{ path: '/layout/admin/myMoney', name: '费用总览' }, //
{ path: '/layout/admin/myOrder', name: '我的订单' }, { path: '/layout/admin/myMoneyDetail', name: '消费明细', visible: false, disabled: false },
{ path: '/layout/admin/flow', name: '账单明细' }, { path: '/layout/admin/myOrder', name: '我的订单', visible: true, disabled: false },
{ path: '/layout/admin/coupon', name: '优惠券(待开发)', disabled: true }, { path: '/layout/admin/flow', name: '账单明细', visible: true, disabled: false },
{ path: '/layout/admin/invoice', name: '发票(待开发)', disabled: true }, { path: '/layout/admin/coupon', name: '优惠券(待开发)', disabled: true, visible: true },
{ path: '/layout/admin/voucher', name: '代金券(待开发)', disabled: true }, { path: '/layout/admin/invoice', name: '发票(待开发)', disabled: true, visible: true },
{ path: '/layout/admin/contract', name: '合同(待开发)', disabled: true }, { path: '/layout/admin/voucher', name: '代金券(待开发)', disabled: true, visible: true },
{ path: '/layout/admin/contract', name: '合同(待开发)', disabled: true, visible: true },
], ],
}, },
{ {
path: '', path: '',
name: '账号', name: '账号',
icon: TeamOutlined, icon: TeamOutlined,
visible: true,
children: [ children: [
{ path: '/layout/admin/security', name: '账号安全' }, { path: '/layout/admin/security', name: '账号安全', visible: true },
{ path: '/layout/admin/history', name: '访问记录' }, { path: '/layout/admin/history', name: '访问记录', visible: true },
// { path: '/controlPanel/security', name: '' },
], ],
}, },
]; ];
@ -84,60 +85,111 @@ const state = reactive({
openKeys: ['/controlPanel/fee', '/controlPanel/account'], openKeys: ['/controlPanel/fee', '/controlPanel/account'],
}); });
// 使 MenuProps['items']
// MenuItemType
type MenuItemType = NonNullable<MenuProps['items']>[number];
// //
function getItem( function getItem(
label: string, label: string,
key: string, key: string,
icon?: any, icon?: any,
children?: ItemType[], children?: MenuItemType[],
type?: 'group', type?: 'group',
disabled?: boolean // disabled disabled?: boolean
): ItemType { ): MenuItemType | null {
return { return {
key, key,
icon, icon,
children, children,
label, label,
type, type,
disabled, // disabled disabled,
} as ItemType; } as MenuItemType;
} }
// menuItems a-menu items // menuItems a-menu items
const items = computed(() => { const items = computed(() => {
return menuItems.map((item) => { return menuItems
.filter(item => item.visible !== false)
.map((item) => {
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
const childItems = item.children.map((child) => // visible false
getItem(child.name, child.path, undefined, undefined, undefined, child.disabled) 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);
} }
});
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 }) => { const handleMenuSelect = ({ key }: { key: string }) => {
// a-menu select //
const targetItem = findMenuItemByKey(menuItems, key); const allItems = flattenMenuItems(menuItems);
if (targetItem?.disabled) { const targetItem = allItems.find(item => item.path === key);
//
if (targetItem?.disabled || targetItem?.visible === false) {
return; return;
} }
router.push(key); router.push(key);
}; };
// //
function findMenuItemByKey(items: MenuItem[], key: string): MenuItem | undefined { function flattenMenuItems(items: MenuItem[]): MenuItem[] {
for (const item of items) { let result: MenuItem[] = [];
if (item.path === key) return item;
items.forEach(item => {
result.push(item);
if (item.children) { if (item.children) {
const found = findMenuItemByKey(item.children, key); result = result.concat(flattenMenuItems(item.children));
if (found) return found;
} }
} });
return undefined;
return result;
} }
//
const changeMode = (checked: boolean) => { const changeMode = (checked: boolean) => {
state.mode = checked ? 'vertical' : 'inline'; state.mode = checked ? 'vertical' : 'inline';
}; };