befly-admin 3.4.5 → 3.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +2 -0
- package/bunfig.toml +1 -8
- package/index.html +2 -2
- package/package.json +12 -8
- package/src/config/index.ts +20 -0
- package/src/layouts/{internal/0.vue → default.vue} +51 -21
- package/src/main.ts +3 -5
- package/src/plugins/global.ts +17 -0
- package/src/plugins/{internal/http.ts → http.ts} +1 -1
- package/src/router/index.ts +55 -0
- package/src/styles/{internal/index.scss → global.scss} +29 -29
- package/src/types/auto-imports.d.ts +176 -637
- package/src/types/components.d.ts +28 -19
- package/src/types/typed-router.d.ts +32 -0
- package/src/utils/index.ts +21 -9
- package/src/views/index.vue +27 -0
- package/src/views/internal/login.vue +73 -0
- package/src/views/test.vue +60 -0
- package/tsconfig.json +4 -4
- package/vite.config.ts +134 -60
- package/src/components/internal/Icon.vue +0 -41
- package/src/components/internal/README.md +0 -27
- package/src/layouts/4.vue +0 -17
- package/src/layouts/internal/1.vue +0 -22
- package/src/layouts/internal/2.vue +0 -169
- package/src/layouts/internal/README.md +0 -27
- package/src/plugins/internal/README.md +0 -36
- package/src/plugins/internal/router.ts +0 -48
- package/src/plugins/internal/store.ts +0 -19
- package/src/styles/internal/README.md +0 -27
- package/src/styles/internal/mixins.scss +0 -98
- package/src/types/env.d.ts +0 -23
- package/src/utils/README.md +0 -37
- package/src/utils/internal/README.md +0 -21
- package/src/utils/internal/index.ts +0 -30
- package/src/views/internal/403/403.vue +0 -66
- package/src/views/internal/README.md +0 -27
- package/src/views/internal/admin/components/edit.vue +0 -147
- package/src/views/internal/admin/components/role.vue +0 -135
- package/src/views/internal/admin/index.vue +0 -169
- package/src/views/internal/dict/components/edit.vue +0 -156
- package/src/views/internal/dict/index.vue +0 -159
- package/src/views/internal/index/components/addonList.vue +0 -125
- package/src/views/internal/index/components/environmentInfo.vue +0 -97
- package/src/views/internal/index/components/operationLogs.vue +0 -112
- package/src/views/internal/index/components/performanceMetrics.vue +0 -148
- package/src/views/internal/index/components/quickActions.vue +0 -27
- package/src/views/internal/index/components/serviceStatus.vue +0 -193
- package/src/views/internal/index/components/systemNotifications.vue +0 -136
- package/src/views/internal/index/components/systemOverview.vue +0 -188
- package/src/views/internal/index/components/systemResources.vue +0 -104
- package/src/views/internal/index/components/userInfo.vue +0 -202
- package/src/views/internal/index/index.vue +0 -62
- package/src/views/internal/login/components/emailLoginForm.vue +0 -163
- package/src/views/internal/login/components/registerForm.vue +0 -168
- package/src/views/internal/login/components/welcomePanel.vue +0 -61
- package/src/views/internal/login/index_1.vue +0 -189
- package/src/views/internal/menu/components/edit.vue +0 -150
- package/src/views/internal/menu/index.vue +0 -168
- package/src/views/internal/news/detail/detail_2.vue +0 -26
- package/src/views/internal/news/detail/index.vue +0 -26
- package/src/views/internal/news/news.vue +0 -26
- package/src/views/internal/role/components/api.vue +0 -280
- package/src/views/internal/role/components/edit.vue +0 -129
- package/src/views/internal/role/components/menu.vue +0 -143
- package/src/views/internal/role/index.vue +0 -179
- package/src/views/internal/user/user.vue +0 -320
- /package/src/plugins/{internal/storage.ts → storage.ts} +0 -0
- /package/src/styles/{internal/variables.scss → variables.scss} +0 -0
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="layout-container">
|
|
3
|
-
<RouterView />
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup>
|
|
8
|
-
const router = useRouter();
|
|
9
|
-
const route = useRoute();
|
|
10
|
-
|
|
11
|
-
// 响应式数据
|
|
12
|
-
const $Data = $ref({
|
|
13
|
-
collapsed: $Storage.local.get('sidebar-collapsed') === 'true',
|
|
14
|
-
expandedKeys: [],
|
|
15
|
-
menuItems: []
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// 方法
|
|
19
|
-
const $Method = {
|
|
20
|
-
// 切换折叠状态
|
|
21
|
-
toggleCollapse() {
|
|
22
|
-
$Data.collapsed = !$Data.collapsed;
|
|
23
|
-
$Storage.local.set('sidebar-collapsed', String($Data.collapsed));
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// 当前激活菜单
|
|
28
|
-
const activeMenu = computed(() => route.name);
|
|
29
|
-
const currentTitle = computed(() => route.meta.title || '');
|
|
30
|
-
|
|
31
|
-
// 图标映射(根据路由名称首段匹配)
|
|
32
|
-
const iconMap = {
|
|
33
|
-
index: DashboardIcon,
|
|
34
|
-
user: UserIcon,
|
|
35
|
-
news: FileIcon,
|
|
36
|
-
system: SettingIcon,
|
|
37
|
-
default: AppIcon
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// 从路由构建菜单结构
|
|
41
|
-
function buildMenuFromRoutes() {
|
|
42
|
-
const routes = router.getRoutes();
|
|
43
|
-
// 过滤掉布局路由和登录页
|
|
44
|
-
const pageRoutes = routes.filter((r) => r.name && r.name !== 'layout0' && r.name !== 'login' && !String(r.name).startsWith('layout'));
|
|
45
|
-
const menuTree = {};
|
|
46
|
-
for (const r of pageRoutes) {
|
|
47
|
-
const name = String(r.name);
|
|
48
|
-
const segments = name.split('-');
|
|
49
|
-
const firstSeg = segments[0];
|
|
50
|
-
// 一级菜单
|
|
51
|
-
if (!menuTree[firstSeg]) {
|
|
52
|
-
menuTree[firstSeg] = {
|
|
53
|
-
value: segments.length === 1 ? name : firstSeg,
|
|
54
|
-
label: firstSeg.charAt(0).toUpperCase() + firstSeg.slice(1),
|
|
55
|
-
icon: iconMap[firstSeg] || iconMap.default,
|
|
56
|
-
children: []
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
// 多级路由加入子菜单
|
|
60
|
-
if (segments.length > 1) {
|
|
61
|
-
menuTree[firstSeg].children.push({
|
|
62
|
-
value: name,
|
|
63
|
-
label: segments.slice(1).join(' / ')
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
$Data.menuItems = Object.values(menuTree).sort((a, b) => {
|
|
68
|
-
if (a.value === 'index') return -1;
|
|
69
|
-
if (b.value === 'index') return 1;
|
|
70
|
-
return a.label.localeCompare(b.label);
|
|
71
|
-
});
|
|
72
|
-
// 默认展开所有包含子菜单的项
|
|
73
|
-
$Data.expandedKeys = $Data.menuItems.filter((m) => m.children && m.children.length).map((m) => m.value);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// 组件挂载时构建菜单
|
|
77
|
-
onMounted(() => {
|
|
78
|
-
buildMenuFromRoutes();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const userMenuOptions = [
|
|
82
|
-
{ content: '个人中心', value: 'profile' },
|
|
83
|
-
{ content: '退出登录', value: 'logout' }
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
const handleMenuChange = (value) => {
|
|
87
|
-
router.push({ name: value });
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const handleUserMenu = (data) => {
|
|
91
|
-
if (data.value === 'logout') {
|
|
92
|
-
$Storage.local.remove('token');
|
|
93
|
-
router.push('/login');
|
|
94
|
-
Modal.message({
|
|
95
|
-
message: '退出成功',
|
|
96
|
-
status: 'success'
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
</script>
|
|
101
|
-
|
|
102
|
-
<style scoped lang="scss">
|
|
103
|
-
.layout-container {
|
|
104
|
-
height: 100vh;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.sidebar {
|
|
108
|
-
transition: width 0.3s ease;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.logo {
|
|
112
|
-
height: 64px;
|
|
113
|
-
display: flex;
|
|
114
|
-
align-items: center;
|
|
115
|
-
justify-content: center;
|
|
116
|
-
border-bottom: 1px solid $border-color;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.logo h2 {
|
|
120
|
-
margin: 0;
|
|
121
|
-
font-size: 20px;
|
|
122
|
-
font-weight: 600;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.logo-short {
|
|
126
|
-
font-size: 24px;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.header {
|
|
130
|
-
display: flex;
|
|
131
|
-
align-items: center;
|
|
132
|
-
justify-content: space-between;
|
|
133
|
-
padding: 0 24px;
|
|
134
|
-
background: $bg-color-container;
|
|
135
|
-
border-bottom: 1px solid $border-color;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.header-left {
|
|
139
|
-
display: flex;
|
|
140
|
-
align-items: center;
|
|
141
|
-
gap: 16px;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.header-left h3 {
|
|
145
|
-
margin: 0;
|
|
146
|
-
font-size: 18px;
|
|
147
|
-
font-weight: 500;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.collapse-btn {
|
|
151
|
-
font-size: 20px;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.header-right {
|
|
155
|
-
display: flex;
|
|
156
|
-
align-items: center;
|
|
157
|
-
gap: 16px;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.ml-2 {
|
|
161
|
-
margin-left: 8px;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.content {
|
|
165
|
-
padding: 24px;
|
|
166
|
-
background: $bg-color-page;
|
|
167
|
-
overflow-y: auto;
|
|
168
|
-
}
|
|
169
|
-
</style>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Internal 目录说明
|
|
2
|
-
|
|
3
|
-
⚠️ **重要提示**
|
|
4
|
-
|
|
5
|
-
此目录下的所有文件由 **befly-admin** 框架管理,请勿修改!
|
|
6
|
-
|
|
7
|
-
## 自动更新
|
|
8
|
-
|
|
9
|
-
运行以下命令会自动更新此目录:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
befly sync:admin
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## 注意事项
|
|
16
|
-
|
|
17
|
-
1. ❌ **请勿修改** internal 目录下的任何文件
|
|
18
|
-
2. ❌ **请勿删除** internal 目录
|
|
19
|
-
3. ✅ 如需自定义布局,请在 internal 目录外创建文件
|
|
20
|
-
|
|
21
|
-
## 文件用途
|
|
22
|
-
|
|
23
|
-
此目录包含框架核心布局文件,确保管理系统的页面结构正常运行。
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
📚 更多信息请查看项目文档
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Internal 目录说明
|
|
2
|
-
|
|
3
|
-
⚠️ **重要提示**
|
|
4
|
-
|
|
5
|
-
此目录下的所有文件由 **befly-admin** 框架管理,请勿修改!
|
|
6
|
-
|
|
7
|
-
## 自动更新
|
|
8
|
-
|
|
9
|
-
运行以下命令会自动更新此目录:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
befly sync:admin
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## 注意事项
|
|
16
|
-
|
|
17
|
-
1. ❌ **请勿修改** internal 目录下的任何文件
|
|
18
|
-
2. ❌ **请勿删除** internal 目录
|
|
19
|
-
3. ✅ 如需自定义插件,请在 internal 目录外创建文件,并使用不同的导出名称
|
|
20
|
-
|
|
21
|
-
## 保留的导出名称
|
|
22
|
-
|
|
23
|
-
框架保留以下导出名称,请勿在自定义插件中使用:
|
|
24
|
-
|
|
25
|
-
- `$Http` - HTTP 请求封装
|
|
26
|
-
- `$Storage` - 本地存储封装
|
|
27
|
-
- `router` - Vue Router 实例
|
|
28
|
-
- `useAppStore` - 应用状态管理
|
|
29
|
-
|
|
30
|
-
## 文件用途
|
|
31
|
-
|
|
32
|
-
此目录包含框架核心插件,确保管理系统的基础功能正常运行。
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
📚 更多信息请查看项目文档
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { createRouter, createWebHashHistory } from 'vue-router';
|
|
2
|
-
import autoRoutes from 'virtual:befly-auto-routes';
|
|
3
|
-
import { $Storage } from './storage';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 创建并导出路由实例
|
|
7
|
-
* 可直接在 main.ts 中使用 app.use(router)
|
|
8
|
-
*/
|
|
9
|
-
export const router = createRouter({
|
|
10
|
-
history: createWebHashHistory(import.meta.env.BASE_URL),
|
|
11
|
-
routes: autoRoutes
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
// 路由守卫 - 基础验证
|
|
15
|
-
router.beforeEach(async (to, from, next) => {
|
|
16
|
-
// 设置页面标题
|
|
17
|
-
const titlePrefix = 'Befly Admin';
|
|
18
|
-
if (to.meta?.title) {
|
|
19
|
-
document.title = `${titlePrefix} - ${to.meta.title}`;
|
|
20
|
-
} else {
|
|
21
|
-
document.title = titlePrefix;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const token = $Storage.local.get('token');
|
|
25
|
-
|
|
26
|
-
// 判断是否为公开路由:使用 layout0 的需要登录,其他 layout 为公开路由
|
|
27
|
-
const isProtectedRoute = to.matched.some((record) => record.name === 'layout0');
|
|
28
|
-
|
|
29
|
-
// 1. 未登录且访问受保护路由 → 跳转登录
|
|
30
|
-
if (!token && isProtectedRoute) {
|
|
31
|
-
return next('/login');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 2. 已登录访问登录页 → 跳转首页
|
|
35
|
-
if (token && to.path === '/login') {
|
|
36
|
-
return next('/');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
next();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// 路由就绪后处理
|
|
43
|
-
router.afterEach((to) => {
|
|
44
|
-
// 可以在这里添加页面访问统计等
|
|
45
|
-
if (import.meta.env.DEV) {
|
|
46
|
-
console.log(`[Router] 导航到: ${to.path}`);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { defineStore } from 'pinia';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 全局状态管理
|
|
5
|
-
* 集中管理所有全局数据,避免分散到多个 store 文件
|
|
6
|
-
*/
|
|
7
|
-
export const useGlobal = defineStore('global', () => {
|
|
8
|
-
// ==================== 全局状态 ====================
|
|
9
|
-
|
|
10
|
-
// 可以在这里添加全局状态,例如:
|
|
11
|
-
// - 用户信息
|
|
12
|
-
// - 主题配置
|
|
13
|
-
// - 应用设置
|
|
14
|
-
// - 等等
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
// 暂时没有状态和方法
|
|
18
|
-
};
|
|
19
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Internal 目录说明
|
|
2
|
-
|
|
3
|
-
⚠️ **重要提示**
|
|
4
|
-
|
|
5
|
-
此目录下的所有文件由 **befly-admin** 框架管理,请勿修改!
|
|
6
|
-
|
|
7
|
-
## 自动更新
|
|
8
|
-
|
|
9
|
-
运行以下命令会自动更新此目录:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
befly sync:admin
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## 注意事项
|
|
16
|
-
|
|
17
|
-
1. ❌ **请勿修改** internal 目录下的任何文件
|
|
18
|
-
2. ❌ **请勿删除** internal 目录
|
|
19
|
-
3. ✅ 如需自定义样式,请在 internal 目录外创建文件
|
|
20
|
-
|
|
21
|
-
## 文件用途
|
|
22
|
-
|
|
23
|
-
此目录包含框架核心样式文件,确保管理系统的视觉效果正常运行。
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
📚 更多信息请查看项目文档
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
// SCSS 混合宏(Mixins)
|
|
2
|
-
|
|
3
|
-
// 文本溢出省略
|
|
4
|
-
@mixin text-ellipsis($lines: 1) {
|
|
5
|
-
@if $lines == 1 {
|
|
6
|
-
overflow: hidden;
|
|
7
|
-
text-overflow: ellipsis;
|
|
8
|
-
white-space: nowrap;
|
|
9
|
-
} @else {
|
|
10
|
-
display: -webkit-box;
|
|
11
|
-
-webkit-box-orient: vertical;
|
|
12
|
-
-webkit-line-clamp: $lines;
|
|
13
|
-
overflow: hidden;
|
|
14
|
-
text-overflow: ellipsis;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Flex 布局
|
|
19
|
-
@mixin flex-center {
|
|
20
|
-
display: flex;
|
|
21
|
-
align-items: center;
|
|
22
|
-
justify-content: center;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@mixin flex-between {
|
|
26
|
-
display: flex;
|
|
27
|
-
align-items: center;
|
|
28
|
-
justify-content: space-between;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// 响应式断点
|
|
32
|
-
@mixin respond-to($breakpoint) {
|
|
33
|
-
@if $breakpoint == xs {
|
|
34
|
-
@media (max-width: $breakpoint-xs) {
|
|
35
|
-
@content;
|
|
36
|
-
}
|
|
37
|
-
} @else if $breakpoint == sm {
|
|
38
|
-
@media (min-width: $breakpoint-xs) and (max-width: $breakpoint-sm) {
|
|
39
|
-
@content;
|
|
40
|
-
}
|
|
41
|
-
} @else if $breakpoint == md {
|
|
42
|
-
@media (min-width: $breakpoint-sm) and (max-width: $breakpoint-md) {
|
|
43
|
-
@content;
|
|
44
|
-
}
|
|
45
|
-
} @else if $breakpoint == lg {
|
|
46
|
-
@media (min-width: $breakpoint-md) and (max-width: $breakpoint-lg) {
|
|
47
|
-
@content;
|
|
48
|
-
}
|
|
49
|
-
} @else if $breakpoint == xl {
|
|
50
|
-
@media (min-width: $breakpoint-lg) {
|
|
51
|
-
@content;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 清除浮动
|
|
57
|
-
@mixin clearfix {
|
|
58
|
-
&::after {
|
|
59
|
-
content: '';
|
|
60
|
-
display: table;
|
|
61
|
-
clear: both;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 动画过渡
|
|
66
|
-
@mixin transition($property: all, $duration: $transition-normal, $timing: ease) {
|
|
67
|
-
transition: $property $duration $timing;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 阴影
|
|
71
|
-
@mixin shadow($level: medium) {
|
|
72
|
-
@if $level == small {
|
|
73
|
-
box-shadow: $shadow-small;
|
|
74
|
-
} @else if $level == medium {
|
|
75
|
-
box-shadow: $shadow-medium;
|
|
76
|
-
} @else if $level == large {
|
|
77
|
-
box-shadow: $shadow-large;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// 绝对居中
|
|
82
|
-
@mixin absolute-center {
|
|
83
|
-
position: absolute;
|
|
84
|
-
top: 50%;
|
|
85
|
-
left: 50%;
|
|
86
|
-
transform: translate(-50%, -50%);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// 固定宽高比
|
|
90
|
-
@mixin aspect-ratio($width, $height) {
|
|
91
|
-
position: relative;
|
|
92
|
-
|
|
93
|
-
&::before {
|
|
94
|
-
content: '';
|
|
95
|
-
display: block;
|
|
96
|
-
padding-top: ($height / $width) * 100%;
|
|
97
|
-
}
|
|
98
|
-
}
|
package/src/types/env.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
2
|
-
|
|
3
|
-
declare module '*.vue' {
|
|
4
|
-
import type { DefineComponent } from 'vue';
|
|
5
|
-
const component: DefineComponent<{}, {}, any>;
|
|
6
|
-
export default component;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// 自动路由模块声明
|
|
10
|
-
declare module 'virtual:auto-routes' {
|
|
11
|
-
import type { RouteRecordRaw } from 'vue-router';
|
|
12
|
-
const routes: RouteRecordRaw[];
|
|
13
|
-
export default routes;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface ImportMetaEnv {
|
|
17
|
-
readonly VITE_API_URL: string;
|
|
18
|
-
readonly VITE_APP_TITLE: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface ImportMeta {
|
|
22
|
-
readonly env: ImportMetaEnv;
|
|
23
|
-
}
|
package/src/utils/README.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# Utils 目录说明
|
|
2
|
-
|
|
3
|
-
## 目录结构
|
|
4
|
-
|
|
5
|
-
- `internal.ts` - 框架核心工具函数(由 befly-admin 管理)
|
|
6
|
-
- `index.ts` - 用户自定义工具函数
|
|
7
|
-
|
|
8
|
-
## 使用说明
|
|
9
|
-
|
|
10
|
-
### 框架工具函数
|
|
11
|
-
|
|
12
|
-
```typescript
|
|
13
|
-
import { arrayToTree } from '@/utils/internal';
|
|
14
|
-
// 或者
|
|
15
|
-
import { arrayToTree } from '@/utils';
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
### 自定义工具函数
|
|
19
|
-
|
|
20
|
-
在 `index.ts` 中添加您的工具函数:
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
/**
|
|
24
|
-
* 格式化日期
|
|
25
|
-
*/
|
|
26
|
-
export function formatDate(date: Date): string {
|
|
27
|
-
return date.toISOString().split('T')[0];
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## 注意事项
|
|
32
|
-
|
|
33
|
-
⚠️ **请勿修改** `internal.ts` 文件,运行 `befly sync:admin` 会自动更新此文件
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
📚 更多信息请查看项目文档
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Internal Utils
|
|
2
|
-
|
|
3
|
-
⚠️ **框架核心工具目录**
|
|
4
|
-
|
|
5
|
-
此目录由 `befly-admin` 包管理,请勿手动修改。
|
|
6
|
-
|
|
7
|
-
运行 `befly sync:admin` 会自动更新此目录。
|
|
8
|
-
|
|
9
|
-
## 文件说明
|
|
10
|
-
|
|
11
|
-
- `index.ts` - 核心工具函数(如 `arrayToTree`)
|
|
12
|
-
|
|
13
|
-
## 使用方式
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
// 从 utils 导入(推荐)
|
|
17
|
-
import { arrayToTree } from '@/utils';
|
|
18
|
-
|
|
19
|
-
// 直接从 internal 导入
|
|
20
|
-
import { arrayToTree } from '@/utils/internal';
|
|
21
|
-
```
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 框架核心工具函数
|
|
3
|
-
* ⚠️ 此文件由 befly-admin 包管理,请勿修改
|
|
4
|
-
* 运行 `befly sync:admin` 会自动更新此文件
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 将一维数组转换为树形结构
|
|
9
|
-
* @param items 一维数组
|
|
10
|
-
* @param pid 父节点ID,默认为0
|
|
11
|
-
* @returns 树形结构数组
|
|
12
|
-
*/
|
|
13
|
-
export function arrayToTree<T extends { id: number; pid: number; children?: T[] }>(items: T[], pid = 0): T[] {
|
|
14
|
-
const tree: T[] = [];
|
|
15
|
-
|
|
16
|
-
for (const item of items) {
|
|
17
|
-
if (item.pid === pid) {
|
|
18
|
-
const children = arrayToTree(items, item.id);
|
|
19
|
-
const node = { ...item };
|
|
20
|
-
|
|
21
|
-
if (children.length > 0) {
|
|
22
|
-
node.children = children;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
tree.push(node);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return tree;
|
|
30
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="error-page">
|
|
3
|
-
<div class="error-content">
|
|
4
|
-
<div class="error-code">403</div>
|
|
5
|
-
<h1 class="error-title">无权限访问</h1>
|
|
6
|
-
<p class="error-description">抱歉,您没有访问该页面的权限</p>
|
|
7
|
-
<div class="error-actions">
|
|
8
|
-
<tiny-button type="primary" @click="$Method.goHome">返回首页</tiny-button>
|
|
9
|
-
<tiny-button @click="$Method.goBack">返回上一页</tiny-button>
|
|
10
|
-
</div>
|
|
11
|
-
</div>
|
|
12
|
-
</div>
|
|
13
|
-
</template>
|
|
14
|
-
|
|
15
|
-
<script setup>
|
|
16
|
-
const router = useRouter();
|
|
17
|
-
|
|
18
|
-
const $Method = {
|
|
19
|
-
goHome() {
|
|
20
|
-
router.push('/');
|
|
21
|
-
},
|
|
22
|
-
goBack() {
|
|
23
|
-
router.back();
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<style scoped lang="scss">
|
|
29
|
-
.error-page {
|
|
30
|
-
display: flex;
|
|
31
|
-
align-items: center;
|
|
32
|
-
justify-content: center;
|
|
33
|
-
min-height: 100vh;
|
|
34
|
-
background: $bg-color-page;
|
|
35
|
-
|
|
36
|
-
.error-content {
|
|
37
|
-
text-align: center;
|
|
38
|
-
|
|
39
|
-
.error-code {
|
|
40
|
-
font-size: 120px;
|
|
41
|
-
font-weight: bold;
|
|
42
|
-
color: #ff6b6b;
|
|
43
|
-
margin-bottom: 20px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.error-title {
|
|
47
|
-
font-size: 24px;
|
|
48
|
-
font-weight: 600;
|
|
49
|
-
color: $text-primary;
|
|
50
|
-
margin-bottom: 12px;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.error-description {
|
|
54
|
-
font-size: 14px;
|
|
55
|
-
color: $text-secondary;
|
|
56
|
-
margin-bottom: 30px;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.error-actions {
|
|
60
|
-
display: flex;
|
|
61
|
-
gap: 12px;
|
|
62
|
-
justify-content: center;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Internal 目录说明
|
|
2
|
-
|
|
3
|
-
⚠️ **重要提示**
|
|
4
|
-
|
|
5
|
-
此目录下的所有文件由 **befly-admin** 框架管理,请勿修改!
|
|
6
|
-
|
|
7
|
-
## 自动更新
|
|
8
|
-
|
|
9
|
-
运行以下命令会自动更新此目录:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
befly sync:admin
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## 注意事项
|
|
16
|
-
|
|
17
|
-
1. ❌ **请勿修改** internal 目录下的任何文件
|
|
18
|
-
2. ❌ **请勿删除** internal 目录
|
|
19
|
-
3. ✅ 如需创建业务页面,请在 internal 目录外创建文件
|
|
20
|
-
|
|
21
|
-
## 文件用途
|
|
22
|
-
|
|
23
|
-
此目录包含框架提供的管理页面(用户管理、角色管理、菜单管理等),确保管理系统的基础功能正常运行。
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
📚 更多信息请查看项目文档
|