diff --git a/layouts/admin/aside.uvue b/layouts/admin/aside.uvue
deleted file mode 100644
index 4435c9d4..00000000
--- a/layouts/admin/aside.uvue
+++ /dev/null
@@ -1,598 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/admin/breadcrumb.uvue b/layouts/admin/breadcrumb.uvue
deleted file mode 100644
index 2c8894fb..00000000
--- a/layouts/admin/breadcrumb.uvue
+++ /dev/null
@@ -1,281 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- 首页
- /
- {{ currentPageTitle }}
-
-
-
-
-
-
-
-
- {{ notificationCount }}
-
-
-
-
-
- {{ userInfo.nickname ? userInfo.nickname.charAt(0) : 'A' }}
-
-
- {{ userInfo.nickname || '管理员' }}
- {{ userInfo.role || 'admin' }}
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/admin/components/AdminAside.uvue b/layouts/admin/components/AdminAside.uvue
new file mode 100644
index 00000000..740504e2
--- /dev/null
+++ b/layouts/admin/components/AdminAside.uvue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layouts/admin/components/AdminFooter.uvue b/layouts/admin/components/AdminFooter.uvue
new file mode 100644
index 00000000..d192f674
--- /dev/null
+++ b/layouts/admin/components/AdminFooter.uvue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/layouts/admin/components/AdminHeader.uvue b/layouts/admin/components/AdminHeader.uvue
new file mode 100644
index 00000000..1d81a9de
--- /dev/null
+++ b/layouts/admin/components/AdminHeader.uvue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
diff --git a/layouts/admin/components/AdminSubsider.uvue b/layouts/admin/components/AdminSubsider.uvue
new file mode 100644
index 00000000..aba51ef8
--- /dev/null
+++ b/layouts/admin/components/AdminSubsider.uvue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+ {{ g.title }}
+ {{ isGroupOpen(g.title) ? '˄' : '˅' }}
+
+
+
+
+
+ {{ c.title }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layouts/admin/components/AdminTagsView.uvue b/layouts/admin/components/AdminTagsView.uvue
new file mode 100644
index 00000000..fa1ed21b
--- /dev/null
+++ b/layouts/admin/components/AdminTagsView.uvue
@@ -0,0 +1,76 @@
+
+
+
+
+
+ {{ t.title }}
+
+ ×
+
+
+
+
+
+
+
+
+
+
diff --git a/layouts/admin/defaults.uvue b/layouts/admin/defaults.uvue
deleted file mode 100644
index 8630cf29..00000000
--- a/layouts/admin/defaults.uvue
+++ /dev/null
@@ -1,453 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/admin/header.uvue b/layouts/admin/header.uvue
deleted file mode 100644
index b35af90e..00000000
--- a/layouts/admin/header.uvue
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/admin/index-simple.uvue b/layouts/admin/index-simple.uvue
deleted file mode 100644
index 26652946..00000000
--- a/layouts/admin/index-simple.uvue
+++ /dev/null
@@ -1,351 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/admin/index.uvue b/layouts/admin/index.uvue
index aafa6957..801ecf83 100644
--- a/layouts/admin/index.uvue
+++ b/layouts/admin/index.uvue
@@ -1,641 +1,190 @@
-
+
-
-
-
+
-
-
diff --git a/layouts/admin/tags-view.uvue b/layouts/admin/tags-view.uvue
deleted file mode 100644
index 91880f85..00000000
--- a/layouts/admin/tags-view.uvue
+++ /dev/null
@@ -1,250 +0,0 @@
-
-
-
-
-
-
- {{ tag.title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/admin/types.uts b/layouts/admin/types.uts
index 826d1cf7..46883180 100644
--- a/layouts/admin/types.uts
+++ b/layouts/admin/types.uts
@@ -1,13 +1,5 @@
// 统一类型定义文件,避免重复定义冲突
-export type MenuItem = {
- id: string
- title: string
- icon: string
- path?: string
- children?: MenuItem[]
-}
-
export type UserInfo = {
nickname: string
role: string
@@ -17,4 +9,29 @@ export type TagItem = {
path: string
title: string
isAffix?: boolean
-}
\ No newline at end of file
+}
+
+export type MenuChild = {
+ id: string
+ title: string
+ path: string
+}
+
+export type MenuGroup = {
+ title: string
+ children: MenuChild[]
+}
+
+export type MenuItem = {
+ id: string
+ title: string
+ icon: string // 你的 svg 路径
+ path?: string
+ groups?: MenuGroup[]
+}
+
+export type TabItem = {
+ id: string
+ title: string
+ path: string
+}
diff --git a/layouts/admin/utils/menu.uts b/layouts/admin/utils/menu.uts
new file mode 100644
index 00000000..5e93064b
--- /dev/null
+++ b/layouts/admin/utils/menu.uts
@@ -0,0 +1,101 @@
+import type { MenuItem } from '../types.uts'
+
+export const menuList: MenuItem[] = [
+ {
+ id: 'home',
+ title: '首页',
+ icon: '/static/homepage.svg',
+ path: '/pages/mall/admin/homePage/index',
+ groups: []
+ },
+ {
+ id: 'user',
+ title: '用户',
+ icon: '/static/user.svg',
+ path: '/pages/mall/admin/user-management',
+ groups: [
+ {
+ title: '用户管理',
+ children: [
+ { id: 'user-list', title: '用户列表', path: '/pages/mall/admin/user-management' },
+ { id: 'user-add', title: '添加用户', path: '/pages/mall/admin/user-management?action=add' },
+ { id: 'user-statistics', title: '用户统计 ', path: '/pages/mall/admin/user-statistics' },
+ ]
+ }
+ ]
+ },
+ {
+ id: 'order',
+ title: '订单',
+ icon: '/static/order.svg',
+ path: '/pages/mall/admin/order-management',
+ groups: [
+ {
+ title: '订单管理',
+ children: [
+ { id: 'order-list', title: '订单列表', path: '/pages/mall/admin/order-management' }
+ ]
+ }
+ ]
+ },
+ {
+ id: 'product',
+ title: '商品',
+ icon: '/static/shopping.svg',
+ path: '/pages/mall/admin/product-management',
+ groups: [
+ {
+ title: '商品管理',
+ children: [
+ { id: 'product-list', title: '商品列表', path: '/pages/mall/admin/product-management' },
+ { id: 'product-add', title: '添加商品', path: '/pages/mall/admin/product-management?action=add' }
+ ]
+ }
+ ]
+ },
+ {
+ id: 'marketing',
+ title: '营销',
+ icon: '/static/finance.svg',
+ path: '/pages/mall/admin/marketing-management',
+ groups: [
+ {
+ title: '优惠券活动',
+ children: [
+ { id: 'coupon-list', title: '优惠券列表', path: '/pages/mall/admin/marketing/coupon/list' }
+ { id: 'coupon-receive', title: '领取情况', path: '/pages/mall/admin/marketing/coupon/receive' }
+
+ ]
+ },
+ {
+ title: '积分',
+ children: [
+ { id: 'points', title: '积分管理', path: '/pages/mall/admin/marketing/points/index' }
+ ]
+ },
+ {
+ title: '签到',
+ children: [
+ { id: 'rule', title: '签到规则', path: '/pages/mall/admin/marketing/signin/rule' }
+ { id: 'record', title: '记录', path: '/pages/mall/admin/marketing/signin/record' }
+
+ ]
+ }
+ ]
+ },
+ {
+ id: 'system',
+ title: '设置',
+ icon: '/static/setting.svg',
+ path: '/pages/mall/admin/system-settings',
+ groups: [
+ {
+ title: '系统设置',
+ children: [
+ { id: 'basic', title: '基本设置', path: '/pages/mall/admin/system-settings' },
+ { id: 'security', title: '安全设置', path: '/pages/mall/admin/system-settings?tab=security' }
+ ]
+ }
+ ]
+ }
+]
diff --git a/layouts/admin/utils/nav.uts b/layouts/admin/utils/nav.uts
new file mode 100644
index 00000000..715efdfc
--- /dev/null
+++ b/layouts/admin/utils/nav.uts
@@ -0,0 +1,34 @@
+import type { MenuItem } from '../types.uts'
+
+export function findActiveByCurrentPage(menuList: MenuItem[], currentPage: string) {
+ // currentPage 既可能是顶级菜单 id,也可能是子页面 id(如 user-list)
+ // 返回:activeMenuId / activeSubId / activeGroupTitle
+ for (const m of menuList) {
+ if (m.id === currentPage) {
+ return { activeMenuId: m.id, activeSubId: '', activeGroupTitle: '' }
+ }
+ const groups = m.groups || []
+ for (const g of groups) {
+ for (const c of g.children) {
+ if (c.id === currentPage) {
+ return { activeMenuId: m.id, activeSubId: c.id, activeGroupTitle: g.title }
+ }
+ }
+ }
+ }
+ return { activeMenuId: menuList[0]?.id || 'home', activeSubId: '', activeGroupTitle: '' }
+}
+
+export function getCurrentRoutePath(): string {
+ // 使用页面栈获取当前路由(uni-app标准能力)
+ // getCurrentPages 用于获取当前页面栈实例 :contentReference[oaicite:2]{index=2}
+ const pages = getCurrentPages()
+ const last: any = pages[pages.length - 1]
+ // #ifdef H5
+ return last?.route ? `/${last.route}` : ''
+ // #endif
+ // #ifndef H5
+ // 小程序/App 可能是 route / $page?.fullPath 形式,按你项目实际字段微调
+ return last?.route ? `/${last.route}` : (last?.$page?.fullPath || '')
+ // #endif
+}
diff --git a/layouts/admin/utils/tabs.uts b/layouts/admin/utils/tabs.uts
new file mode 100644
index 00000000..1a2a6762
--- /dev/null
+++ b/layouts/admin/utils/tabs.uts
@@ -0,0 +1,33 @@
+import type { TabItem, MenuItem } from '../types.uts'
+
+export function makeTabFromPath(menuList: MenuItem[], path: string): TabItem {
+ // path 可能带 query;用于 tab 的 id 也要稳定
+ const pure = path.split('?')[0]
+
+ // 先找子页面
+ for (const m of menuList) {
+ const groups = m.groups || []
+ for (const g of groups) {
+ for (const c of g.children) {
+ if (c.path.split('?')[0] === pure) {
+ return { id: c.id, title: c.title, path: c.path }
+ }
+ }
+ }
+ if (m.path.split('?')[0] === pure) {
+ return { id: m.id, title: m.title, path: m.path }
+ }
+ }
+ // 找不到就兜底
+ return { id: pure, title: '页面', path }
+}
+
+export function upsertTab(tabs: TabItem[], tab: TabItem): TabItem[] {
+ const idx = tabs.findIndex(t => t.id === tab.id)
+ if (idx >= 0) return tabs
+ return [...tabs, tab]
+}
+
+export function removeTab(tabs: TabItem[], tabId: string): TabItem[] {
+ return tabs.filter(t => t.id !== tabId)
+}
diff --git a/pages.json b/pages.json
index 87a87bce..2b186914 100644
--- a/pages.json
+++ b/pages.json
@@ -1,7 +1,7 @@
{
"pages": [
{
- "path": "pages/mall/admin/index",
+ "path": "pages/mall/admin/homePage/index",
"style": {
"navigationBarTitleText": "管理后台",
"navigationStyle": "custom"
@@ -57,4 +57,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/pages/mall/admin/homePage/components/KpiMiniCard.uvue b/pages/mall/admin/homePage/components/KpiMiniCard.uvue
new file mode 100644
index 00000000..89b9aee9
--- /dev/null
+++ b/pages/mall/admin/homePage/components/KpiMiniCard.uvue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+ {{ valuePrefix }}{{ valueText }}
+
+
+
+ {{ metaLeft }}
+
+
+ {{ metaRight }}
+
+
+ {{ trendArrow }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/index.uvue b/pages/mall/admin/homePage/index.uvue
similarity index 58%
rename from pages/mall/admin/index.uvue
rename to pages/mall/admin/homePage/index.uvue
index 340db481..98a2280e 100644
--- a/pages/mall/admin/index.uvue
+++ b/pages/mall/admin/homePage/index.uvue
@@ -3,116 +3,58 @@
-
-
-
-
-
- ¥{{ formatNumber(kpiData.sales.today) }}
-
-
- {{ Math.abs(kpiData.sales.change) }}%
-
-
-
-
-
-
-
-
+
-
-
-
-
-
- {{ formatNumber(kpiData.visits.today) }}
-
-
- {{ Math.abs(kpiData.visits.change) }}%
-
-
-
-
-
-
-
-
+
-
-
-
-
-
- {{ formatNumber(kpiData.orders.today) }}
-
-
- {{ Math.abs(kpiData.orders.change) }}%
-
-
-
-
-
-
-
-
+
-
-
-
-
-
- {{ formatNumber(kpiData.users.today) }}
-
-
- {{ Math.abs(kpiData.users.change) }}%
-
-
-
-
-
-
-
-
+
+