befly-admin 3.2.1 → 3.3.1

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 (35) hide show
  1. package/package.json +3 -3
  2. package/src/layouts/0.vue +2 -3
  3. package/src/layouts/2.vue +7 -4
  4. package/src/plugins/http.ts +2 -8
  5. package/src/plugins/router.ts +2 -1
  6. package/src/plugins/storage.ts +146 -0
  7. package/src/views/403/403.vue +39 -6
  8. package/src/views/admin/components/edit.vue +3 -3
  9. package/src/views/admin/components/role.vue +3 -3
  10. package/src/views/admin/index.vue +2 -2
  11. package/src/views/dict/components/edit.vue +3 -3
  12. package/src/views/dict/index.vue +2 -2
  13. package/src/views/index/components/{AddonList.vue → addonList.vue} +2 -2
  14. package/src/views/index/components/{EnvironmentInfo.vue → environmentInfo.vue} +1 -1
  15. package/src/views/index/components/{OperationLogs.vue → operationLogs.vue} +2 -2
  16. package/src/views/index/components/{PerformanceMetrics.vue → performanceMetrics.vue} +1 -1
  17. package/src/views/index/components/{QuickActions.vue → quickActions.vue} +3 -3
  18. package/src/views/index/components/{ServiceStatus.vue → serviceStatus.vue} +1 -1
  19. package/src/views/index/components/{SystemNotifications.vue → systemNotifications.vue} +1 -1
  20. package/src/views/index/components/{SystemOverview.vue → systemOverview.vue} +5 -5
  21. package/src/views/index/components/{SystemResources.vue → systemResources.vue} +4 -4
  22. package/src/views/index/components/{UserInfo.vue → userInfo.vue} +1 -1
  23. package/src/views/index/index.vue +7 -7
  24. package/src/views/login/components/emailLoginForm.vue +163 -0
  25. package/src/views/login/components/registerForm.vue +168 -0
  26. package/src/views/login/components/welcomePanel.vue +61 -0
  27. package/src/views/login/index_1.vue +16 -521
  28. package/src/views/menu/components/edit.vue +3 -3
  29. package/src/views/menu/index.vue +2 -2
  30. package/src/views/role/components/api.vue +3 -3
  31. package/src/views/role/components/menu.vue +10 -10
  32. package/src/views/role/index.vue +2 -2
  33. package/src/views/user/user.vue +8 -8
  34. package/src/api/auth.ts +0 -60
  35. package/temp/router.js +0 -71
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly-admin",
3
- "version": "3.2.1",
4
- "description": "Befly Admin - 基于 Vue3 + TDesign 的后台管理系统",
3
+ "version": "3.3.1",
4
+ "description": "Befly Admin - 基于 Vue3 + OpenTiny Vue 的后台管理系统",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "publishConfig": {
@@ -38,5 +38,5 @@
38
38
  "node": ">=22.0.0",
39
39
  "pnpm": ">=9.0.0"
40
40
  },
41
- "gitHead": "a1808ee7bb1722de50f09da5eda9eb982e9ad350"
41
+ "gitHead": "66e103e5effbb89dd6de894972766fa1a03d564e"
42
42
  }
package/src/layouts/0.vue CHANGED
@@ -9,7 +9,6 @@
9
9
  <tiny-dropdown title="管理员" trigger="click" border type="info" @item-click="$Method.handleUserMenu">
10
10
  <template #dropdown>
11
11
  <tiny-dropdown-menu>
12
- <tiny-dropdown-item :item-data="{ value: 'clearCache' }">刷新缓存</tiny-dropdown-item>
13
12
  <tiny-dropdown-item :item-data="{ value: 'logout' }" divided>退出登录</tiny-dropdown-item>
14
13
  </tiny-dropdown-menu>
15
14
  </template>
@@ -54,7 +53,7 @@ const $Method = {
54
53
  // 获取用户菜单权限
55
54
  async fetchUserMenus() {
56
55
  try {
57
- const { data } = await $Http('/addon/admin/menuAll');
56
+ const { data } = await $Http('/core/menu/all');
58
57
  // 将一维数组转换为树形结构(最多2级)
59
58
  $Data.userMenus = arrayToTree(data);
60
59
  $Method.setActiveMenu();
@@ -102,7 +101,7 @@ const $Method = {
102
101
  handleUserMenu(data) {
103
102
  const value = data.itemData?.value || data.value;
104
103
  if (value === 'logout') {
105
- localStorage.removeItem('token');
104
+ $Storage.local.remove('token');
106
105
  router.push('/login');
107
106
  Modal.message({ message: '退出成功', status: 'success' });
108
107
  } else if (value === 'clearCache') {
package/src/layouts/2.vue CHANGED
@@ -10,7 +10,7 @@ const route = useRoute();
10
10
 
11
11
  // 响应式数据
12
12
  const $Data = $ref({
13
- collapsed: localStorage.getItem('sidebar-collapsed') === 'true',
13
+ collapsed: $Storage.local.get('sidebar-collapsed') === 'true',
14
14
  expandedKeys: [],
15
15
  menuItems: []
16
16
  });
@@ -20,7 +20,7 @@ const $Method = {
20
20
  // 切换折叠状态
21
21
  toggleCollapse() {
22
22
  $Data.collapsed = !$Data.collapsed;
23
- localStorage.setItem('sidebar-collapsed', String($Data.collapsed));
23
+ $Storage.local.set('sidebar-collapsed', String($Data.collapsed));
24
24
  }
25
25
  };
26
26
 
@@ -89,9 +89,12 @@ const handleMenuChange = (value) => {
89
89
 
90
90
  const handleUserMenu = (data) => {
91
91
  if (data.value === 'logout') {
92
- localStorage.removeItem('token');
92
+ $Storage.local.remove('token');
93
93
  router.push('/login');
94
- MessagePlugin.success('退出成功');
94
+ Modal.message({
95
+ message: '退出成功',
96
+ status: 'success'
97
+ });
95
98
  }
96
99
  };
97
100
  </script>
@@ -1,5 +1,6 @@
1
1
  import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
2
2
  import { Modal } from '@opentiny/vue';
3
+ import { $Storage } from './storage';
3
4
 
4
5
  // API 响应格式
5
6
  interface ApiResponse<T = any> {
@@ -21,7 +22,7 @@ const request: AxiosInstance = axios.create({
21
22
  request.interceptors.request.use(
22
23
  (config) => {
23
24
  // 添加 token
24
- const token = localStorage.getItem('token');
25
+ const token = $Storage.local.get('token');
25
26
  if (token) {
26
27
  config.headers.Authorization = `Bearer ${token}`;
27
28
  // 开发环境下打印 token 信息
@@ -70,13 +71,6 @@ request.interceptors.response.use(
70
71
  * @param method - 请求方法,默认为 'post',可选 'get' | 'post'
71
72
  * @param config - axios 请求配置
72
73
  * @returns Promise<ApiResponse<T>>
73
- *
74
- * @example
75
- * // POST 请求(默认)
76
- * await $Http('/addon/admin/login', { email, password });
77
- *
78
- * // GET 请求
79
- * await $Http('/addon/admin/info', {}, 'get');
80
74
  */
81
75
  export function $Http<T = any>(url: string, data: any = {}, method: 'get' | 'post' = 'post', config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
82
76
  const methodLower = method.toLowerCase() as 'get' | 'post';
@@ -1,5 +1,6 @@
1
1
  import { createRouter, createWebHashHistory } from 'vue-router';
2
2
  import autoRoutes from 'virtual:auto-routes';
3
+ import { $Storage } from './storage';
3
4
 
4
5
  /**
5
6
  * 创建并导出路由实例
@@ -20,7 +21,7 @@ router.beforeEach(async (to, from, next) => {
20
21
  document.title = titlePrefix;
21
22
  }
22
23
 
23
- const token = localStorage.getItem('token');
24
+ const token = $Storage.local.get('token');
24
25
 
25
26
  // 判断是否为公开路由:使用 layout0 的需要登录,其他 layout 为公开路由
26
27
  const isProtectedRoute = to.matched.some((record) => record.name === 'layout0');
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Storage 封装
3
+ * 支持命名空间隔离,统一管理 localStorage 和 sessionStorage
4
+ */
5
+
6
+ // 获取命名空间
7
+ const NAMESPACE = import.meta.env.VITE_STORAGE_NAMESPACE || 'befly';
8
+
9
+ /**
10
+ * 存储操作类
11
+ */
12
+ class StorageManager {
13
+ private localStorage: Storage;
14
+ private sessionStorage: Storage;
15
+ private namespace: string;
16
+
17
+ constructor(namespace: string = NAMESPACE) {
18
+ this.localStorage = window.localStorage;
19
+ this.sessionStorage = window.sessionStorage;
20
+ this.namespace = namespace;
21
+ }
22
+
23
+ /**
24
+ * 生成带命名空间的key
25
+ */
26
+ private getKey(key: string): string {
27
+ return `${this.namespace}:${key}`;
28
+ }
29
+
30
+ /**
31
+ * 创建存储操作方法
32
+ */
33
+ private createStorageOps(storage: Storage) {
34
+ return {
35
+ /**
36
+ * 设置存储
37
+ * @param key 键名
38
+ * @param value 值(自动序列化)
39
+ */
40
+ set: (key: string, value: any): void => {
41
+ try {
42
+ const fullKey = this.getKey(key);
43
+ const serializedValue = JSON.stringify(value);
44
+ storage.setItem(fullKey, serializedValue);
45
+ } catch (error) {
46
+ console.error(`Storage.set error for key "${key}":`, error);
47
+ }
48
+ },
49
+
50
+ /**
51
+ * 获取存储
52
+ * @param key 键名
53
+ * @param defaultValue 默认值
54
+ * @returns 解析后的值
55
+ */
56
+ get: <T = any>(key: string, defaultValue: T | null = null): T | null => {
57
+ try {
58
+ const fullKey = this.getKey(key);
59
+ const value = storage.getItem(fullKey);
60
+ if (value === null) {
61
+ return defaultValue;
62
+ }
63
+ return JSON.parse(value) as T;
64
+ } catch (error) {
65
+ console.error(`Storage.get error for key "${key}":`, error);
66
+ return defaultValue;
67
+ }
68
+ },
69
+
70
+ /**
71
+ * 删除存储
72
+ * @param key 键名
73
+ */
74
+ remove: (key: string): void => {
75
+ try {
76
+ const fullKey = this.getKey(key);
77
+ storage.removeItem(fullKey);
78
+ } catch (error) {
79
+ console.error(`Storage.remove error for key "${key}":`, error);
80
+ }
81
+ },
82
+
83
+ /**
84
+ * 清空当前命名空间下的所有存储
85
+ */
86
+ clear: (): void => {
87
+ try {
88
+ const keys = Object.keys(storage);
89
+ const prefix = `${this.namespace}:`;
90
+ keys.forEach((key) => {
91
+ if (key.startsWith(prefix)) {
92
+ storage.removeItem(key);
93
+ }
94
+ });
95
+ } catch (error) {
96
+ console.error('Storage.clear error:', error);
97
+ }
98
+ },
99
+
100
+ /**
101
+ * 检查键是否存在
102
+ * @param key 键名
103
+ * @returns 是否存在
104
+ */
105
+ has: (key: string): boolean => {
106
+ try {
107
+ const fullKey = this.getKey(key);
108
+ return storage.getItem(fullKey) !== null;
109
+ } catch (error) {
110
+ console.error(`Storage.has error for key "${key}":`, error);
111
+ return false;
112
+ }
113
+ },
114
+
115
+ /**
116
+ * 获取所有当前命名空间的键
117
+ * @returns 键名数组(不含命名空间前缀)
118
+ */
119
+ keys: (): string[] => {
120
+ try {
121
+ const allKeys = Object.keys(storage);
122
+ const prefix = `${this.namespace}:`;
123
+ return allKeys.filter((key) => key.startsWith(prefix)).map((key) => key.replace(prefix, ''));
124
+ } catch (error) {
125
+ console.error('Storage.keys error:', error);
126
+ return [];
127
+ }
128
+ }
129
+ };
130
+ }
131
+
132
+ /** localStorage 操作 */
133
+ get local() {
134
+ return this.createStorageOps(this.localStorage);
135
+ }
136
+
137
+ /** sessionStorage 操作 */
138
+ get session() {
139
+ return this.createStorageOps(this.sessionStorage);
140
+ }
141
+ }
142
+
143
+ /**
144
+ * 统一的存储操作对象(单例)
145
+ */
146
+ export const $Storage = new StorageManager();
@@ -1,11 +1,14 @@
1
1
  <template>
2
2
  <div class="error-page">
3
- <t-result status="403" title="无权限访问" description="抱歉,您没有访问该页面的权限">
4
- <template #extra>
5
- <t-button theme="primary" @click="$Method.goHome">返回首页</t-button>
6
- <t-button theme="default" @click="$Method.goBack">返回上一页</t-button>
7
- </template>
8
- </t-result>
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>
9
12
  </div>
10
13
  </template>
11
14
 
@@ -29,5 +32,35 @@ const $Method = {
29
32
  justify-content: center;
30
33
  min-height: 100vh;
31
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
+ }
32
65
  }
33
66
  </style>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <tiny-dialog-box v-model:visible="$Data.visible" :title="$Prop.actionType === 'upd' ? '编辑管理员' : '添加管理员'" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="10vh" @close="$Method.onClose">
3
- <tiny-form :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($Form.form = el)">
3
+ <tiny-form :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
4
4
  <tiny-form-item label="用户名" prop="username">
5
5
  <tiny-input v-model="$Data.formData.username" placeholder="请输入用户名" :disabled="$Prop.actionType === 'upd'" />
6
6
  </tiny-form-item>
@@ -52,7 +52,7 @@ const $Prop = defineProps({
52
52
  const $Emit = defineEmits(['update:modelValue', 'success']);
53
53
 
54
54
  // 表单引用
55
- const $Form = $shallowRef({
55
+ const $From = $shallowRef({
56
56
  form: null
57
57
  });
58
58
 
@@ -118,7 +118,7 @@ const $Method = {
118
118
 
119
119
  async onSubmit() {
120
120
  try {
121
- const valid = await $Form.form.validate();
121
+ const valid = await $From.form.validate();
122
122
  if (!valid) return;
123
123
 
124
124
  const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/adminUpd' : '/addon/admin/adminIns', $Data.formData);
@@ -58,7 +58,7 @@ const $Method = {
58
58
  // 加载角色列表
59
59
  async apiRoleList() {
60
60
  try {
61
- const res = await $Http('/addon/admin/roleList', {
61
+ const res = await $Http('/core/role/list', {
62
62
  page: 1,
63
63
  limit: 1000
64
64
  });
@@ -80,7 +80,7 @@ const $Method = {
80
80
  if (!$Prop.rowData.id) return;
81
81
 
82
82
  try {
83
- const res = await $Http('/addon/admin/adminRoleDetail', {
83
+ const res = await $Http('/core/roleDetail', {
84
84
  adminId: $Prop.rowData.id
85
85
  });
86
86
  $Data.checkedRoleCode = res.data.roleCode || '';
@@ -97,7 +97,7 @@ const $Method = {
97
97
  }
98
98
 
99
99
  try {
100
- const res = await $Http('/addon/admin/adminRoleSave', {
100
+ const res = await $Http('/core/roleSave', {
101
101
  adminId: $Prop.rowData.id,
102
102
  roleCode: $Data.checkedRoleCode
103
103
  });
@@ -99,7 +99,7 @@ const $Method = {
99
99
  // 加载管理员列表
100
100
  async apiAdminList() {
101
101
  try {
102
- const res = await $Http('/addon/admin/adminList', {
102
+ const res = await $Http('/core/list', {
103
103
  page: $Data.pagerConfig.currentPage,
104
104
  limit: $Data.pagerConfig.pageSize
105
105
  });
@@ -122,7 +122,7 @@ const $Method = {
122
122
  status: 'warning'
123
123
  }).then(async () => {
124
124
  try {
125
- const res = await $Http('/addon/admin/adminDel', { id: row.id });
125
+ const res = await $Http('/core/del', { id: row.id });
126
126
  if (res.code === 0) {
127
127
  Modal.message({ message: '删除成功', status: 'success' });
128
128
  $Method.apiAdminList();
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <tiny-dialog-box v-model:visible="$Data.visible" :title="$Prop.actionType === 'upd' ? '编辑字典' : '添加字典'" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="10vh" @close="$Method.onClose">
3
- <tiny-form :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($Form.form = el)">
3
+ <tiny-form :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
4
4
  <tiny-form-item label="字典名称" prop="name">
5
5
  <tiny-input v-model="$Data.formData.name" placeholder="请输入字典名称" />
6
6
  </tiny-form-item>
@@ -52,7 +52,7 @@ const $Prop = defineProps({
52
52
  const $Emit = defineEmits(['update:modelValue', 'success']);
53
53
 
54
54
  // 表单引用
55
- const $Form = $shallowRef({
55
+ const $From = $shallowRef({
56
56
  form: null
57
57
  });
58
58
 
@@ -120,7 +120,7 @@ const $Method = {
120
120
 
121
121
  async onSubmit() {
122
122
  try {
123
- const valid = await $Form.form.validate();
123
+ const valid = await $From.form.validate();
124
124
  if (!valid) return;
125
125
 
126
126
  const res = await $Http($Prop.actionType === 'add' ? '/addon/admin/dictIns' : '/addon/admin/dictUpd', $Data.formData);
@@ -91,7 +91,7 @@ const $Method = {
91
91
  // 加载字典列表
92
92
  async apiDictList() {
93
93
  try {
94
- const res = await $Http('/addon/admin/dictList', {
94
+ const res = await $Http('/core/dict/list', {
95
95
  page: $Data.pagerConfig.currentPage,
96
96
  limit: $Data.pagerConfig.pageSize
97
97
  });
@@ -114,7 +114,7 @@ const $Method = {
114
114
  status: 'warning'
115
115
  }).then(async () => {
116
116
  try {
117
- const res = await $Http('/addon/admin/dictDel', { id: row.id });
117
+ const res = await $Http('/core/dict/del', { id: row.id });
118
118
  if (res.code === 0) {
119
119
  Modal.message({ message: '删除成功', status: 'success' });
120
120
  $Method.apiDictList();
@@ -14,7 +14,7 @@
14
14
  <div class="addon-info">
15
15
  <div class="addon-title">
16
16
  <span class="addon-name">{{ addon.title }}</span>
17
- <t-tag theme="success" variant="outline" size="small">{{ addon.version }}</t-tag>
17
+ <tiny-tag type="success" size="small">{{ addon.version }}</tiny-tag>
18
18
  </div>
19
19
  <div class="addon-desc">{{ addon.description }}</div>
20
20
  </div>
@@ -31,7 +31,7 @@ const addonList = $ref([]);
31
31
  // 获取数据
32
32
  const fetchData = async () => {
33
33
  try {
34
- const { data } = await $Http('/addon/admin/dashboardAddonList');
34
+ const { data } = await $Http('/core/dashboard/addonList');
35
35
  addonList.splice(0, addonList.length, ...data);
36
36
  } catch (error) {
37
37
  console.error('获取插件列表失败:', error);
@@ -49,7 +49,7 @@ const environmentInfo = $ref({
49
49
  // 获取数据
50
50
  const fetchData = async () => {
51
51
  try {
52
- const { data } = await $Http('/addon/admin/dashboardEnvironmentInfo');
52
+ const { data } = await $Http('/core/dashboard/environmentInfo');
53
53
  Object.assign(environmentInfo, data);
54
54
  } catch (error) {
55
55
  console.error('获取运行环境信息失败:', error);
@@ -22,9 +22,9 @@
22
22
  <span class="col-module">{{ log.module }}</span>
23
23
  <span class="col-ip">{{ log.ip }}</span>
24
24
  <span class="col-status">
25
- <t-tag :theme="log.status === 'success' ? 'success' : 'danger'" size="small" variant="light">
25
+ <tiny-tag :type="log.status === 'success' ? 'success' : 'danger'" size="small">
26
26
  {{ log.status === 'success' ? '成功' : '失败' }}
27
- </t-tag>
27
+ </tiny-tag>
28
28
  </span>
29
29
  </div>
30
30
  </div>
@@ -65,7 +65,7 @@ const performanceMetrics = $ref({
65
65
  // 获取数据
66
66
  const fetchData = async () => {
67
67
  try {
68
- const { data } = await $Http('/addon/admin/dashboardPerformanceMetrics');
68
+ const { data } = await $Http('/core/dashboard/performanceMetrics');
69
69
  Object.assign(performanceMetrics, data);
70
70
  } catch (error) {
71
71
  console.error('获取性能指标失败:', error);
@@ -1,12 +1,12 @@
1
1
  <template>
2
2
  <div class="section-block">
3
3
  <div class="section-content">
4
- <t-button theme="primary" size="large" @click="handleClearCache">
5
- <template #icon>
4
+ <tiny-button type="primary" size="large" @click="handleClearCache">
5
+ <template #prefix>
6
6
  <Icon name="RotateCw" :size="18" />
7
7
  </template>
8
8
  刷新缓存
9
- </t-button>
9
+ </tiny-button>
10
10
  </div>
11
11
  </div>
12
12
  </template>
@@ -33,7 +33,7 @@ const services = $ref([]);
33
33
  // 获取数据
34
34
  const fetchData = async () => {
35
35
  try {
36
- const { data } = await $Http('/addon/admin/dashboardServiceStatus');
36
+ const { data } = await $Http('/core/dashboard/serviceStatus');
37
37
  services.splice(0, services.length, ...data.services);
38
38
  } catch (error) {
39
39
  console.error('获取服务状态失败:', error);
@@ -14,7 +14,7 @@
14
14
  <span class="notification-title">{{ notification.title }}</span>
15
15
  <span class="notification-time">{{ formatTime(notification.createdAt) }}</span>
16
16
  </div>
17
- <t-tag v-if="!notification.isRead" theme="primary" size="small" variant="light">新</t-tag>
17
+ <tiny-tag v-if="!notification.isRead" type="primary" size="small">新</tiny-tag>
18
18
  </div>
19
19
  </div>
20
20
  </div>
@@ -5,8 +5,8 @@
5
5
  <h2>系统概览</h2>
6
6
  </div>
7
7
  <div class="section-content">
8
- <t-row :gutter="12">
9
- <t-col :xs="24" :sm="12" :md="12" :lg="12">
8
+ <tiny-row :flex="true" :gap="12">
9
+ <tiny-col :xs="24" :sm="12" :md="12" :lg="12">
10
10
  <div class="info-block">
11
11
  <div class="stats-grid">
12
12
  <div class="stat-box stat-primary">
@@ -32,8 +32,8 @@
32
32
  </div>
33
33
  </div>
34
34
  </div>
35
- </t-col>
36
- </t-row>
35
+ </tiny-col>
36
+ </tiny-row>
37
37
  </div>
38
38
  </div>
39
39
  </template>
@@ -49,7 +49,7 @@ const permissionStats = $ref({
49
49
  // 获取数据
50
50
  const fetchData = async () => {
51
51
  try {
52
- const { data } = await $Http('/addon/admin/dashboardSystemOverview');
52
+ const { data } = await $Http('/core/dashboard/systemOverview');
53
53
  Object.assign(permissionStats, data);
54
54
  } catch (error) {
55
55
  console.error('获取系统概览失败:', error);
@@ -13,7 +13,7 @@
13
13
  <span class="resource-value">{{ systemResources.cpu.usage }}%</span>
14
14
  <span class="resource-desc">{{ systemResources.cpu.cores }}核心</span>
15
15
  </div>
16
- <t-progress :percentage="systemResources.cpu.usage" :theme="getProgressColor(systemResources.cpu.usage)" size="small" />
16
+ <tiny-progress :percentage="systemResources.cpu.usage" :status="getProgressColor(systemResources.cpu.usage)" />
17
17
  </div>
18
18
  <div class="resource-compact-item">
19
19
  <div class="resource-compact-header">
@@ -22,7 +22,7 @@
22
22
  <span class="resource-value">{{ systemResources.memory.percentage }}%</span>
23
23
  <span class="resource-desc">{{ systemResources.memory.used }}GB / {{ systemResources.memory.total }}GB</span>
24
24
  </div>
25
- <t-progress :percentage="systemResources.memory.percentage" :theme="getProgressColor(systemResources.memory.percentage)" size="small" />
25
+ <tiny-progress :percentage="systemResources.memory.percentage" :status="getProgressColor(systemResources.memory.percentage)" />
26
26
  </div>
27
27
  <div class="resource-compact-item">
28
28
  <div class="resource-compact-header">
@@ -31,7 +31,7 @@
31
31
  <span class="resource-value">{{ systemResources.disk.percentage }}%</span>
32
32
  <span class="resource-desc">{{ systemResources.disk.used }}GB / {{ systemResources.disk.total }}GB</span>
33
33
  </div>
34
- <t-progress :percentage="systemResources.disk.percentage" :theme="getProgressColor(systemResources.disk.percentage)" size="small" />
34
+ <tiny-progress :percentage="systemResources.disk.percentage" :status="getProgressColor(systemResources.disk.percentage)" />
35
35
  </div>
36
36
  </div>
37
37
  </div>
@@ -49,7 +49,7 @@ const systemResources = $ref({
49
49
  // 获取数据
50
50
  const fetchData = async () => {
51
51
  try {
52
- const { data } = await $Http('/addon/admin/dashboardSystemResources');
52
+ const { data } = await $Http('/core/dashboard/systemResources');
53
53
  Object.assign(systemResources, data);
54
54
  } catch (error) {
55
55
  console.error('获取系统资源失败:', error);
@@ -33,7 +33,7 @@ const userInfo = $ref({});
33
33
  // 获取数据
34
34
  const fetchData = async () => {
35
35
  try {
36
- const { data } = await $Http('/addon/admin/adminInfo');
36
+ const { data } = await $Http('/core/admin/info');
37
37
  Object.assign(userInfo, data);
38
38
  } catch (error) {
39
39
  console.error('获取用户信息失败:', error);
@@ -15,13 +15,13 @@
15
15
  </template>
16
16
 
17
17
  <script setup>
18
- import SystemOverview from './components/SystemOverview.vue';
19
- import ServiceStatus from './components/ServiceStatus.vue';
20
- import UserInfo from './components/UserInfo.vue';
21
- import AddonList from './components/AddonList.vue';
22
- import SystemResources from './components/SystemResources.vue';
23
- import PerformanceMetrics from './components/PerformanceMetrics.vue';
24
- import EnvironmentInfo from './components/EnvironmentInfo.vue';
18
+ import SystemOverview from './components/systemOverview.vue';
19
+ import ServiceStatus from './components/serviceStatus.vue';
20
+ import UserInfo from './components/userInfo.vue';
21
+ import AddonList from './components/addonList.vue';
22
+ import SystemResources from './components/systemResources.vue';
23
+ import PerformanceMetrics from './components/performanceMetrics.vue';
24
+ import EnvironmentInfo from './components/environmentInfo.vue';
25
25
  </script>
26
26
 
27
27
  <style scoped lang="scss">