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.
Files changed (69) hide show
  1. package/.gitignore +2 -0
  2. package/bunfig.toml +1 -8
  3. package/index.html +2 -2
  4. package/package.json +12 -8
  5. package/src/config/index.ts +20 -0
  6. package/src/layouts/{internal/0.vue → default.vue} +51 -21
  7. package/src/main.ts +3 -5
  8. package/src/plugins/global.ts +17 -0
  9. package/src/plugins/{internal/http.ts → http.ts} +1 -1
  10. package/src/router/index.ts +55 -0
  11. package/src/styles/{internal/index.scss → global.scss} +29 -29
  12. package/src/types/auto-imports.d.ts +176 -637
  13. package/src/types/components.d.ts +28 -19
  14. package/src/types/typed-router.d.ts +32 -0
  15. package/src/utils/index.ts +21 -9
  16. package/src/views/index.vue +27 -0
  17. package/src/views/internal/login.vue +73 -0
  18. package/src/views/test.vue +60 -0
  19. package/tsconfig.json +4 -4
  20. package/vite.config.ts +134 -60
  21. package/src/components/internal/Icon.vue +0 -41
  22. package/src/components/internal/README.md +0 -27
  23. package/src/layouts/4.vue +0 -17
  24. package/src/layouts/internal/1.vue +0 -22
  25. package/src/layouts/internal/2.vue +0 -169
  26. package/src/layouts/internal/README.md +0 -27
  27. package/src/plugins/internal/README.md +0 -36
  28. package/src/plugins/internal/router.ts +0 -48
  29. package/src/plugins/internal/store.ts +0 -19
  30. package/src/styles/internal/README.md +0 -27
  31. package/src/styles/internal/mixins.scss +0 -98
  32. package/src/types/env.d.ts +0 -23
  33. package/src/utils/README.md +0 -37
  34. package/src/utils/internal/README.md +0 -21
  35. package/src/utils/internal/index.ts +0 -30
  36. package/src/views/internal/403/403.vue +0 -66
  37. package/src/views/internal/README.md +0 -27
  38. package/src/views/internal/admin/components/edit.vue +0 -147
  39. package/src/views/internal/admin/components/role.vue +0 -135
  40. package/src/views/internal/admin/index.vue +0 -169
  41. package/src/views/internal/dict/components/edit.vue +0 -156
  42. package/src/views/internal/dict/index.vue +0 -159
  43. package/src/views/internal/index/components/addonList.vue +0 -125
  44. package/src/views/internal/index/components/environmentInfo.vue +0 -97
  45. package/src/views/internal/index/components/operationLogs.vue +0 -112
  46. package/src/views/internal/index/components/performanceMetrics.vue +0 -148
  47. package/src/views/internal/index/components/quickActions.vue +0 -27
  48. package/src/views/internal/index/components/serviceStatus.vue +0 -193
  49. package/src/views/internal/index/components/systemNotifications.vue +0 -136
  50. package/src/views/internal/index/components/systemOverview.vue +0 -188
  51. package/src/views/internal/index/components/systemResources.vue +0 -104
  52. package/src/views/internal/index/components/userInfo.vue +0 -202
  53. package/src/views/internal/index/index.vue +0 -62
  54. package/src/views/internal/login/components/emailLoginForm.vue +0 -163
  55. package/src/views/internal/login/components/registerForm.vue +0 -168
  56. package/src/views/internal/login/components/welcomePanel.vue +0 -61
  57. package/src/views/internal/login/index_1.vue +0 -189
  58. package/src/views/internal/menu/components/edit.vue +0 -150
  59. package/src/views/internal/menu/index.vue +0 -168
  60. package/src/views/internal/news/detail/detail_2.vue +0 -26
  61. package/src/views/internal/news/detail/index.vue +0 -26
  62. package/src/views/internal/news/news.vue +0 -26
  63. package/src/views/internal/role/components/api.vue +0 -280
  64. package/src/views/internal/role/components/edit.vue +0 -129
  65. package/src/views/internal/role/components/menu.vue +0 -143
  66. package/src/views/internal/role/index.vue +0 -179
  67. package/src/views/internal/user/user.vue +0 -320
  68. /package/src/plugins/{internal/storage.ts → storage.ts} +0 -0
  69. /package/src/styles/{internal/variables.scss → variables.scss} +0 -0
package/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ types
2
+
1
3
  # Logs
2
4
  logs
3
5
  *.log
package/bunfig.toml CHANGED
@@ -1,11 +1,4 @@
1
1
  [install]
2
- # 使用隔离模式
3
2
  linker = "isolated"
4
3
 
5
-
6
- # 提升类型定义和工具到根目录
7
- publicHoistPattern = [
8
- "@types/*", # 所有 TypeScript 类型
9
- "typescript", # TypeScript 编译器
10
- "@opentiny/*",
11
- ]
4
+ publicHoistPattern = ["@types*", "*eslint*", "@opentiny/*"]
package/index.html CHANGED
@@ -1,10 +1,10 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="zh-CN">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Befly Admin - 后台管理系统</title>
7
+ <title>Befly - 后台管理系统</title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly-admin",
3
- "version": "3.4.5",
3
+ "version": "3.4.7",
4
4
  "description": "Befly Admin - 基于 Vue3 + OpenTiny Vue 的后台管理系统",
5
5
  "type": "module",
6
6
  "private": false,
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "scripts": {
25
25
  "dev": "vite",
26
- "build": "vue-tsc && vite build",
26
+ "build": "vite build",
27
27
  "preview": "vite preview",
28
28
  "type-check": "vue-tsc --noEmit",
29
29
  "sync:admin": "bunx befly sync:admin"
@@ -31,26 +31,30 @@
31
31
  "dependencies": {
32
32
  "@opentiny/vue": "^3.27.0",
33
33
  "axios": "^1.13.2",
34
- "befly-auto-routes": "^1.1.0",
35
- "lucide-vue-next": "^0.552.0",
36
34
  "pinia": "^3.0.4",
37
35
  "vue": "^3.5.22",
38
36
  "vue-router": "^4.6.3"
39
37
  },
40
38
  "devDependencies": {
39
+ "@befly-addon/admin": "1.0.11",
40
+ "@iconify-json/lucide": "^1.2.72",
41
41
  "@opentiny/unplugin-tiny-vue": "^1.0.0",
42
42
  "@vitejs/plugin-vue": "^6.0.1",
43
43
  "@vue-macros/reactivity-transform": "^3.1.1",
44
44
  "sass": "^1.93.3",
45
45
  "typescript": "^5.9.3",
46
46
  "unplugin-auto-import": "^20.2.0",
47
+ "unplugin-icons": "^0.22.0",
47
48
  "unplugin-vue-components": "^30.0.0",
48
- "vite": "^7.2.0",
49
+ "unplugin-vue-router": "^0.10.8",
50
+ "vite": "^7.2.2",
51
+ "vite-plugin-vue-devtools": "^8.0.3",
52
+ "vite-plugin-vue-layouts-next": "^1.2.0",
49
53
  "vue-tsc": "^3.1.3"
50
54
  },
51
55
  "engines": {
52
- "node": ">=22.0.0",
53
- "pnpm": ">=9.0.0"
56
+ "node": ">=24.0.0",
57
+ "pnpm": ">=10.0.0"
54
58
  },
55
- "gitHead": "70faf2a86ad8e9e71c5e80fde3f0b2e22c81a18a"
59
+ "gitHead": "51d86162e5f0b94ecc44a833a98ebf97c27f7bd6"
56
60
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 内部配置
3
+ * 存放框架内置的配置变量,不建议修改
4
+ */
5
+
6
+ /**
7
+ * 内置配置对象
8
+ */
9
+ export const $Config = {
10
+ /** 应用标题 */
11
+ appTitle: import.meta.env.VITE_APP_TITLE || '管理后台',
12
+ /** API 基础地址 */
13
+ apiBaseUrl: import.meta.env.VITE_API_BASE_URL || '',
14
+ /** 存储命名空间 */
15
+ storageNamespace: import.meta.env.VITE_STORAGE_NAMESPACE || 'befly_admin',
16
+ /** 是否开发环境 */
17
+ isDev: import.meta.env.DEV,
18
+ /** 是否生产环境 */
19
+ isProd: import.meta.env.PROD
20
+ };
@@ -3,16 +3,16 @@
3
3
  <!-- 顶部导航栏 -->
4
4
  <div class="layout-header">
5
5
  <div class="logo">
6
- <h2>{{ import.meta.env.VITE_APP_TITLE }}</h2>
6
+ <h2>{{ $Config.appTitle }}</h2>
7
7
  </div>
8
8
  <div class="header-right">
9
- <tiny-dropdown title="管理员" trigger="click" border type="info" @item-click="$Method.handleUserMenu">
10
- <template #dropdown>
11
- <tiny-dropdown-menu>
12
- <tiny-dropdown-item :item-data="{ value: 'logout' }" divided>退出登录</tiny-dropdown-item>
13
- </tiny-dropdown-menu>
14
- </template>
15
- </tiny-dropdown>
9
+ <div class="user-info-bar">
10
+ <div class="user-text">
11
+ <span class="user-name">{{ $Data.userInfo.nickname || '管理员' }}</span>
12
+ <tiny-tag type="info" size="small">{{ $Data.userInfo.role || '超级管理员' }}</tiny-tag>
13
+ </div>
14
+ <tiny-button size="medium" :icon="iconClose()" @click="$Method.handleLogout" />
15
+ </div>
16
16
  </div>
17
17
  </div>
18
18
 
@@ -21,7 +21,7 @@
21
21
  <tiny-tree-menu :data="$Data.userMenus" :props="{ label: 'name' }" node-key="id" :node-height="40" :show-filter="false" :default-expanded-keys="$Data.expandedKeys" :default-expanded-keys-highlight="$Data.currentNodeKey" style="height: 100%" only-check-children width-adapt @node-click="$Method.onMenuClick">
22
22
  <template #default="{ data }">
23
23
  <span class="menu-item">
24
- <Icon :name="data.icon || 'Squircle'" :size="16" style="margin-right: 8px; vertical-align: middle" />
24
+ <i-lucide:square style="width: 16px; height: 16px; margin-right: 8px; vertical-align: middle" />
25
25
  <span>{{ data.name }}</span>
26
26
  </span>
27
27
  </template>
@@ -37,15 +37,21 @@
37
37
 
38
38
  <script setup>
39
39
  import { arrayToTree } from '@/utils';
40
+ import { iconClose } from '@opentiny/vue-icon';
40
41
 
41
42
  const router = useRouter();
42
43
  const route = useRoute();
44
+ const global = useGlobal();
43
45
 
44
46
  // 响应式数据
45
47
  const $Data = $ref({
46
48
  userMenus: [],
47
49
  expandedKeys: [],
48
- currentNodeKey: 0
50
+ currentNodeKey: 0,
51
+ userInfo: {
52
+ nickname: '管理员',
53
+ role: '超级管理员'
54
+ }
49
55
  });
50
56
 
51
57
  // 方法
@@ -97,17 +103,17 @@ const $Method = {
97
103
  }
98
104
  },
99
105
 
100
- // 处理用户菜单点击
101
- handleUserMenu(data) {
102
- const value = data.itemData?.value || data.value;
103
- if (value === 'logout') {
104
- $Storage.local.remove('token');
105
- router.push('/login');
106
- Modal.message({ message: '退出成功', status: 'success' });
107
- } else if (value === 'clearCache') {
108
- console.log('刷新缓存');
109
- Modal.message({ message: '缓存刷新成功', status: 'success' });
110
- }
106
+ // 处理退出登录
107
+ handleLogout() {
108
+ Modal.confirm({
109
+ message: '确定要退出登录吗?',
110
+ title: '确认',
111
+ onConfirm: () => {
112
+ $Storage.local.remove('token');
113
+ router.push('/internal/login');
114
+ Message.success('退出成功');
115
+ }
116
+ });
111
117
  }
112
118
  };
113
119
 
@@ -161,6 +167,30 @@ $Method.fetchUserMenus();
161
167
  display: flex;
162
168
  align-items: center;
163
169
  gap: 16px;
170
+
171
+ .user-info-bar {
172
+ display: flex;
173
+ align-items: center;
174
+ gap: 12px;
175
+
176
+ .user-avatar {
177
+ width: 32px;
178
+ height: 32px;
179
+ flex-shrink: 0;
180
+ }
181
+
182
+ .user-text {
183
+ display: flex;
184
+ flex-direction: column;
185
+ align-items: flex-start;
186
+
187
+ .user-name {
188
+ font-size: 14px;
189
+ font-weight: 500;
190
+ color: $text-primary;
191
+ }
192
+ }
193
+ }
164
194
  }
165
195
  }
166
196
 
package/src/main.ts CHANGED
@@ -1,12 +1,10 @@
1
- import { createApp } from 'vue';
2
- import { createPinia } from 'pinia';
3
1
  import App from './App.vue';
4
2
 
5
- // 引入全局样式
6
- import './styles/internal/index.scss';
3
+ // 引入全局基础样式(reset、通用类、滚动条等)
4
+ import '@/styles/global.scss';
7
5
 
8
6
  // 引入路由实例
9
- import { router } from './plugins/internal/router';
7
+ import { router } from './router';
10
8
 
11
9
  const app = createApp(App);
12
10
 
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 全局状态管理
3
+ * 集中管理所有全局数据,避免分散到多个 store 文件
4
+ */
5
+ export const useGlobal = defineStore('global', () => {
6
+ // ==================== 全局数据 ====================
7
+ const data = $ref({});
8
+
9
+ // ==================== 全局方法 ====================
10
+ const method = {};
11
+
12
+ // ==================== 返回 ====================
13
+ return {
14
+ data,
15
+ method
16
+ };
17
+ });
@@ -56,7 +56,7 @@ request.interceptors.response.use(
56
56
  return Promise.reject(res.data);
57
57
  }
58
58
 
59
- return res;
59
+ return res as any;
60
60
  },
61
61
  (error) => {
62
62
  Modal.message({ message: '网络连接失败', status: 'error' });
@@ -0,0 +1,55 @@
1
+ import { createRouter, createWebHashHistory } from 'vue-router';
2
+ import { routes, handleHotUpdate } from 'vue-router/auto-routes';
3
+ import { setupLayouts } from 'virtual:generated-layouts';
4
+ import { $Storage } from '@/plugins/storage';
5
+
6
+ // 应用布局系统
7
+ const layoutRoutes = setupLayouts(routes);
8
+
9
+ // 打印自动生成的路由信息
10
+ console.log('=== 自动生成的路由列表 ===');
11
+ console.log(`路由总数: ${layoutRoutes.length}`);
12
+ console.dir(layoutRoutes);
13
+ console.log('========================');
14
+
15
+ /**
16
+ * 创建并导出路由实例
17
+ * 可直接在 main.ts 中使用 app.use(router)
18
+ */
19
+ export const router = createRouter({
20
+ history: createWebHashHistory(import.meta.env.BASE_URL),
21
+ routes: layoutRoutes
22
+ });
23
+
24
+ // HMR 支持
25
+ if (import.meta.hot) {
26
+ handleHotUpdate(router);
27
+ }
28
+
29
+ // 路由守卫 - 基础验证
30
+ router.beforeEach(async (to, from, next) => {
31
+ const token = $Storage.local.get('token');
32
+
33
+ // 判断是否为公开路由:meta.public 为 true 表示公开路由
34
+ const isPublicRoute = to.meta?.public === true;
35
+
36
+ // 1. 未登录且访问非公开路由 → 跳转登录
37
+ if (!token && !isPublicRoute) {
38
+ return next('/internal/login');
39
+ }
40
+
41
+ // 2. 已登录访问登录页 → 跳转首页
42
+ if (token && to.path === '/internal/login') {
43
+ return next('/');
44
+ }
45
+
46
+ next();
47
+ });
48
+
49
+ // 路由就绪后处理
50
+ router.afterEach((to) => {
51
+ // 可以在这里添加页面访问统计等
52
+ if (import.meta.env.DEV) {
53
+ console.log(`[Router] 导航到: ${to.path}`);
54
+ }
55
+ });
@@ -73,35 +73,35 @@ body {
73
73
  padding-left: 0 !important;
74
74
  }
75
75
 
76
- // 首页组件通用样式
77
- .section-block {
78
- background: $dashboard-section-bg;
79
- border-radius: $dashboard-section-radius;
80
- padding: $dashboard-section-padding;
81
- border: 1px solid $dashboard-section-border;
82
- box-shadow: $shadow-small;
83
-
84
- .section-header {
85
- display: flex;
86
- align-items: center;
87
- gap: $spacing-sm;
88
- margin-bottom: $spacing-md;
89
- padding-bottom: $spacing-sm;
90
- border-bottom: 1px solid $border-color-light;
91
-
92
- h2 {
93
- font-size: $dashboard-header-font-size;
94
- font-weight: 600;
95
- color: $text-primary;
96
- margin: 0;
97
- flex: 1;
98
- }
99
- }
100
-
101
- .section-content {
102
- font-size: $dashboard-content-font-size;
103
- }
104
- }
76
+ // 首页组件通用样式 - 临时注释未定义变量
77
+ // .section-block {
78
+ // background: $dashboard-section-bg;
79
+ // border-radius: $dashboard-section-radius;
80
+ // padding: $dashboard-section-padding;
81
+ // border: 1px solid $dashboard-section-border;
82
+ // box-shadow: $shadow-small;
83
+
84
+ // .section-header {
85
+ // display: flex;
86
+ // align-items: center;
87
+ // gap: $spacing-sm;
88
+ // margin-bottom: $spacing-md;
89
+ // padding-bottom: $spacing-sm;
90
+ // border-bottom: 1px solid $border-color-light;
91
+
92
+ // h2 {
93
+ // font-size: $dashboard-header-font-size;
94
+ // font-weight: 600;
95
+ // color: $text-primary;
96
+ // margin: 0;
97
+ // flex: 1;
98
+ // }
99
+ // }
100
+
101
+ // .section-content {
102
+ // font-size: $dashboard-content-font-size;
103
+ // }
104
+ // }
105
105
 
106
106
  // 数据列表页面通用布局样式
107
107
  .page-table {