befly-admin 3.4.6 → 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 (65) hide show
  1. package/.gitignore +2 -0
  2. package/index.html +2 -2
  3. package/package.json +8 -8
  4. package/src/config/{internal/index.ts → index.ts} +1 -1
  5. package/src/layouts/{internal/0.vue → default.vue} +49 -20
  6. package/src/main.ts +3 -5
  7. package/src/plugins/{internal/global.ts → global.ts} +1 -11
  8. package/src/plugins/{internal/http.ts → http.ts} +1 -1
  9. package/src/{plugins/internal/router.ts → router/index.ts} +22 -15
  10. package/src/styles/{internal/index.scss → global.scss} +29 -29
  11. package/src/types/auto-imports.d.ts +90 -645
  12. package/src/types/components.d.ts +5 -23
  13. package/src/types/typed-router.d.ts +32 -0
  14. package/src/utils/index.ts +21 -9
  15. package/src/views/index.vue +27 -0
  16. package/src/views/internal/login.vue +73 -0
  17. package/src/views/test.vue +60 -0
  18. package/tsconfig.json +4 -4
  19. package/vite.config.ts +123 -44
  20. package/src/components/internal/README.md +0 -27
  21. package/src/layouts/4.vue +0 -17
  22. package/src/layouts/internal/1.vue +0 -22
  23. package/src/layouts/internal/2.vue +0 -169
  24. package/src/layouts/internal/README.md +0 -27
  25. package/src/plugins/internal/README.md +0 -36
  26. package/src/styles/internal/README.md +0 -27
  27. package/src/styles/internal/mixins.scss +0 -98
  28. package/src/types/env.d.ts +0 -23
  29. package/src/utils/README.md +0 -37
  30. package/src/utils/internal/README.md +0 -21
  31. package/src/utils/internal/index.ts +0 -30
  32. package/src/views/internal/403/403.vue +0 -66
  33. package/src/views/internal/README.md +0 -27
  34. package/src/views/internal/admin/components/edit.vue +0 -147
  35. package/src/views/internal/admin/components/role.vue +0 -135
  36. package/src/views/internal/admin/index.vue +0 -176
  37. package/src/views/internal/dict/components/edit.vue +0 -156
  38. package/src/views/internal/dict/index.vue +0 -159
  39. package/src/views/internal/index/components/addonList.vue +0 -125
  40. package/src/views/internal/index/components/environmentInfo.vue +0 -97
  41. package/src/views/internal/index/components/operationLogs.vue +0 -112
  42. package/src/views/internal/index/components/performanceMetrics.vue +0 -148
  43. package/src/views/internal/index/components/quickActions.vue +0 -27
  44. package/src/views/internal/index/components/serviceStatus.vue +0 -181
  45. package/src/views/internal/index/components/systemNotifications.vue +0 -130
  46. package/src/views/internal/index/components/systemOverview.vue +0 -188
  47. package/src/views/internal/index/components/systemResources.vue +0 -104
  48. package/src/views/internal/index/components/userInfo.vue +0 -202
  49. package/src/views/internal/index/index.vue +0 -62
  50. package/src/views/internal/login/components/emailLoginForm.vue +0 -163
  51. package/src/views/internal/login/components/registerForm.vue +0 -168
  52. package/src/views/internal/login/components/welcomePanel.vue +0 -61
  53. package/src/views/internal/login/index_1.vue +0 -189
  54. package/src/views/internal/menu/components/edit.vue +0 -150
  55. package/src/views/internal/menu/index.vue +0 -168
  56. package/src/views/internal/news/detail/detail_2.vue +0 -26
  57. package/src/views/internal/news/detail/index.vue +0 -26
  58. package/src/views/internal/news/news.vue +0 -26
  59. package/src/views/internal/role/components/api.vue +0 -280
  60. package/src/views/internal/role/components/edit.vue +0 -129
  61. package/src/views/internal/role/components/menu.vue +0 -143
  62. package/src/views/internal/role/index.vue +0 -179
  63. package/src/views/internal/user/user.vue +0 -320
  64. /package/src/plugins/{internal/storage.ts → storage.ts} +0 -0
  65. /package/src/styles/{internal/variables.scss → variables.scss} +0 -0
@@ -1,179 +0,0 @@
1
- <template>
2
- <div class="page-role page-table">
3
- <div class="main-tool">
4
- <div class="left">
5
- <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
- <template #icon>
7
- <i-lucide:plus style="width: 16px; height: 16px" />
8
- </template>
9
- 添加角色
10
- </tiny-button>
11
- </div>
12
- <div class="right">
13
- <tiny-button @click="$Method.handleRefresh">
14
- <template #icon>
15
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
16
- </template>
17
- 刷新
18
- </tiny-button>
19
- </div>
20
- </div>
21
- <div class="main-table">
22
- <tiny-grid :data="$Data.tableData" header-cell-class-name="custom-table-cell-class" size="small" height="100%" show-overflow="tooltip" border seq-serial>
23
- <tiny-grid-column type="index" title="序号" align="center" :width="100" />
24
- <tiny-grid-column field="name" title="角色名称" :width="150" />
25
- <tiny-grid-column field="code" title="角色代码" :width="150" />
26
- <tiny-grid-column field="description" title="描述" :min-width="150" />
27
- <tiny-grid-column field="sort" title="排序" align="center" :width="80" />
28
- <tiny-grid-column field="state" title="状态" align="center" :width="100">
29
- <template #default="{ row }">
30
- <tiny-tag v-if="row.state === 1" type="success">正常</tiny-tag>
31
- <tiny-tag v-else-if="row.state === 2" type="warning">禁用</tiny-tag>
32
- <tiny-tag v-else type="danger">已删除</tiny-tag>
33
- </template>
34
- </tiny-grid-column>
35
- <tiny-grid-column title="操作" :width="120" align="center" fixed="right">
36
- <template #default="{ row }">
37
- <tiny-dropdown title="操作" trigger="click" size="small" border visible-arrow @item-click="(data) => $Method.onAction(data.itemData.command, row)">
38
- <template #dropdown>
39
- <tiny-dropdown-menu>
40
- <tiny-dropdown-item :item-data="{ command: 'upd' }">
41
- <i-lucide:pencil style="width: 14px; height: 14px; margin-right: 6px" />
42
- 编辑
43
- </tiny-dropdown-item>
44
- <tiny-dropdown-item :item-data="{ command: 'menu' }">
45
- <i-lucide:settings style="width: 14px; height: 14px; margin-right: 6px" />
46
- 菜单权限
47
- </tiny-dropdown-item>
48
- <tiny-dropdown-item :item-data="{ command: 'api' }">
49
- <i-lucide:code style="width: 14px; height: 14px; margin-right: 6px" />
50
- 接口权限
51
- </tiny-dropdown-item>
52
- <tiny-dropdown-item :item-data="{ command: 'del' }" divided>
53
- <i-lucide:trash-2 style="width: 14px; height: 14px; margin-right: 6px" />
54
- 删除
55
- </tiny-dropdown-item>
56
- </tiny-dropdown-menu>
57
- </template>
58
- </tiny-dropdown>
59
- </template>
60
- </tiny-grid-column>
61
- </tiny-grid>
62
- </div>
63
-
64
- <div class="main-page">
65
- <tiny-pager :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.pageSize" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @size-change="$Method.handleSizeChange" />
66
- </div>
67
-
68
- <!-- 编辑对话框组件 -->
69
- <EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="$Method.apiRoleList" />
70
-
71
- <!-- 菜单权限对话框组件 -->
72
- <MenuDialog v-if="$Data.menuVisible" v-model="$Data.menuVisible" :row-data="$Data.rowData" @success="$Method.apiRoleList" />
73
-
74
- <!-- 接口权限对话框组件 -->
75
- <ApiDialog v-if="$Data.apiVisible" v-model="$Data.apiVisible" :row-data="$Data.rowData" @success="$Method.apiRoleList" />
76
- </div>
77
- </template>
78
-
79
- <script setup>
80
- import EditDialog from './components/edit.vue';
81
- import MenuDialog from './components/menu.vue';
82
- import ApiDialog from './components/api.vue';
83
-
84
- // 响应式数据
85
- const $Data = $ref({
86
- tableData: [],
87
- pagerConfig: {
88
- currentPage: 1,
89
- pageSize: 30,
90
- total: 0,
91
- align: 'right',
92
- layout: 'total, prev, pager, next, jumper'
93
- },
94
- editVisible: false,
95
- menuVisible: false,
96
- apiVisible: false,
97
- actionType: 'add',
98
- rowData: {}
99
- });
100
-
101
- // 方法
102
- const $Method = {
103
- async initData() {
104
- await $Method.apiRoleList();
105
- },
106
- // 加载角色列表
107
- async apiRoleList() {
108
- try {
109
- const res = await $Http('/addon/admin/role/list', {
110
- page: $Data.pagerConfig.currentPage,
111
- limit: $Data.pagerConfig.limit
112
- });
113
- $Data.tableData = res.data.lists || [];
114
- $Data.pagerConfig.total = res.data.total || 0;
115
- } catch (error) {
116
- console.error('加载角色列表失败:', error);
117
- Modal.message({
118
- message: '加载数据失败',
119
- status: 'error'
120
- });
121
- }
122
- },
123
-
124
- // 删除角色
125
- async apiRoleDel(row) {
126
- Modal.confirm({
127
- header: '确认删除',
128
- body: `确定要删除角色"${row.name}" 吗?`,
129
- status: 'warning'
130
- }).then(async () => {
131
- try {
132
- const res = await $Http('/addon/admin/role/del', { id: row.id });
133
- if (res.code === 0) {
134
- Modal.message({ message: '删除成功', status: 'success' });
135
- $Method.apiRoleList();
136
- } else {
137
- Modal.message({ message: res.msg || '删除失败', status: 'error' });
138
- }
139
- } catch (error) {
140
- console.error('删除失败:', error);
141
- Modal.message({ message: '删除失败', status: 'error' });
142
- }
143
- });
144
- },
145
-
146
- // 刷新
147
- handleRefresh() {
148
- $Method.apiRoleList();
149
- },
150
-
151
- // 分页改变
152
- onPageChange({ currentPage }) {
153
- $Data.pagerConfig.currentPage = currentPage;
154
- $Method.apiRoleList();
155
- },
156
-
157
- // 操作菜单点击
158
- onAction(command, rowData) {
159
- $Data.actionType = command;
160
- $Data.rowData = rowData;
161
- if (command === 'add' || command === 'upd') {
162
- $Data.editVisible = true;
163
- } else if (command === 'menu') {
164
- $Data.menuVisible = true;
165
- } else if (command === 'api') {
166
- $Data.apiVisible = true;
167
- } else if (command === 'del') {
168
- $Method.apiRoleDel(rowData);
169
- }
170
- }
171
- };
172
-
173
- $Method.initData();
174
- </script>
175
-
176
- <style scoped lang="scss">
177
- .page-role {
178
- }
179
- </style>
@@ -1,320 +0,0 @@
1
- <template>
2
- <div class="user-manage">
3
- <!-- 上:过滤和操作栏 -->
4
- <div class="toolbar">
5
- <div class="toolbar-left">
6
- <t-button theme="primary" @click="$Method.handleAdd">
7
- <template #icon>
8
- <i-lucide:plus style="width: 16px; height: 16px" />
9
- </template>
10
- 添加管理员
11
- </t-button>
12
- </div>
13
- <div class="toolbar-right">
14
- <t-space>
15
- <t-input v-model="$Data.searchKeyword" placeholder="搜索用户名/邮箱" clearable style="width: 200px" @enter="$Method.handleSearch" />
16
- <t-select v-model="$Data.searchState" placeholder="状态" clearable style="width: 120px" :options="$Data.stateOptions" @change="$Method.handleSearch" />
17
- <t-button theme="default" @click="$Method.handleSearch">
18
- <template #icon>
19
- <i-lucide:search style="width: 16px; height: 16px" />
20
- </template>
21
- 搜索
22
- </t-button>
23
- <t-button theme="default" @click="$Method.handleReset">
24
- <template #icon>
25
- <i-lucide:rotate-cw style="width: 16px; height: 16px" />
26
- </template>
27
- 重置
28
- </t-button>
29
- </t-space>
30
- </div>
31
- </div>
32
-
33
- <!-- 中:数据表格 -->
34
- <div class="table-wrapper">
35
- <t-table :data="$Data.userList" :columns="$Data.columns" row-key="id" :loading="$Data.loading" bordered stripe hover max-height="100%">
36
- <template #state="{ row }">
37
- <tiny-tag v-if="row.state === 1" type="success">正常</tiny-tag>
38
- <tiny-tag v-else-if="row.state === 2" type="warning">禁用</tiny-tag>
39
- <tiny-tag v-else type="danger">已删除</tiny-tag>
40
- </template>
41
-
42
- <template #lastLoginTime="{ row }">
43
- <span v-if="row.lastLoginTime">{{ new Date(Number(row.lastLoginTime)).toLocaleString() }}</span>
44
- <span v-else>-</span>
45
- </template>
46
-
47
- <template #operation="{ row }">
48
- <t-space>
49
- <t-link theme="primary" @click="$Method.handleRole(row)">分配角色</t-link>
50
- <t-link theme="warning" @click="$Method.handleEdit(row)">编辑</t-link>
51
- <t-link theme="danger" @click="$Method.handleDelete(row)">删除</t-link>
52
- </t-space>
53
- </template>
54
- </t-table>
55
- </div>
56
-
57
- <!-- 下:分页栏 -->
58
- <div class="pagination-wrapper">
59
- <t-pagination v-model="$Data.pagination.current" v-model:page-size="$Data.pagination.pageSize" :total="$Data.pagination.total" :page-size-options="[10, 20, 50, 100]" show-jumper show-page-size @change="$Method.onPageChange" />
60
- </div>
61
-
62
- <!-- 角色分配对话框 -->
63
- <t-dialog v-model:visible="$Data.roleVisible" header="分配角色" width="600px" :on-confirm="$Method.handleRoleSubmit">
64
- <div class="role-dialog">
65
- <div class="user-info">
66
- <tiny-tag type="primary">{{ $Data.currentUser.username }}</tiny-tag>
67
- <span class="user-email">{{ $Data.currentUser.email }}</span>
68
- </div>
69
- <t-divider />
70
- <t-select v-model="$Data.checkedRoleCode" :options="$Data.roleOptions" placeholder="请选择角色" />
71
- </div>
72
- </t-dialog>
73
- </div>
74
- </template>
75
-
76
- <script setup>
77
- // 响应式数据
78
- const $Data = $ref({
79
- loading: false,
80
- userList: [],
81
- pagination: {
82
- current: 1,
83
- pageSize: 10,
84
- total: 0
85
- },
86
- searchKeyword: '',
87
- searchState: undefined,
88
- stateOptions: [
89
- { label: '正常', value: 1 },
90
- { label: '禁用', value: 2 },
91
- { label: '已删除', value: 0 }
92
- ],
93
- roleVisible: false,
94
- currentUser: {},
95
- columns: [
96
- { colKey: 'username', title: '用户名', width: 150 },
97
- { colKey: 'email', title: '邮箱', width: 200 },
98
- { colKey: 'nickname', title: '昵称', width: 150 },
99
- { colKey: 'state', title: '状态', width: 100 },
100
- { colKey: 'roleCode', title: '角色', width: 120 },
101
- { colKey: 'lastLoginTime', title: '最后登录', width: 180 },
102
- { colKey: 'operation', title: '操作', width: 200, fixed: 'right' }
103
- ],
104
- roleOptions: [],
105
- checkedRoleCode: ''
106
- });
107
-
108
- // 方法集合
109
- const $Method = {
110
- // 加载用户列表
111
- async loadUserList() {
112
- $Data.loading = true;
113
- try {
114
- const res = await $Http('/addon/admin/list', {
115
- page: $Data.pagination.current,
116
- limit: $Data.pagination.pageSize
117
- });
118
- if (res.code === 0 && res.data) {
119
- // getList 返回分页对象 { list, total, page, limit, pages }
120
- $Data.userList = res.data.list || [];
121
- $Data.pagination.total = res.data.total || 0;
122
- }
123
- } catch (error) {
124
- MessagePlugin.error('加载用户列表失败');
125
- console.error(error);
126
- } finally {
127
- $Data.loading = false;
128
- }
129
- },
130
-
131
- // 分页变化
132
- onPageChange(pageInfo) {
133
- $Data.pagination.current = pageInfo.current;
134
- $Data.pagination.pageSize = pageInfo.pageSize;
135
- $Method.loadUserList();
136
- },
137
-
138
- // 搜索
139
- handleSearch() {
140
- $Data.pagination.current = 1;
141
- $Method.loadUserList();
142
- },
143
-
144
- // 重置
145
- handleReset() {
146
- $Data.searchKeyword = '';
147
- $Data.searchState = undefined;
148
- $Data.pagination.current = 1;
149
- $Method.loadUserList();
150
- },
151
-
152
- // 添加管理员
153
- handleAdd() {
154
- MessagePlugin.info('添加管理员功能待开发');
155
- },
156
-
157
- // 编辑管理员
158
- handleEdit(row) {
159
- MessagePlugin.info(`编辑管理员:${row.username}`);
160
- },
161
-
162
- // 删除管理员
163
- handleDelete(row) {
164
- DialogPlugin.confirm({
165
- header: '确认删除',
166
- body: `确定要删除管理员 "${row.username}" 吗?`,
167
- onConfirm: async () => {
168
- try {
169
- // TODO: 调用删除接口
170
- MessagePlugin.success('删除成功');
171
- await $Method.loadUserList();
172
- } catch (error) {
173
- MessagePlugin.error('删除失败');
174
- console.error(error);
175
- }
176
- }
177
- });
178
- },
179
-
180
- // 加载角色列表
181
- async loadRoleList() {
182
- try {
183
- const res = await $Http('/addon/admin/role/list', {});
184
- if (res.code === 0 && res.data) {
185
- // getList 返回分页对象
186
- const roleList = res.data.list || res.data || [];
187
- $Data.roleOptions = roleList
188
- .filter((role) => role.state === 1)
189
- .map((role) => ({
190
- label: role.name,
191
- value: role.code
192
- }));
193
- }
194
- } catch (error) {
195
- MessagePlugin.error('加载角色列表失败');
196
- console.error(error);
197
- }
198
- },
199
-
200
- // 打开角色分配对话框
201
- async handleRole(row) {
202
- $Data.currentUser = row;
203
- $Data.roleVisible = true;
204
-
205
- // 加载角色列表
206
- await $Method.loadRoleList();
207
-
208
- // 加载该用户已有的角色
209
- try {
210
- const res = await $Http('/addon/admin/roleDetail', { adminId: row.id });
211
- if (res.code === 0 && res.data) {
212
- $Data.checkedRoleCode = res.data.roleCode || '';
213
- }
214
- } catch (error) {
215
- MessagePlugin.error('加载用户角色失败');
216
- console.error(error);
217
- }
218
- },
219
-
220
- // 提交角色分配
221
- async handleRoleSubmit() {
222
- if (!$Data.checkedRoleCode) {
223
- MessagePlugin.warning('请选择角色');
224
- return false;
225
- }
226
-
227
- try {
228
- const res = await $Http('/addon/admin/roleSave', {
229
- adminId: $Data.currentUser.id,
230
- roleCode: $Data.checkedRoleCode
231
- });
232
-
233
- if (res.code === 0) {
234
- MessagePlugin.success('角色分配成功');
235
- $Data.roleVisible = false;
236
- await $Method.loadUserList();
237
- return true;
238
- } else {
239
- MessagePlugin.error(res.msg || '分配失败');
240
- return false;
241
- }
242
- } catch (error) {
243
- MessagePlugin.error('分配失败');
244
- console.error(error);
245
- return false;
246
- }
247
- }
248
- };
249
-
250
- // 初始化加载
251
- $Method.loadUserList();
252
- </script>
253
-
254
- <style scoped lang="scss">
255
- .user-manage {
256
- height: 100%;
257
- display: flex;
258
- flex-direction: column;
259
- gap: 16px;
260
- padding: 16px;
261
- overflow: hidden; // 防止外层滚动
262
- }
263
-
264
- // 上:工具栏
265
- .toolbar {
266
- flex-shrink: 0; // 不允许收缩
267
- display: flex;
268
- justify-content: space-between;
269
- align-items: center;
270
- padding: 16px;
271
- background: $bg-color-container;
272
- border-radius: $border-radius;
273
- box-shadow: $shadow-card;
274
-
275
- .toolbar-left {
276
- display: flex;
277
- gap: 12px;
278
- }
279
-
280
- .toolbar-right {
281
- display: flex;
282
- gap: 12px;
283
- }
284
- }
285
-
286
- // 中:表格区域(撑满剩余空间并支持滚动)
287
- .table-wrapper {
288
- flex: 1; // 占据剩余空间
289
- overflow: hidden; // 隐藏超出部分
290
- display: flex;
291
- flex-direction: column;
292
- background: $bg-color-container;
293
- border-radius: $border-radius;
294
- box-shadow: $shadow-card;
295
- }
296
-
297
- // 下:分页栏
298
- .pagination-wrapper {
299
- flex-shrink: 0; // 不允许收缩
300
- display: flex;
301
- justify-content: flex-end;
302
- padding: 16px;
303
- background: $bg-color-container;
304
- border-radius: $border-radius;
305
- box-shadow: $shadow-card;
306
- }
307
-
308
- .role-dialog {
309
- .user-info {
310
- display: flex;
311
- align-items: center;
312
- gap: 12px;
313
- margin-bottom: 16px;
314
-
315
- .user-email {
316
- color: $text-secondary;
317
- }
318
- }
319
- }
320
- </style>
File without changes