@befly-addon/admin 1.0.54 → 1.0.56

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 (82) hide show
  1. package/apis/admin/cacheRefresh.ts +17 -14
  2. package/apis/admin/ins.ts +11 -15
  3. package/apis/admin/upd.ts +1 -13
  4. package/apis/api/all.ts +1 -1
  5. package/apis/api/list.ts +30 -0
  6. package/apis/auth/login.ts +51 -7
  7. package/apis/dashboard/serviceStatus.ts +2 -2
  8. package/apis/dashboard/systemResources.ts +1 -1
  9. package/apis/dict/all.ts +1 -1
  10. package/apis/dict/del.ts +1 -1
  11. package/apis/dict/detail.ts +2 -2
  12. package/apis/dict/ins.ts +1 -1
  13. package/apis/dict/upd.ts +1 -1
  14. package/apis/email/config.ts +16 -0
  15. package/apis/email/logList.ts +13 -0
  16. package/apis/email/send.ts +42 -0
  17. package/apis/email/verify.ts +12 -0
  18. package/apis/loginLog/list.ts +13 -0
  19. package/apis/menu/all.ts +2 -2
  20. package/apis/menu/list.ts +1 -1
  21. package/apis/operateLog/list.ts +13 -0
  22. package/apis/role/del.ts +2 -2
  23. package/apis/role/save.ts +2 -2
  24. package/apis/sysConfig/all.ts +12 -0
  25. package/apis/sysConfig/del.ts +30 -0
  26. package/apis/sysConfig/get.ts +31 -0
  27. package/apis/sysConfig/ins.ts +38 -0
  28. package/apis/sysConfig/list.ts +14 -0
  29. package/apis/sysConfig/upd.ts +50 -0
  30. package/package.json +14 -3
  31. package/plugins/email.ts +206 -0
  32. package/styles/variables.scss +121 -60
  33. package/tables/admin.json +0 -15
  34. package/tables/emailLog.json +69 -0
  35. package/tables/loginLog.json +96 -0
  36. package/tables/operateLog.json +82 -0
  37. package/tables/role.json +1 -1
  38. package/tables/sysConfig.json +53 -0
  39. package/views/403_1/meta.json +4 -0
  40. package/views/{dict → config/dict}/components/edit.vue +7 -5
  41. package/views/config/dict/index.vue +205 -0
  42. package/views/config/dict/meta.json +4 -0
  43. package/views/config/meta.json +4 -0
  44. package/views/config/system/components/edit.vue +179 -0
  45. package/views/config/system/index.vue +256 -0
  46. package/views/config/system/meta.json +4 -0
  47. package/views/index/index.vue +46 -9
  48. package/views/index/meta.json +4 -0
  49. package/views/log/email/index.vue +285 -0
  50. package/views/log/email/meta.json +4 -0
  51. package/views/log/login/index.vue +180 -0
  52. package/views/log/login/meta.json +4 -0
  53. package/views/log/meta.json +4 -0
  54. package/views/log/operate/index.vue +242 -0
  55. package/views/log/operate/meta.json +4 -0
  56. package/views/login_1/meta.json +4 -0
  57. package/views/{admin → people/admin}/components/edit.vue +23 -35
  58. package/views/{admin → people/admin}/index.vue +37 -96
  59. package/views/people/admin/meta.json +4 -0
  60. package/views/people/meta.json +4 -0
  61. package/views/permission/api/index.vue +143 -0
  62. package/views/permission/api/meta.json +4 -0
  63. package/views/permission/menu/index.vue +146 -0
  64. package/views/permission/menu/meta.json +4 -0
  65. package/views/permission/meta.json +4 -0
  66. package/views/{role → permission/role}/components/api.vue +22 -51
  67. package/views/{role → permission/role}/components/edit.vue +14 -15
  68. package/views/{role → permission/role}/components/menu.vue +11 -38
  69. package/views/permission/role/index.vue +227 -0
  70. package/views/permission/role/meta.json +4 -0
  71. package/apis/menu/del.ts +0 -31
  72. package/apis/menu/ins.ts +0 -19
  73. package/apis/menu/upd.ts +0 -27
  74. package/views/dict/index.vue +0 -162
  75. package/views/menu/components/edit.vue +0 -145
  76. package/views/menu/index.vue +0 -173
  77. package/views/role/index.vue +0 -184
  78. /package/views/{403 → 403_1}/index.vue +0 -0
  79. /package/views/{login → login_1}/components/emailLoginForm.vue +0 -0
  80. /package/views/{login → login_1}/components/registerForm.vue +0 -0
  81. /package/views/{login → login_1}/components/welcomePanel.vue +0 -0
  82. /package/views/{login/index_1.vue → login_1/index.vue} +0 -0
@@ -12,7 +12,7 @@
12
12
 
13
13
  <!-- 接口分组列表 -->
14
14
  <div class="api-container">
15
- <div v-for="group in $Data.filteredApiData" :key="group.name" class="api-group">
15
+ <div class="api-group" v-for="group in $Data.filteredApiData" :key="group.name">
16
16
  <div class="group-header">{{ group.title }}</div>
17
17
  <div class="api-checkbox-list">
18
18
  <TCheckboxGroup v-model="$Data.checkedApiIds">
@@ -24,13 +24,11 @@
24
24
  </div>
25
25
 
26
26
  <template #footer>
27
- <div class="footer-left">
28
- <TButton size="small" @click="$Method.onCheckAll">全选</TButton>
29
- <TButton size="small" @click="$Method.onUncheckAll">取消全选</TButton>
30
- </div>
31
- <div class="footer-right">
32
- <TButton @click="$Method.onClose">取消</TButton>
33
- <TButton theme="primary" @click="$Method.onSubmit">保存</TButton>
27
+ <div class="dialog-footer">
28
+ <t-space>
29
+ <TButton theme="default" @click="$Method.onClose">取消</TButton>
30
+ <TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">保存</TButton>
31
+ </t-space>
34
32
  </div>
35
33
  </template>
36
34
  </TDialog>
@@ -56,6 +54,7 @@ const $Emit = defineEmits(['update:modelValue', 'success']);
56
54
 
57
55
  const $Data = $ref({
58
56
  visible: false,
57
+ submitting: false,
59
58
  apiData: [],
60
59
  filteredApiData: [],
61
60
  searchText: '',
@@ -113,7 +112,7 @@ const $Method = {
113
112
  $Data.apiData = Array.from(apiMap.values());
114
113
  } catch (error) {
115
114
  console.error('加载接口失败:', error);
116
- MessagePlugin.info({ message: '加载接口失败', status: 'error' });
115
+ MessagePlugin.error('加载接口失败');
117
116
  }
118
117
  },
119
118
 
@@ -148,49 +147,28 @@ const $Method = {
148
147
  .filter((group) => group.apis.length > 0);
149
148
  },
150
149
 
151
- // 全选
152
- onCheckAll() {
153
- const allApiIds = [];
154
- $Data.apiData.forEach((group) => {
155
- group.apis.forEach((api) => {
156
- allApiIds.push(api.id);
157
- });
158
- });
159
- $Data.checkedApiIds = allApiIds;
160
- },
161
-
162
- // 取消全选
163
- onUncheckAll() {
164
- $Data.checkedApiIds = [];
165
- },
166
-
167
150
  // 提交表单
168
151
  async onSubmit() {
169
152
  try {
153
+ $Data.submitting = true;
154
+
170
155
  const res = await $Http('/addon/admin/role/apiSave', {
171
156
  roleId: $Prop.rowData.id,
172
157
  apiIds: $Data.checkedApiIds
173
158
  });
174
159
 
175
160
  if (res.code === 0) {
176
- MessagePlugin.info({
177
- message: '保存成功',
178
- status: 'success'
179
- });
161
+ MessagePlugin.success('保存成功');
180
162
  $Data.visible = false;
181
163
  $Emit('success');
182
164
  } else {
183
- MessagePlugin.info({
184
- message: res.msg || '保存失败',
185
- status: 'error'
186
- });
165
+ MessagePlugin.error(res.msg || '保存失败');
187
166
  }
188
167
  } catch (error) {
189
168
  console.error('保存失败:', error);
190
- MessagePlugin.info({
191
- message: '保存失败',
192
- status: 'error'
193
- });
169
+ MessagePlugin.error('保存失败');
170
+ } finally {
171
+ $Data.submitting = false;
194
172
  }
195
173
  }
196
174
  };
@@ -218,6 +196,10 @@ $Method.initData();
218
196
  border-radius: var(--border-radius-small);
219
197
  overflow: hidden;
220
198
 
199
+ .api-checkbox-list {
200
+ padding: 10px;
201
+ }
202
+
221
203
  &:last-child {
222
204
  margin-bottom: 0;
223
205
  }
@@ -271,20 +253,9 @@ $Method.initData();
271
253
  }
272
254
  }
273
255
 
274
- // 底部操作栏布局
275
- :deep(.t-dialog__footer) {
256
+ .dialog-footer {
257
+ width: 100%;
276
258
  display: flex;
277
- justify-content: space-between;
278
- align-items: center;
279
-
280
- .footer-left {
281
- display: flex;
282
- gap: 8px;
283
- }
284
-
285
- .footer-right {
286
- display: flex;
287
- gap: 8px;
288
- }
259
+ justify-content: center;
289
260
  }
290
261
  </style>
@@ -9,22 +9,22 @@
9
9
  <TInput v-model="$Data.formData.code" placeholder="请输入角色代码,如:admin" />
10
10
  </TFormItem>
11
11
  <TFormItem label="角色描述" prop="description">
12
- <TInput v-model="$Data.formData.description" type="textarea" placeholder="请输入角色描述" :rows="3" />
12
+ <TInput v-model="$Data.formData.description" placeholder="请输入角色描述" />
13
13
  </TFormItem>
14
14
  <TFormItem label="排序" prop="sort">
15
15
  <TInputNumber v-model="$Data.formData.sort" :min="0" :max="9999" />
16
16
  </TFormItem>
17
17
  <TFormItem label="状态" prop="state">
18
18
  <TRadioGroup v-model="$Data.formData.state">
19
- <TRadio :label="1">正常</TRadio>
20
- <TRadio :label="2">禁用</TRadio>
19
+ <TRadio :value="1">正常</TRadio>
20
+ <TRadio :value="2">禁用</TRadio>
21
21
  </TRadioGroup>
22
22
  </TFormItem>
23
23
  </TForm>
24
24
  </div>
25
25
  <template #footer>
26
26
  <TButton @click="$Method.onClose">取消</TButton>
27
- <TButton theme="primary" @click="$Method.onSubmit">确定</TButton>
27
+ <TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">确定</TButton>
28
28
  </template>
29
29
  </TDialog>
30
30
  </template>
@@ -42,6 +42,7 @@ import {
42
42
  Button as TButton,
43
43
  MessagePlugin
44
44
  } from 'tdesign-vue-next';
45
+ import { fieldClear } from 'befly-shared/fieldClear';
45
46
  import { $Http } from '@/plugins/http';
46
47
 
47
48
  const $Prop = defineProps({
@@ -70,6 +71,7 @@ const $Computed = {};
70
71
 
71
72
  const $Data = $ref({
72
73
  visible: false,
74
+ submitting: false,
73
75
  formData: {
74
76
  id: 0,
75
77
  name: '',
@@ -116,20 +118,17 @@ const $Method = {
116
118
  const valid = await $From.form.validate();
117
119
  if (!valid) return;
118
120
 
119
- const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/roleUpd' : '/addon/admin/roleIns', $Data.formData);
121
+ $Data.submitting = true;
122
+ const formData = $Prop.actionType === 'add' ? fieldClear($Data.formData, { omitKeys: ['id', 'state'] }) : $Data.formData;
123
+ const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/role/upd' : '/addon/admin/role/ins', formData);
120
124
 
121
- MessagePlugin.info({
122
- message: $Prop.actionType === 'upd' ? '更新成功' : '添加成功',
123
- status: 'success'
124
- });
125
- $Data.visible = false;
125
+ MessagePlugin.success(res.msg);
126
126
  $Emit('success');
127
+ $Method.onClose();
127
128
  } catch (error) {
128
- console.error('提交失败:', error);
129
- MessagePlugin.info({
130
- message: '提交失败',
131
- status: 'error'
132
- });
129
+ MessagePlugin.error(error.msg || '提交失败');
130
+ } finally {
131
+ $Data.submitting = false;
133
132
  }
134
133
  }
135
134
  };
@@ -1,17 +1,16 @@
1
1
  <template>
2
2
  <TDialog v-model:visible="$Data.visible" title="菜单权限" width="600px" :append-to-body="true" :show-footer="true" top="10vh" @close="$Method.onClose">
3
3
  <div class="comp-role-menu">
4
- <TTree :data="$Data.menuTreeData" node-key="id" show-checkbox default-expand-all :props="{ label: 'name' }" :ref="(el) => ($From.tree = el)" />
4
+ <TTree v-model:value="$Data.menuTreeCheckedKeys" :data="$Data.menuTreeData" value-mode="all" :keys="{ value: 'id', label: 'name', children: 'children' }" checkable expand-all />
5
5
  </div>
6
6
  <template #footer>
7
7
  <TButton @click="$Method.onClose">取消</TButton>
8
- <TButton theme="primary" @click="$Method.onSubmit">保存</TButton>
8
+ <TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">保存</TButton>
9
9
  </template>
10
10
  </TDialog>
11
11
  </template>
12
12
 
13
13
  <script setup>
14
- import { nextTick } from 'vue';
15
14
  import { Dialog as TDialog, Tree as TTree, Button as TButton, MessagePlugin } from 'tdesign-vue-next';
16
15
  import { arrayToTree } from '@/utils';
17
16
  import { $Http } from '@/plugins/http';
@@ -29,13 +28,9 @@ const $Prop = defineProps({
29
28
 
30
29
  const $Emit = defineEmits(['update:modelValue', 'success']);
31
30
 
32
- // 表单引用
33
- const $From = $shallowRef({
34
- tree: null
35
- });
36
-
37
31
  const $Data = $ref({
38
32
  visible: false,
33
+ submitting: false,
39
34
  menuTreeData: [],
40
35
  menuTreeCheckedKeys: []
41
36
  });
@@ -69,7 +64,7 @@ const $Method = {
69
64
  $Data.menuTreeData = arrayToTree(menuList);
70
65
  } catch (error) {
71
66
  console.error('加载菜单失败:', error);
72
- MessagePlugin.info({ message: '加载菜单失败', status: 'error' });
67
+ MessagePlugin.error('加载菜单失败');
73
68
  }
74
69
  },
75
70
 
@@ -84,13 +79,6 @@ const $Method = {
84
79
 
85
80
  // roleMenuDetail 返回的 data 直接就是菜单 ID 数组
86
81
  $Data.menuTreeCheckedKeys = Array.isArray(res.data) ? res.data : [];
87
-
88
- // 等待树渲染完成后设置选中状态
89
- nextTick(() => {
90
- if ($From.tree && $Data.menuTreeCheckedKeys.length > 0) {
91
- $From.tree.setCheckedKeys($Data.menuTreeCheckedKeys);
92
- }
93
- });
94
82
  } catch (error) {
95
83
  console.error('加载角色菜单失败:', error);
96
84
  }
@@ -99,40 +87,25 @@ const $Method = {
99
87
  // 提交表单
100
88
  async onSubmit() {
101
89
  try {
102
- if (!$From.tree) {
103
- MessagePlugin.info({ message: '菜单树未初始化', status: 'error' });
104
- return;
105
- }
106
-
107
- // 获取选中的节点(包括半选中的父节点)
108
- const checkedKeys = $From.tree.getCheckedKeys();
109
- const halfCheckedKeys = $From.tree.getHalfCheckedKeys();
110
- const menuIds = [...checkedKeys, ...halfCheckedKeys];
90
+ $Data.submitting = true;
111
91
 
112
92
  const res = await $Http('/addon/admin/role/menuSave', {
113
93
  roleId: $Prop.rowData.id,
114
- menuIds
94
+ menuIds: $Data.menuTreeCheckedKeys
115
95
  });
116
96
 
117
97
  if (res.code === 0) {
118
- MessagePlugin.info({
119
- message: '保存成功',
120
- status: 'success'
121
- });
98
+ MessagePlugin.success('保存成功');
122
99
  $Data.visible = false;
123
100
  $Emit('success');
124
101
  } else {
125
- MessagePlugin.info({
126
- message: res.msg || '保存失败',
127
- status: 'error'
128
- });
102
+ MessagePlugin.error(res.msg || '保存失败');
129
103
  }
130
104
  } catch (error) {
131
105
  console.error('保存失败:', error);
132
- MessagePlugin.info({
133
- message: '保存失败',
134
- status: 'error'
135
- });
106
+ MessagePlugin.error('保存失败');
107
+ } finally {
108
+ $Data.submitting = false;
136
109
  }
137
110
  }
138
111
  };
@@ -0,0 +1,227 @@
1
+ <template>
2
+ <div class="page-role page-table">
3
+ <div class="main-tool">
4
+ <div class="left">
5
+ <TButton theme="primary" @click="$Method.onAction('add', {})">
6
+ <template #icon>
7
+ <ILucidePlus />
8
+ </template>
9
+ </TButton>
10
+ </div>
11
+ <div class="right">
12
+ <TButton shape="circle" @click="$Method.handleRefresh">
13
+ <template #icon>
14
+ <ILucideRotateCw />
15
+ </template>
16
+ </TButton>
17
+ </div>
18
+ </div>
19
+ <div class="main-content">
20
+ <div class="main-table">
21
+ <TTable :data="$Data.tableData" :columns="$Data.columns" :loading="$Data.loading" :active-row-keys="$Data.activeRowKeys" row-key="id" height="calc(100vh - 94px)" active-row-type="single" @active-change="$Method.onActiveChange">
22
+ <template #state="{ row }">
23
+ <TTag v-if="row.state === 1" shape="round" theme="success" variant="light-outline">正常</TTag>
24
+ <TTag v-else-if="row.state === 2" shape="round" theme="warning" variant="light-outline">禁用</TTag>
25
+ <TTag v-else shape="round" theme="danger" variant="light-outline">已删除</TTag>
26
+ </template>
27
+ <template #operation="{ row }">
28
+ <TDropdown trigger="click" placement="bottom-right" @click="(data) => $Method.onAction(data.value, row)">
29
+ <TButton theme="primary" size="small">
30
+ 操作
31
+ <template #suffix> <t-icon name="chevron-down" size="16" /></template>
32
+ </TButton>
33
+ <TDropdownMenu slot="dropdown">
34
+ <TDropdownItem value="upd">
35
+ <ILucidePencil />
36
+ 编辑
37
+ </TDropdownItem>
38
+ <TDropdownItem value="menu">
39
+ <ILucideSettings />
40
+ 菜单权限
41
+ </TDropdownItem>
42
+ <TDropdownItem value="api">
43
+ <ILucideCode />
44
+ 接口权限
45
+ </TDropdownItem>
46
+ <TDropdownItem value="del" :divider="true">
47
+ <ILucideTrash2 style="width: 14px; height: 14px; margin-right: 6px" />
48
+ 删除
49
+ </TDropdownItem>
50
+ </TDropdownMenu>
51
+ </TDropdown>
52
+ </template>
53
+ </TTable>
54
+ </div>
55
+
56
+ <div class="main-detail">
57
+ <DetailPanel :data="$Data.currentRow" :fields="$Data.columns" />
58
+ </div>
59
+ </div>
60
+
61
+ <div class="main-page">
62
+ <TPagination :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.limit" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @page-size-change="$Method.handleSizeChange" />
63
+ </div>
64
+
65
+ <!-- 编辑对话框组件 -->
66
+ <EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="$Method.apiRoleList" />
67
+
68
+ <!-- 菜单权限对话框组件 -->
69
+ <MenuDialog v-if="$Data.menuVisible" v-model="$Data.menuVisible" :row-data="$Data.rowData" @success="$Method.apiRoleList" />
70
+
71
+ <!-- 接口权限对话框组件 -->
72
+ <ApiDialog v-if="$Data.apiVisible" v-model="$Data.apiVisible" :row-data="$Data.rowData" @success="$Method.apiRoleList" />
73
+ </div>
74
+ </template>
75
+
76
+ <script setup>
77
+ import { Button as TButton, Table as TTable, Tag as TTag, Dropdown as TDropdown, DropdownMenu as TDropdownMenu, DropdownItem as TDropdownItem, Pagination as TPagination, MessagePlugin, DialogPlugin } from 'tdesign-vue-next';
78
+ import ILucidePlus from '~icons/lucide/plus';
79
+ import ILucideRotateCw from '~icons/lucide/rotate-cw';
80
+ import ILucidePencil from '~icons/lucide/pencil';
81
+ import ILucideSettings from '~icons/lucide/settings';
82
+ import ILucideCode from '~icons/lucide/code';
83
+ import ILucideTrash2 from '~icons/lucide/trash-2';
84
+ import EditDialog from './components/edit.vue';
85
+ import MenuDialog from './components/menu.vue';
86
+ import ApiDialog from './components/api.vue';
87
+ import DetailPanel from '@/components/DetailPanel.vue';
88
+ import { $Http } from '@/plugins/http';
89
+ import { withDefaultColumns } from '@/utils';
90
+
91
+ // 响应式数据
92
+ const $Data = $ref({
93
+ tableData: [],
94
+ loading: false,
95
+ activeRowKeys: [],
96
+ currentRow: null,
97
+ columns: withDefaultColumns([
98
+ { colKey: 'id', title: 'ID' },
99
+ { colKey: 'name', title: '角色名称' },
100
+ { colKey: 'code', title: '角色代码' },
101
+ { colKey: 'description', title: '描述' },
102
+ { colKey: 'sort', title: '排序' },
103
+ { colKey: 'state', title: '状态' },
104
+ { colKey: 'operation', title: '操作' }
105
+ ]),
106
+ pagerConfig: {
107
+ currentPage: 1,
108
+ limit: 30,
109
+ total: 0,
110
+ align: 'right',
111
+ layout: 'total, prev, pager, next, jumper'
112
+ },
113
+ editVisible: false,
114
+ menuVisible: false,
115
+ apiVisible: false,
116
+ actionType: 'add',
117
+ rowData: {}
118
+ });
119
+
120
+ // 方法
121
+ const $Method = {
122
+ async initData() {
123
+ await $Method.apiRoleList();
124
+ },
125
+ // 加载角色列表
126
+ async apiRoleList() {
127
+ $Data.loading = true;
128
+ try {
129
+ const res = await $Http('/addon/admin/role/list', {
130
+ page: $Data.pagerConfig.currentPage,
131
+ limit: $Data.pagerConfig.limit
132
+ });
133
+ $Data.tableData = res.data.lists || [];
134
+ $Data.pagerConfig.total = res.data.total || 0;
135
+
136
+ // 自动选中并高亮第一行
137
+ if ($Data.tableData.length > 0) {
138
+ $Data.currentRow = $Data.tableData[0];
139
+ $Data.activeRowKeys = [$Data.tableData[0].id];
140
+ } else {
141
+ $Data.currentRow = null;
142
+ $Data.activeRowKeys = [];
143
+ }
144
+ } catch (error) {
145
+ console.error('加载角色列表失败:', error);
146
+ MessagePlugin.error('加载数据失败');
147
+ } finally {
148
+ $Data.loading = false;
149
+ }
150
+ },
151
+
152
+ // 删除角色
153
+ async apiRoleDel(row) {
154
+ DialogPlugin.confirm({
155
+ header: '确认删除',
156
+ body: `确定要删除角色“${row.name}” 吗?`,
157
+ status: 'warning'
158
+ }).then(async () => {
159
+ try {
160
+ const res = await $Http('/addon/admin/role/del', { id: row.id });
161
+ if (res.code === 0) {
162
+ MessagePlugin.success('删除成功');
163
+ $Method.apiRoleList();
164
+ } else {
165
+ MessagePlugin.error(res.msg || '删除失败');
166
+ }
167
+ } catch (error) {
168
+ console.error('删除失败:', error);
169
+ MessagePlugin.error('删除失败');
170
+ }
171
+ });
172
+ },
173
+
174
+ // 刷新
175
+ handleRefresh() {
176
+ $Method.apiRoleList();
177
+ },
178
+
179
+ // 分页改变
180
+ onPageChange({ currentPage }) {
181
+ $Data.pagerConfig.currentPage = currentPage;
182
+ $Method.apiRoleList();
183
+ },
184
+
185
+ // 每页条数改变
186
+ handleSizeChange({ pageSize }) {
187
+ $Data.pagerConfig.limit = pageSize;
188
+ $Data.pagerConfig.currentPage = 1;
189
+ $Method.apiRoleList();
190
+ },
191
+
192
+ // 高亮行变化
193
+ onActiveChange(value, context) {
194
+ // 禁止取消高亮:如果新值为空,保持当前选中
195
+ if (value.length === 0 && $Data.activeRowKeys.length > 0) {
196
+ return;
197
+ }
198
+ $Data.activeRowKeys = value;
199
+ // 更新当前高亮的行数据
200
+ if (context.activeRowList && context.activeRowList.length > 0) {
201
+ $Data.currentRow = context.activeRowList[0].row;
202
+ }
203
+ },
204
+
205
+ // 操作菜单点击
206
+ onAction(command, rowData) {
207
+ $Data.actionType = command;
208
+ $Data.rowData = rowData;
209
+ if (command === 'add' || command === 'upd') {
210
+ $Data.editVisible = true;
211
+ } else if (command === 'menu') {
212
+ $Data.menuVisible = true;
213
+ } else if (command === 'api') {
214
+ $Data.apiVisible = true;
215
+ } else if (command === 'del') {
216
+ $Method.apiRoleDel(rowData);
217
+ }
218
+ }
219
+ };
220
+
221
+ $Method.initData();
222
+ </script>
223
+
224
+ <style scoped lang="scss">
225
+ .page-role {
226
+ }
227
+ </style>
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "角色管理",
3
+ "order": 1
4
+ }
package/apis/menu/del.ts DELETED
@@ -1,31 +0,0 @@
1
- export default {
2
- name: '删除菜单',
3
- handler: async (befly, ctx) => {
4
- try {
5
- // 检查是否有子菜单(使用 getList 代替 getAll)
6
- const childrenList = await befly.db.getList({
7
- table: 'addon_admin_menu',
8
- where: { pid: ctx.body.id }
9
- });
10
-
11
- if (childrenList.total > 0) {
12
- return befly.tool.No('该菜单下有子菜单,无法删除');
13
- }
14
-
15
- // 删除菜单
16
- await befly.db.delData({
17
- table: 'addon_admin_menu',
18
- where: { id: ctx.body.id }
19
- });
20
-
21
- // 注意:菜单权限现在存储在 role.menus 字段中
22
- // 如果需要从角色权限中移除此菜单,需要额外处理
23
- // 这里暂时不处理,由管理员在角色管理界面手动调整
24
-
25
- return befly.tool.Yes('操作成功');
26
- } catch (error) {
27
- befly.logger.error('删除菜单失败:', error);
28
- return befly.tool.No('操作失败');
29
- }
30
- }
31
- };
package/apis/menu/ins.ts DELETED
@@ -1,19 +0,0 @@
1
- import adminMenuTable from '../../tables/menu.json';
2
-
3
- export default {
4
- name: '创建菜单',
5
- fields: adminMenuTable,
6
- handler: async (befly, ctx) => {
7
- try {
8
- const menuId = await befly.db.insData({
9
- table: 'addon_admin_menu',
10
- data: ctx.body
11
- });
12
-
13
- return befly.tool.Yes('操作成功', { id: menuId });
14
- } catch (error) {
15
- befly.logger.error('创建菜单失败:', error);
16
- return befly.tool.No('操作失败');
17
- }
18
- }
19
- };
package/apis/menu/upd.ts DELETED
@@ -1,27 +0,0 @@
1
- import adminMenuTable from '../../tables/menu.json';
2
-
3
- export default {
4
- name: '更新菜单',
5
- fields: adminMenuTable,
6
- handler: async (befly, ctx) => {
7
- try {
8
- await befly.db.updData({
9
- table: 'addon_admin_menu',
10
- where: { id: ctx.body.id },
11
- data: {
12
- name: ctx.body.name,
13
- path: ctx.body.path,
14
- icon: ctx.body.icon,
15
- sort: ctx.body.sort,
16
- pid: ctx.body.pid
17
- // state 字段不在此处更新,需要禁用/启用时单独处理
18
- }
19
- });
20
-
21
- return befly.tool.Yes('操作成功');
22
- } catch (error) {
23
- befly.logger.error('更新菜单失败:', error);
24
- return befly.tool.No('操作失败');
25
- }
26
- }
27
- };