befly-admin 3.0.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 (57) hide show
  1. package/.env.development +4 -0
  2. package/.env.production +4 -0
  3. package/LICENSE +201 -0
  4. package/README.md +143 -0
  5. package/index.html +13 -0
  6. package/libs/auto-routes-template.js +104 -0
  7. package/libs/autoRouter.ts +67 -0
  8. package/libs/icons.ts +543 -0
  9. package/package.json +42 -0
  10. package/public/logo.svg +106 -0
  11. package/src/App.vue +17 -0
  12. package/src/api/auth.ts +60 -0
  13. package/src/components/Icon.vue +41 -0
  14. package/src/env.d.ts +9 -0
  15. package/src/layouts/0.vue +207 -0
  16. package/src/layouts/1.vue +22 -0
  17. package/src/layouts/2.vue +166 -0
  18. package/src/main.ts +19 -0
  19. package/src/plugins/http.ts +94 -0
  20. package/src/plugins/router.ts +47 -0
  21. package/src/plugins/store.ts +19 -0
  22. package/src/styles/index.scss +198 -0
  23. package/src/styles/mixins.scss +98 -0
  24. package/src/styles/variables.scss +75 -0
  25. package/src/types/env.d.ts +23 -0
  26. package/src/util.ts +28 -0
  27. package/src/views/403/403.vue +33 -0
  28. package/src/views/admin/components/edit.vue +147 -0
  29. package/src/views/admin/components/role.vue +135 -0
  30. package/src/views/admin/index.vue +169 -0
  31. package/src/views/dict/components/edit.vue +156 -0
  32. package/src/views/dict/index.vue +159 -0
  33. package/src/views/index/components/AddonList.vue +125 -0
  34. package/src/views/index/components/EnvironmentInfo.vue +97 -0
  35. package/src/views/index/components/OperationLogs.vue +112 -0
  36. package/src/views/index/components/PerformanceMetrics.vue +148 -0
  37. package/src/views/index/components/QuickActions.vue +27 -0
  38. package/src/views/index/components/ServiceStatus.vue +193 -0
  39. package/src/views/index/components/SystemNotifications.vue +136 -0
  40. package/src/views/index/components/SystemOverview.vue +188 -0
  41. package/src/views/index/components/SystemResources.vue +104 -0
  42. package/src/views/index/components/UserInfo.vue +136 -0
  43. package/src/views/index/index.vue +62 -0
  44. package/src/views/login/index_1.vue +694 -0
  45. package/src/views/menu/components/edit.vue +150 -0
  46. package/src/views/menu/index.vue +168 -0
  47. package/src/views/news/detail/detail_2.vue +26 -0
  48. package/src/views/news/detail/index.vue +26 -0
  49. package/src/views/news/news.vue +26 -0
  50. package/src/views/role/components/api.vue +280 -0
  51. package/src/views/role/components/edit.vue +129 -0
  52. package/src/views/role/components/menu.vue +143 -0
  53. package/src/views/role/index.vue +179 -0
  54. package/src/views/user/user.vue +320 -0
  55. package/temp/router.js +71 -0
  56. package/tsconfig.json +34 -0
  57. package/vite.config.ts +100 -0
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <tiny-dialog-box v-model:visible="$Data.visible" title="分配角色" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="20vh" @close="$Method.onClose">
3
+ <div class="role-dialog">
4
+ <div class="user-info">
5
+ <tiny-tag type="info">{{ $Prop.rowData.username }}</tiny-tag>
6
+ <span class="user-email">{{ $Prop.rowData.email }}</span>
7
+ </div>
8
+ <tiny-divider />
9
+ <tiny-select v-model="$Data.checkedRoleCode" :options="$Data.roleOptions" placeholder="请选择角色" />
10
+ </div>
11
+ <template #footer>
12
+ <tiny-button @click="$Method.onClose">取消</tiny-button>
13
+ <tiny-button type="primary" @click="$Method.onSubmit">确定</tiny-button>
14
+ </template>
15
+ </tiny-dialog-box>
16
+ </template>
17
+
18
+ <script setup>
19
+ const $Prop = defineProps({
20
+ modelValue: {
21
+ type: Boolean,
22
+ default: false
23
+ },
24
+ rowData: {
25
+ type: Object,
26
+ default: {}
27
+ }
28
+ });
29
+
30
+ const $Emit = defineEmits(['update:modelValue', 'success']);
31
+
32
+ const $Data = $ref({
33
+ visible: false,
34
+ roleOptions: [],
35
+ checkedRoleCode: ''
36
+ });
37
+
38
+ // 方法集合
39
+ const $Method = {
40
+ async initData() {
41
+ $Method.onShow();
42
+ await Promise.all([$Method.apiRoleList(), $Method.apiAdminRoleDetail()]);
43
+ },
44
+
45
+ onShow() {
46
+ setTimeout(() => {
47
+ $Data.visible = $Prop.modelValue;
48
+ }, 100);
49
+ },
50
+
51
+ onClose() {
52
+ $Data.visible = false;
53
+ setTimeout(() => {
54
+ $Emit('update:modelValue', false);
55
+ }, 300);
56
+ },
57
+
58
+ // 加载角色列表
59
+ async apiRoleList() {
60
+ try {
61
+ const res = await $Http('/addon/admin/roleList', {
62
+ page: 1,
63
+ limit: 1000
64
+ });
65
+ const roleList = res.data.lists || [];
66
+ $Data.roleOptions = roleList
67
+ .filter((role) => role.state === 1)
68
+ .map((role) => ({
69
+ label: role.name,
70
+ value: role.code
71
+ }));
72
+ } catch (error) {
73
+ console.error('加载角色列表失败:', error);
74
+ Modal.message({ message: '加载角色列表失败', status: 'error' });
75
+ }
76
+ },
77
+
78
+ // 加载管理员角色
79
+ async apiAdminRoleDetail() {
80
+ if (!$Prop.rowData.id) return;
81
+
82
+ try {
83
+ const res = await $Http('/addon/admin/adminRoleDetail', {
84
+ adminId: $Prop.rowData.id
85
+ });
86
+ $Data.checkedRoleCode = res.data.roleCode || '';
87
+ } catch (error) {
88
+ console.error('加载用户角色失败:', error);
89
+ }
90
+ },
91
+
92
+ // 提交角色分配
93
+ async onSubmit() {
94
+ if (!$Data.checkedRoleCode) {
95
+ Modal.message({ message: '请选择角色', status: 'warning' });
96
+ return;
97
+ }
98
+
99
+ try {
100
+ const res = await $Http('/addon/admin/adminRoleSave', {
101
+ adminId: $Prop.rowData.id,
102
+ roleCode: $Data.checkedRoleCode
103
+ });
104
+
105
+ if (res.code === 0) {
106
+ Modal.message({ message: '角色分配成功', status: 'success' });
107
+ $Method.onClose();
108
+ $Emit('success');
109
+ } else {
110
+ Modal.message({ message: res.msg || '分配失败', status: 'error' });
111
+ }
112
+ } catch (error) {
113
+ console.error('分配失败:', error);
114
+ Modal.message({ message: '分配失败', status: 'error' });
115
+ }
116
+ }
117
+ };
118
+
119
+ $Method.initData();
120
+ </script>
121
+
122
+ <style scoped lang="scss">
123
+ .role-dialog {
124
+ .user-info {
125
+ display: flex;
126
+ align-items: center;
127
+ gap: 12px;
128
+ margin-bottom: 16px;
129
+
130
+ .user-email {
131
+ color: $text-secondary;
132
+ }
133
+ }
134
+ }
135
+ </style>
@@ -0,0 +1,169 @@
1
+ <template>
2
+ <div class="page-admin page-table">
3
+ <div class="main-tool">
4
+ <div class="left">
5
+ <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
+ <template #icon>
7
+ <Icon name="Plus" :size="16" />
8
+ </template>
9
+ 添加管理员
10
+ </tiny-button>
11
+ </div>
12
+ <div class="right">
13
+ <tiny-button @click="$Method.handleRefresh">
14
+ <template #icon>
15
+ <Icon name="RotateCw" :size="16" />
16
+ </template>
17
+ 刷新
18
+ </tiny-button>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="main-table">
23
+ <tiny-grid :data="$Data.tableData" header-cell-class-name="custom-table-cell-class" size="small" height="100%" seq-serial>
24
+ <tiny-grid-column type="index" title="序号" :width="60" />
25
+ <tiny-grid-column field="username" title="用户名" />
26
+ <tiny-grid-column field="email" title="邮箱" :width="200" />
27
+ <tiny-grid-column field="nickname" title="昵称" :width="150" />
28
+ <tiny-grid-column field="roleCode" title="角色" :width="120" />
29
+ <tiny-grid-column field="state" title="状态" :width="100">
30
+ <template #default="{ row }">
31
+ <tiny-tag v-if="row.state === 1" type="success">正常</tiny-tag>
32
+ <tiny-tag v-else-if="row.state === 2" type="warning">禁用</tiny-tag>
33
+ <tiny-tag v-else type="danger">已删除</tiny-tag>
34
+ </template>
35
+ </tiny-grid-column>
36
+ <tiny-grid-column title="操作" :width="120" align="right">
37
+ <template #default="{ row }">
38
+ <tiny-dropdown title="操作" trigger="click" size="small" border visible-arrow @item-click="(data) => $Method.onAction(data.itemData.command, row)">
39
+ <template #dropdown>
40
+ <tiny-dropdown-menu>
41
+ <tiny-dropdown-item :item-data="{ command: 'role' }">
42
+ <Icon name="User" />
43
+ 分配角色
44
+ </tiny-dropdown-item>
45
+ <tiny-dropdown-item :item-data="{ command: 'upd' }">
46
+ <Icon name="Edit" />
47
+ 编辑
48
+ </tiny-dropdown-item>
49
+ <tiny-dropdown-item :item-data="{ command: 'del' }" divided>
50
+ <Icon name="Trash2" />
51
+ 删除
52
+ </tiny-dropdown-item>
53
+ </tiny-dropdown-menu>
54
+ </template>
55
+ </tiny-dropdown>
56
+ </template>
57
+ </tiny-grid-column>
58
+ </tiny-grid>
59
+ </div>
60
+
61
+ <div class="main-page">
62
+ <tiny-pager :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.pageSize" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @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.apiAdminList" />
67
+
68
+ <!-- 角色分配对话框组件 -->
69
+ <RoleDialog v-if="$Data.roleVisible" v-model="$Data.roleVisible" :row-data="$Data.rowData" @success="$Method.apiAdminList" />
70
+ </div>
71
+ </template>
72
+
73
+ <script setup>
74
+ import EditDialog from './components/edit.vue';
75
+ import RoleDialog from './components/role.vue';
76
+
77
+ // 响应式数据
78
+ const $Data = $ref({
79
+ tableData: [],
80
+ pagerConfig: {
81
+ currentPage: 1,
82
+ pageSize: 30,
83
+ total: 0,
84
+ align: 'right',
85
+ layout: 'total, prev, pager, next, jumper'
86
+ },
87
+ editVisible: false,
88
+ roleVisible: false,
89
+ actionType: 'add',
90
+ rowData: {}
91
+ });
92
+
93
+ // 方法
94
+ const $Method = {
95
+ async initData() {
96
+ await $Method.apiAdminList();
97
+ },
98
+
99
+ // 加载管理员列表
100
+ async apiAdminList() {
101
+ try {
102
+ const res = await $Http('/addon/admin/adminList', {
103
+ page: $Data.pagerConfig.currentPage,
104
+ limit: $Data.pagerConfig.pageSize
105
+ });
106
+ $Data.tableData = res.data.lists || [];
107
+ $Data.pagerConfig.total = res.data.total || 0;
108
+ } catch (error) {
109
+ console.error('加载管理员列表失败:', error);
110
+ Modal.message({
111
+ message: '加载数据失败',
112
+ status: 'error'
113
+ });
114
+ }
115
+ },
116
+
117
+ // 删除管理员
118
+ async apiAdminDel(row) {
119
+ Modal.confirm({
120
+ header: '确认删除',
121
+ body: `确定要删除管理员"${row.username}" 吗?`,
122
+ status: 'warning'
123
+ }).then(async () => {
124
+ try {
125
+ const res = await $Http('/addon/admin/adminDel', { id: row.id });
126
+ if (res.code === 0) {
127
+ Modal.message({ message: '删除成功', status: 'success' });
128
+ $Method.apiAdminList();
129
+ } else {
130
+ Modal.message({ message: res.msg || '删除失败', status: 'error' });
131
+ }
132
+ } catch (error) {
133
+ console.error('删除失败:', error);
134
+ Modal.message({ message: '删除失败', status: 'error' });
135
+ }
136
+ });
137
+ },
138
+
139
+ // 刷新
140
+ handleRefresh() {
141
+ $Method.apiAdminList();
142
+ },
143
+
144
+ // 分页改变
145
+ onPageChange({ currentPage }) {
146
+ $Data.pagerConfig.currentPage = currentPage;
147
+ $Method.apiAdminList();
148
+ },
149
+
150
+ // 操作菜单点击
151
+ onAction(command, rowData) {
152
+ $Data.actionType = command;
153
+ $Data.rowData = rowData;
154
+ if (command === 'add' || command === 'upd') {
155
+ $Data.editVisible = true;
156
+ } else if (command === 'role') {
157
+ $Data.roleVisible = true;
158
+ } else if (command === 'del') {
159
+ $Method.apiAdminDel(rowData);
160
+ }
161
+ }
162
+ };
163
+
164
+ $Method.initData();
165
+ </script>
166
+
167
+ <style scoped lang="scss">
168
+ // 样式继承自全局 page-table
169
+ </style>
@@ -0,0 +1,156 @@
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
+ <tiny-form :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($Form.form = el)">
4
+ <tiny-form-item label="字典名称" prop="name">
5
+ <tiny-input v-model="$Data.formData.name" placeholder="请输入字典名称" />
6
+ </tiny-form-item>
7
+ <tiny-form-item label="字典代码" prop="code">
8
+ <tiny-input v-model="$Data.formData.code" placeholder="请输入字典代码,如:gender" />
9
+ </tiny-form-item>
10
+ <tiny-form-item label="字典值" prop="value">
11
+ <tiny-input v-model="$Data.formData.value" placeholder="请输入字典值" />
12
+ </tiny-form-item>
13
+ <tiny-form-item label="父级ID" prop="pid">
14
+ <tiny-numeric v-model="$Data.formData.pid" :min="0" :max="999999999999999" />
15
+ </tiny-form-item>
16
+ <tiny-form-item label="排序" prop="sort">
17
+ <tiny-numeric v-model="$Data.formData.sort" :min="0" :max="9999" />
18
+ </tiny-form-item>
19
+ <tiny-form-item label="描述" prop="description">
20
+ <tiny-input v-model="$Data.formData.description" type="textarea" placeholder="请输入描述" :rows="3" />
21
+ </tiny-form-item>
22
+ <tiny-form-item label="状态" prop="state">
23
+ <tiny-radio-group v-model="$Data.formData.state">
24
+ <tiny-radio :label="1">正常</tiny-radio>
25
+ <tiny-radio :label="2">禁用</tiny-radio>
26
+ </tiny-radio-group>
27
+ </tiny-form-item>
28
+ </tiny-form>
29
+ <template #footer>
30
+ <tiny-button @click="$Method.onClose">取消</tiny-button>
31
+ <tiny-button type="primary" @click="$Method.onSubmit">确定</tiny-button>
32
+ </template>
33
+ </tiny-dialog-box>
34
+ </template>
35
+
36
+ <script setup>
37
+ const $Prop = defineProps({
38
+ modelValue: {
39
+ type: Boolean,
40
+ default: false
41
+ },
42
+ actionType: {
43
+ type: String,
44
+ default: 'add'
45
+ },
46
+ rowData: {
47
+ type: Object,
48
+ default: {}
49
+ }
50
+ });
51
+
52
+ const $Emit = defineEmits(['update:modelValue', 'success']);
53
+
54
+ // 表单引用
55
+ const $Form = $shallowRef({
56
+ form: null
57
+ });
58
+
59
+ const $Data = $ref({
60
+ visible: false,
61
+ formData: {
62
+ id: 0,
63
+ name: '',
64
+ code: '',
65
+ value: '',
66
+ pid: 0,
67
+ sort: 0,
68
+ description: '',
69
+ state: 1
70
+ }
71
+ });
72
+
73
+ const $Data2 = $shallowRef({
74
+ formRules: {
75
+ name: [{ required: true, message: '请输入字典名称', trigger: 'blur' }],
76
+ code: [
77
+ { required: true, message: '请输入字典代码', trigger: 'blur' },
78
+ { pattern: /^[a-zA-Z0-9_]+$/, message: '字典代码只能包含字母、数字和下划线', trigger: 'blur' }
79
+ ],
80
+ value: [{ required: true, message: '请输入字典值', trigger: 'blur' }]
81
+ }
82
+ });
83
+
84
+ // 方法集合
85
+ const $Method = {
86
+ async initData() {
87
+ $Method.onShow();
88
+ },
89
+
90
+ onShow() {
91
+ $Data.visible = true;
92
+ if ($Prop.actionType === 'upd' && $Prop.rowData) {
93
+ $Data.formData.id = $Prop.rowData.id || 0;
94
+ $Data.formData.name = $Prop.rowData.name || '';
95
+ $Data.formData.code = $Prop.rowData.code || '';
96
+ $Data.formData.value = $Prop.rowData.value || '';
97
+ $Data.formData.pid = $Prop.rowData.pid || 0;
98
+ $Data.formData.sort = $Prop.rowData.sort || 0;
99
+ $Data.formData.description = $Prop.rowData.description || '';
100
+ $Data.formData.state = $Prop.rowData.state ?? 1;
101
+ } else {
102
+ // 重置表单
103
+ $Data.formData.id = 0;
104
+ $Data.formData.name = '';
105
+ $Data.formData.code = '';
106
+ $Data.formData.value = '';
107
+ $Data.formData.pid = 0;
108
+ $Data.formData.sort = 0;
109
+ $Data.formData.description = '';
110
+ $Data.formData.state = 1;
111
+ }
112
+ },
113
+
114
+ onClose() {
115
+ $Data.visible = false;
116
+ setTimeout(() => {
117
+ $Emit('update:modelValue', false);
118
+ }, 300);
119
+ },
120
+
121
+ async onSubmit() {
122
+ try {
123
+ const valid = await $Form.form.validate();
124
+ if (!valid) return;
125
+
126
+ const res = await $Http($Prop.actionType === 'add' ? '/addon/admin/dictIns' : '/addon/admin/dictUpd', $Data.formData);
127
+
128
+ Modal.message({
129
+ message: $Prop.actionType === 'add' ? '添加成功' : '编辑成功',
130
+ status: 'success'
131
+ });
132
+ $Method.onClose();
133
+ $Emit('success');
134
+ } catch (error) {
135
+ console.error('提交失败:', error);
136
+ }
137
+ }
138
+ };
139
+
140
+ // 监听 modelValue 变化
141
+ watch(
142
+ () => $Prop.modelValue,
143
+ (val) => {
144
+ if (val && !$Data.visible) {
145
+ $Method.initData();
146
+ } else if (!val && $Data.visible) {
147
+ $Data.visible = false;
148
+ }
149
+ },
150
+ { immediate: true }
151
+ );
152
+ </script>
153
+
154
+ <style scoped lang="scss">
155
+ // 可根据需要添加样式
156
+ </style>
@@ -0,0 +1,159 @@
1
+ <template>
2
+ <div class="page-dict page-table">
3
+ <div class="main-tool">
4
+ <div class="left">
5
+ <tiny-button type="primary" @click="$Method.onAction('add', {})">
6
+ <template #icon>
7
+ <Icon name="Plus" :size="16" />
8
+ </template>
9
+ 添加字典
10
+ </tiny-button>
11
+ </div>
12
+ <div class="right">
13
+ <tiny-button @click="$Method.handleRefresh">
14
+ <template #icon>
15
+ <Icon name="RotateCw" :size="16" />
16
+ </template>
17
+ 刷新
18
+ </tiny-button>
19
+ </div>
20
+ </div>
21
+ <div class="main-table">
22
+ <tiny-grid :data="$Data.dictList" header-cell-class-name="custom-table-cell-class" size="small" height="100%" seq-serial>
23
+ <tiny-grid-column type="index" title="序号" :width="60" />
24
+ <tiny-grid-column field="name" title="字典名称" />
25
+ <tiny-grid-column field="code" title="字典代码" :width="150" />
26
+ <tiny-grid-column field="value" title="字典值" :width="200" />
27
+ <tiny-grid-column field="pid" title="父级ID" :width="100" />
28
+ <tiny-grid-column field="sort" title="排序" :width="80" />
29
+ <tiny-grid-column field="description" title="描述" />
30
+ <tiny-grid-column field="state" title="状态" :width="100">
31
+ <template #default="{ row }">
32
+ <tiny-tag v-if="row.state === 1" type="success">正常</tiny-tag>
33
+ <tiny-tag v-else-if="row.state === 2" type="warning">禁用</tiny-tag>
34
+ <tiny-tag v-else type="danger">已删除</tiny-tag>
35
+ </template>
36
+ </tiny-grid-column>
37
+ <tiny-grid-column title="操作" :width="120" align="right">
38
+ <template #default="{ row }">
39
+ <tiny-dropdown title="操作" trigger="click" size="small" border visible-arrow @item-click="(data) => $Method.onAction(data.itemData.command, row)">
40
+ <template #dropdown>
41
+ <tiny-dropdown-menu>
42
+ <tiny-dropdown-item :item-data="{ command: 'upd' }">
43
+ <Icon name="Edit" />
44
+ 编辑
45
+ </tiny-dropdown-item>
46
+ <tiny-dropdown-item :item-data="{ command: 'del' }" divided>
47
+ <Icon name="Trash2" />
48
+ 删除
49
+ </tiny-dropdown-item>
50
+ </tiny-dropdown-menu>
51
+ </template>
52
+ </tiny-dropdown>
53
+ </template>
54
+ </tiny-grid-column>
55
+ </tiny-grid>
56
+ </div>
57
+
58
+ <div class="main-page">
59
+ <tiny-pager :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.pageSize" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @size-change="$Method.handleSizeChange" />
60
+ </div>
61
+
62
+ <!-- 编辑对话框组件 -->
63
+ <EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="$Method.apiDictList" />
64
+ </div>
65
+ </template>
66
+
67
+ <script setup>
68
+ import EditDialog from './components/edit.vue';
69
+
70
+ // 响应式数据
71
+ const $Data = $ref({
72
+ dictList: [],
73
+ pagerConfig: {
74
+ currentPage: 1,
75
+ pageSize: 30,
76
+ total: 0,
77
+ align: 'right',
78
+ layout: 'total, prev, pager, next, jumper'
79
+ },
80
+ editVisible: false,
81
+ actionType: 'add',
82
+ rowData: {}
83
+ });
84
+
85
+ // 方法
86
+ const $Method = {
87
+ async initData() {
88
+ await $Method.apiDictList();
89
+ },
90
+
91
+ // 加载字典列表
92
+ async apiDictList() {
93
+ try {
94
+ const res = await $Http('/addon/admin/dictList', {
95
+ page: $Data.pagerConfig.currentPage,
96
+ limit: $Data.pagerConfig.pageSize
97
+ });
98
+ $Data.dictList = res.data.lists || [];
99
+ $Data.pagerConfig.total = res.data.total || 0;
100
+ } catch (error) {
101
+ console.error('加载字典列表失败:', error);
102
+ Modal.message({
103
+ message: '加载数据失败',
104
+ status: 'error'
105
+ });
106
+ }
107
+ },
108
+
109
+ // 删除字典
110
+ async apiDictDel(row) {
111
+ Modal.confirm({
112
+ header: '确认删除',
113
+ body: `确定要删除字典"${row.name}" 吗?`,
114
+ status: 'warning'
115
+ }).then(async () => {
116
+ try {
117
+ const res = await $Http('/addon/admin/dictDel', { id: row.id });
118
+ if (res.code === 0) {
119
+ Modal.message({ message: '删除成功', status: 'success' });
120
+ $Method.apiDictList();
121
+ } else {
122
+ Modal.message({ message: res.msg || '删除失败', status: 'error' });
123
+ }
124
+ } catch (error) {
125
+ console.error('删除失败:', error);
126
+ Modal.message({ message: '删除失败', status: 'error' });
127
+ }
128
+ });
129
+ },
130
+
131
+ // 刷新
132
+ handleRefresh() {
133
+ $Method.apiDictList();
134
+ },
135
+
136
+ // 分页改变
137
+ onPageChange({ currentPage }) {
138
+ $Data.pagerConfig.currentPage = currentPage;
139
+ $Method.apiDictList();
140
+ },
141
+
142
+ // 操作菜单点击
143
+ onAction(command, rowData) {
144
+ $Data.actionType = command;
145
+ $Data.rowData = rowData;
146
+ if (command === 'add' || command === 'upd') {
147
+ $Data.editVisible = true;
148
+ } else if (command === 'del') {
149
+ $Method.apiDictDel(rowData);
150
+ }
151
+ }
152
+ };
153
+
154
+ $Method.initData();
155
+ </script>
156
+
157
+ <style scoped lang="scss">
158
+ // 样式继承自全局 page-table
159
+ </style>