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,280 +0,0 @@
1
- <template>
2
- <tiny-dialog-box v-model:visible="$Data.visible" title="接口权限" width="900px" :append-to-body="true" :show-footer="true" top="5vh" @close="$Method.onClose">
3
- <div class="comp-role-api">
4
- <!-- 搜索框 -->
5
- <div class="search-box">
6
- <tiny-search v-model="$Data.searchText" placeholder="搜索接口名称或路径" clearable @update:modelValue="$Method.onSearch" />
7
- </div>
8
-
9
- <!-- 接口分组列表 -->
10
- <div class="api-container">
11
- <div v-for="group in $Data.filteredApiData" :key="group.name" class="api-group">
12
- <div class="group-header">{{ group.title }}</div>
13
- <div class="api-checkbox-list">
14
- <tiny-checkbox-group v-model="$Data.checkedApiIds">
15
- <tiny-checkbox v-for="api in group.apis" :key="api.id" :label="api.id"> {{ api.label }} </tiny-checkbox>
16
- </tiny-checkbox-group>
17
- </div>
18
- </div>
19
- </div>
20
- </div>
21
-
22
- <template #footer>
23
- <div class="footer-left">
24
- <tiny-button size="small" @click="$Method.onCheckAll">全选</tiny-button>
25
- <tiny-button size="small" @click="$Method.onUncheckAll">取消全选</tiny-button>
26
- </div>
27
- <div class="footer-right">
28
- <tiny-button @click="$Method.onClose">取消</tiny-button>
29
- <tiny-button type="primary" @click="$Method.onSubmit">保存</tiny-button>
30
- </div>
31
- </template>
32
- </tiny-dialog-box>
33
- </template>
34
-
35
- <script setup>
36
- const $Prop = defineProps({
37
- modelValue: {
38
- type: Boolean,
39
- default: false
40
- },
41
- rowData: {
42
- type: Object,
43
- default: () => ({})
44
- }
45
- });
46
-
47
- const $Emit = defineEmits(['update:modelValue', 'success']);
48
-
49
- const $Data = $ref({
50
- visible: false,
51
- apiData: [],
52
- filteredApiData: [],
53
- searchText: '',
54
- checkedApiIds: []
55
- });
56
-
57
- // 方法集合
58
- const $Method = {
59
- async initData() {
60
- $Method.onShow();
61
- await Promise.all([$Method.apiApiAll(), $Method.apiRoleApiDetail()]);
62
- $Data.filteredApiData = $Data.apiData;
63
- },
64
-
65
- onShow() {
66
- setTimeout(() => {
67
- $Data.visible = $Prop.modelValue;
68
- }, 100);
69
- },
70
-
71
- onClose() {
72
- $Data.visible = false;
73
- setTimeout(() => {
74
- $Emit('update:modelValue', false);
75
- }, 300);
76
- },
77
-
78
- // 加载所有接口
79
- async apiApiAll() {
80
- try {
81
- const res = await $Http('/addon/admin/api/all');
82
-
83
- // 将接口列表按 addonTitle 分组
84
- const apiMap = new Map();
85
-
86
- res.data.lists.forEach((api) => {
87
- const addonTitle = api.addonTitle || api.addonName || '项目接口';
88
- const addonName = api.addonName || 'project';
89
-
90
- if (!apiMap.has(addonName)) {
91
- apiMap.set(addonName, {
92
- name: addonName,
93
- title: addonTitle,
94
- apis: []
95
- });
96
- }
97
-
98
- apiMap.get(addonName).apis.push({
99
- id: api.id,
100
- label: `${api.name}`,
101
- description: api.description
102
- });
103
- });
104
-
105
- $Data.apiData = Array.from(apiMap.values());
106
- } catch (error) {
107
- console.error('加载接口失败:', error);
108
- Modal.message({ message: '加载接口失败', status: 'error' });
109
- }
110
- },
111
-
112
- // 加载该角色已分配的接口
113
- async apiRoleApiDetail() {
114
- if (!$Prop.rowData.id) return;
115
-
116
- try {
117
- const res = await $Http('/addon/admin/role/apiDetail', {
118
- roleId: $Prop.rowData.id
119
- });
120
-
121
- $Data.checkedApiIds = res.data.apiIds || [];
122
- } catch (error) {
123
- console.error('加载角色接口失败:', error);
124
- }
125
- },
126
-
127
- // 搜索过滤
128
- onSearch() {
129
- if (!$Data.searchText) {
130
- $Data.filteredApiData = $Data.apiData;
131
- return;
132
- }
133
-
134
- const searchLower = $Data.searchText.toLowerCase();
135
- $Data.filteredApiData = $Data.apiData
136
- .map((group) => ({
137
- ...group,
138
- apis: group.apis.filter((api) => api.label.toLowerCase().includes(searchLower))
139
- }))
140
- .filter((group) => group.apis.length > 0);
141
- },
142
-
143
- // 全选
144
- onCheckAll() {
145
- const allApiIds = [];
146
- $Data.apiData.forEach((group) => {
147
- group.apis.forEach((api) => {
148
- allApiIds.push(api.id);
149
- });
150
- });
151
- $Data.checkedApiIds = allApiIds;
152
- },
153
-
154
- // 取消全选
155
- onUncheckAll() {
156
- $Data.checkedApiIds = [];
157
- },
158
-
159
- // 提交表单
160
- async onSubmit() {
161
- try {
162
- const res = await $Http('/addon/admin/role/apiSave', {
163
- roleId: $Prop.rowData.id,
164
- apiIds: $Data.checkedApiIds
165
- });
166
-
167
- if (res.code === 0) {
168
- Modal.message({
169
- message: '保存成功',
170
- status: 'success'
171
- });
172
- $Data.visible = false;
173
- $Emit('success');
174
- } else {
175
- Modal.message({
176
- message: res.msg || '保存失败',
177
- status: 'error'
178
- });
179
- }
180
- } catch (error) {
181
- console.error('保存失败:', error);
182
- Modal.message({
183
- message: '保存失败',
184
- status: 'error'
185
- });
186
- }
187
- }
188
- };
189
-
190
- $Method.initData();
191
- </script>
192
-
193
- <style scoped lang="scss">
194
- .comp-role-api {
195
- height: 60vh;
196
- display: flex;
197
- flex-direction: column;
198
- gap: 12px;
199
-
200
- .search-box {
201
- }
202
-
203
- .api-container {
204
- flex: 1;
205
- overflow-y: auto;
206
-
207
- .api-group {
208
- margin-bottom: 16px;
209
- border: 1px solid $border-color;
210
- border-radius: $border-radius-small;
211
- overflow: hidden;
212
-
213
- &:last-child {
214
- margin-bottom: 0;
215
- }
216
-
217
- .group-header {
218
- padding: 12px 16px;
219
- background-color: $bg-color-hover;
220
- font-weight: 500;
221
- font-size: $font-size-sm;
222
- color: $text-primary;
223
- display: flex;
224
- align-items: center;
225
- gap: 8px;
226
-
227
- &::before {
228
- content: '';
229
- width: 8px;
230
- height: 8px;
231
- border-radius: 50%;
232
- background-color: $primary-color;
233
- opacity: 0.3;
234
- flex-shrink: 0;
235
- }
236
- }
237
-
238
- .api-checkbox-list {
239
- padding: 16px;
240
- background-color: $bg-color-container;
241
-
242
- :deep(.tiny-checkbox-group) {
243
- display: flex;
244
- flex-wrap: wrap;
245
- gap: 12px;
246
- width: 100%;
247
- }
248
-
249
- :deep(.tiny-checkbox) {
250
- flex: 0 0 calc(33.333% - 8px);
251
- margin: 0;
252
-
253
- .tiny-checkbox__label {
254
- white-space: nowrap;
255
- overflow: hidden;
256
- text-overflow: ellipsis;
257
- }
258
- }
259
- }
260
- }
261
- }
262
- }
263
-
264
- // 底部操作栏布局
265
- :deep(.tiny-dialog-box__footer) {
266
- display: flex;
267
- justify-content: space-between;
268
- align-items: center;
269
-
270
- .footer-left {
271
- display: flex;
272
- gap: 8px;
273
- }
274
-
275
- .footer-right {
276
- display: flex;
277
- gap: 8px;
278
- }
279
- }
280
- </style>
@@ -1,129 +0,0 @@
1
- <template>
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
- <div class="comp-role-edit">
4
- <tiny-form :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
5
- <tiny-form-item label="角色名称" prop="name">
6
- <tiny-input v-model="$Data.formData.name" placeholder="请输入角色名称" />
7
- </tiny-form-item>
8
- <tiny-form-item label="角色代码" prop="code">
9
- <tiny-input v-model="$Data.formData.code" placeholder="请输入角色代码,如:admin" />
10
- </tiny-form-item>
11
- <tiny-form-item label="角色描述" prop="description">
12
- <tiny-input v-model="$Data.formData.description" type="textarea" placeholder="请输入角色描述" :rows="3" />
13
- </tiny-form-item>
14
- <tiny-form-item label="排序" prop="sort">
15
- <tiny-numeric v-model="$Data.formData.sort" :min="0" :max="9999" />
16
- </tiny-form-item>
17
- <tiny-form-item label="状态" prop="state">
18
- <tiny-radio-group v-model="$Data.formData.state">
19
- <tiny-radio :label="1">正常</tiny-radio>
20
- <tiny-radio :label="2">禁用</tiny-radio>
21
- </tiny-radio-group>
22
- </tiny-form-item>
23
- </tiny-form>
24
- </div>
25
- <template #footer>
26
- <tiny-button @click="$Method.onClose">取消</tiny-button>
27
- <tiny-button type="primary" @click="$Method.onSubmit">确定</tiny-button>
28
- </template>
29
- </tiny-dialog-box>
30
- </template>
31
-
32
- <script setup>
33
- const $Prop = defineProps({
34
- modelValue: {
35
- type: Boolean,
36
- default: false
37
- },
38
- actionType: {
39
- type: String,
40
- default: 'add'
41
- },
42
- rowData: {
43
- type: Object,
44
- default: {}
45
- }
46
- });
47
-
48
- const $Emit = defineEmits(['update:modelValue', 'success']);
49
-
50
- // 表单引用
51
- const $From = $shallowRef({
52
- form: null
53
- });
54
-
55
- const $Computed = {};
56
-
57
- const $Data = $ref({
58
- visible: false,
59
- formData: {
60
- id: 0,
61
- name: '',
62
- code: '',
63
- description: '',
64
- sort: 0,
65
- state: 1
66
- }
67
- });
68
-
69
- const $Data2 = $shallowRef({
70
- formRules: {
71
- name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
72
- code: [
73
- { required: true, message: '请输入角色代码', trigger: 'blur' },
74
- { pattern: /^[a-zA-Z0-9_]+$/, message: '角色代码只能包含字母、数字和下划线', trigger: 'blur' }
75
- ],
76
- sort: [{ type: 'number', message: '排序必须是数字', trigger: 'blur' }]
77
- }
78
- });
79
-
80
- // 方法集合
81
- const $Method = {
82
- async initData() {
83
- if ($Prop.actionType === 'upd' && $Prop.rowData.id) {
84
- $Data.formData = Object.assign({}, $Prop.rowData);
85
- }
86
- $Method.onShow();
87
- },
88
- onShow() {
89
- setTimeout(() => {
90
- $Data.visible = $Prop.modelValue;
91
- }, 100);
92
- },
93
- // 关闭抽屉事件
94
- onClose() {
95
- $Data.visible = false;
96
- setTimeout(() => {
97
- $Emit('update:modelValue', false);
98
- }, 300);
99
- },
100
- async onSubmit() {
101
- try {
102
- const valid = await $From.form.validate();
103
- if (!valid) return;
104
-
105
- const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/roleUpd' : '/addon/admin/roleIns', $Data.formData);
106
-
107
- Modal.message({
108
- message: $Prop.actionType === 'upd' ? '更新成功' : '添加成功',
109
- status: 'success'
110
- });
111
- $Data.visible = false;
112
- $Emit('success');
113
- } catch (error) {
114
- console.error('提交失败:', error);
115
- Modal.message({
116
- message: '提交失败',
117
- status: 'error'
118
- });
119
- }
120
- }
121
- };
122
-
123
- $Method.initData();
124
- </script>
125
-
126
- <style scoped lang="scss">
127
- .comp-role-edit {
128
- }
129
- </style>
@@ -1,143 +0,0 @@
1
- <template>
2
- <tiny-dialog-box v-model:visible="$Data.visible" title="菜单权限" width="600px" :append-to-body="true" :show-footer="true" top="10vh" @close="$Method.onClose">
3
- <div class="comp-role-menu">
4
- <tiny-tree :data="$Data.menuTreeData" node-key="id" show-checkbox default-expand-all :props="{ label: 'name' }" :ref="(el) => ($From.tree = el)" />
5
- </div>
6
- <template #footer>
7
- <tiny-button @click="$Method.onClose">取消</tiny-button>
8
- <tiny-button type="primary" @click="$Method.onSubmit">保存</tiny-button>
9
- </template>
10
- </tiny-dialog-box>
11
- </template>
12
-
13
- <script setup>
14
- import { arrayToTree } from '@/utils';
15
-
16
- const $Prop = defineProps({
17
- modelValue: {
18
- type: Boolean,
19
- default: false
20
- },
21
- rowData: {
22
- type: Object,
23
- default: () => ({})
24
- }
25
- });
26
-
27
- const $Emit = defineEmits(['update:modelValue', 'success']);
28
-
29
- // 表单引用
30
- const $From = $shallowRef({
31
- tree: null
32
- });
33
-
34
- const $Data = $ref({
35
- visible: false,
36
- menuTreeData: [],
37
- menuTreeCheckedKeys: []
38
- });
39
-
40
- // 方法集合
41
- const $Method = {
42
- async initData() {
43
- await Promise.all([$Method.apiMenuAll(), $Method.apiRoleMenuDetail()]);
44
- $Method.onShow();
45
- },
46
-
47
- onShow() {
48
- setTimeout(() => {
49
- $Data.visible = $Prop.modelValue;
50
- }, 100);
51
- },
52
-
53
- onClose() {
54
- $Data.visible = false;
55
- setTimeout(() => {
56
- $Emit('update:modelValue', false);
57
- }, 300);
58
- },
59
-
60
- // 加载菜单树(用于配置权限)
61
- async apiMenuAll() {
62
- try {
63
- const res = await $Http('/addon/admin/menu/all');
64
- // menuAll 返回的 data 直接就是菜单数组
65
- const menuList = Array.isArray(res.data) ? res.data : [];
66
- $Data.menuTreeData = arrayToTree(menuList);
67
- } catch (error) {
68
- console.error('加载菜单失败:', error);
69
- Modal.message({ message: '加载菜单失败', status: 'error' });
70
- }
71
- },
72
-
73
- // 加载该角色已分配的菜单
74
- async apiRoleMenuDetail() {
75
- if (!$Prop.rowData.id) return;
76
-
77
- try {
78
- const res = await $Http('/addon/admin/role/menuDetail', {
79
- roleId: $Prop.rowData.id
80
- });
81
-
82
- // roleMenuDetail 返回的 data 直接就是菜单 ID 数组
83
- $Data.menuTreeCheckedKeys = Array.isArray(res.data) ? res.data : [];
84
-
85
- // 等待树渲染完成后设置选中状态
86
- nextTick(() => {
87
- if ($From.tree && $Data.menuTreeCheckedKeys.length > 0) {
88
- $From.tree.setCheckedKeys($Data.menuTreeCheckedKeys);
89
- }
90
- });
91
- } catch (error) {
92
- console.error('加载角色菜单失败:', error);
93
- }
94
- },
95
-
96
- // 提交表单
97
- async onSubmit() {
98
- try {
99
- if (!$From.tree) {
100
- Modal.message({ message: '菜单树未初始化', status: 'error' });
101
- return;
102
- }
103
-
104
- // 获取选中的节点(包括半选中的父节点)
105
- const checkedKeys = $From.tree.getCheckedKeys();
106
- const halfCheckedKeys = $From.tree.getHalfCheckedKeys();
107
- const menuIds = [...checkedKeys, ...halfCheckedKeys];
108
-
109
- const res = await $Http('/addon/admin/role/menuSave', {
110
- roleId: $Prop.rowData.id,
111
- menuIds
112
- });
113
-
114
- if (res.code === 0) {
115
- Modal.message({
116
- message: '保存成功',
117
- status: 'success'
118
- });
119
- $Data.visible = false;
120
- $Emit('success');
121
- } else {
122
- Modal.message({
123
- message: res.msg || '保存失败',
124
- status: 'error'
125
- });
126
- }
127
- } catch (error) {
128
- console.error('保存失败:', error);
129
- Modal.message({
130
- message: '保存失败',
131
- status: 'error'
132
- });
133
- }
134
- }
135
- };
136
-
137
- $Method.initData();
138
- </script>
139
-
140
- <style scoped lang="scss">
141
- .comp-role-menu {
142
- }
143
- </style>