@befly-addon/admin 1.1.35 → 1.2.0

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 (46) hide show
  1. package/apis/admin/cacheRefresh.ts +2 -2
  2. package/apis/menu/all.ts +8 -9
  3. package/apis/menu/list.ts +1 -2
  4. package/apis/role/apiSave.ts +3 -3
  5. package/apis/role/apis.ts +3 -3
  6. package/apis/role/menuSave.ts +2 -2
  7. package/apis/role/menus.ts +3 -3
  8. package/package.json +21 -21
  9. package/plugins/email.ts +3 -8
  10. package/tables/api.json +1 -20
  11. package/tables/menu.json +6 -11
  12. package/tables/role.json +4 -4
  13. package/views/403_1/index.vue +0 -75
  14. package/views/config/dict/components/edit.vue +0 -109
  15. package/views/config/dict/index.vue +0 -266
  16. package/views/config/dictType/components/edit.vue +0 -100
  17. package/views/config/dictType/index.vue +0 -244
  18. package/views/config/index.vue +0 -12
  19. package/views/config/system/components/edit.vue +0 -171
  20. package/views/config/system/index.vue +0 -286
  21. package/views/index/components/addonList.vue +0 -132
  22. package/views/index/components/environmentInfo.vue +0 -100
  23. package/views/index/components/operationLogs.vue +0 -112
  24. package/views/index/components/performanceMetrics.vue +0 -145
  25. package/views/index/components/quickActions.vue +0 -30
  26. package/views/index/components/serviceStatus.vue +0 -192
  27. package/views/index/components/systemNotifications.vue +0 -137
  28. package/views/index/components/systemOverview.vue +0 -190
  29. package/views/index/components/systemResources.vue +0 -111
  30. package/views/index/components/userInfo.vue +0 -204
  31. package/views/index/index.vue +0 -74
  32. package/views/log/email/index.vue +0 -292
  33. package/views/log/index.vue +0 -12
  34. package/views/log/login/index.vue +0 -187
  35. package/views/log/operate/index.vue +0 -249
  36. package/views/login_1/index.vue +0 -415
  37. package/views/people/admin/components/edit.vue +0 -168
  38. package/views/people/admin/index.vue +0 -240
  39. package/views/people/index.vue +0 -12
  40. package/views/permission/api/index.vue +0 -149
  41. package/views/permission/index.vue +0 -12
  42. package/views/permission/menu/index.vue +0 -128
  43. package/views/permission/role/components/api.vue +0 -261
  44. package/views/permission/role/components/edit.vue +0 -142
  45. package/views/permission/role/components/menu.vue +0 -116
  46. package/views/permission/role/index.vue +0 -263
@@ -1,168 +0,0 @@
1
- <template>
2
- <TDialog v-model:visible="$Data.visible" :header="$Prop.actionType === 'upd' ? '编辑管理员' : '添加管理员'" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="10vh" @close="$Method.onClose">
3
- <div class="dialog-wrapper">
4
- <TForm :model="$Data.formData" label-width="80px" label-position="left" label-align="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
5
- <TFormItem label="角色" prop="roleCode">
6
- <TSelect v-model="$Data.formData.roleCode" :options="$Data.allRoleLists" :keys="$Data.keys" placeholder="请选择角色" />
7
- </TFormItem>
8
- <TFormItem label="用户名" prop="username">
9
- <TInput v-model="$Data.formData.username" placeholder="请输入用户名" :disabled="$Prop.actionType === 'upd'" />
10
- </TFormItem>
11
- <TFormItem v-if="$Prop.actionType === 'add'" label="密码" prop="password">
12
- <TInput v-model="$Data.formData.password" type="password" placeholder="请输入密码,至少6位" />
13
- </TFormItem>
14
- <TFormItem label="昵称" prop="nickname">
15
- <TInput v-model="$Data.formData.nickname" placeholder="请输入昵称" />
16
- </TFormItem>
17
- <TFormItem v-if="$Prop.actionType === 'upd'" label="状态" prop="state">
18
- <TRadioGroup v-model="$Data.formData.state">
19
- <TRadio :label="1">正常</TRadio>
20
- <TRadio :label="2">禁用</TRadio>
21
- </TRadioGroup>
22
- </TFormItem>
23
- </TForm>
24
- </div>
25
- <template #footer>
26
- <div class="dialog-footer">
27
- <t-space>
28
- <TButton theme="default" @click="$Method.onClose">取消</TButton>
29
- <TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">确定</TButton>
30
- </t-space>
31
- </div>
32
- </template>
33
- </TDialog>
34
- </template>
35
-
36
- <script setup>
37
- import {
38
- //
39
- Dialog as TDialog,
40
- Form as TForm,
41
- FormItem as TFormItem,
42
- Input as TInput,
43
- Select as TSelect,
44
- RadioGroup as TRadioGroup,
45
- Radio as TRadio,
46
- Button as TButton,
47
- MessagePlugin
48
- } from "tdesign-vue-next";
49
- import { $Http } from "@/plugins/http";
50
- import { fieldClear } from "befly-vite/utils/fieldClear";
51
- import { hashPassword } from "befly-vite/utils/hashPassword";
52
-
53
- const $Prop = defineProps({
54
- modelValue: {
55
- type: Boolean,
56
- default: false
57
- },
58
- actionType: {
59
- type: String,
60
- default: "add"
61
- },
62
- rowData: {
63
- type: Object,
64
- default: {}
65
- }
66
- });
67
-
68
- const $Emit = defineEmits(["update:modelValue", "success"]);
69
-
70
- // 表单引用
71
- const $From = $shallowRef({
72
- form: null
73
- });
74
-
75
- const $Data = $ref({
76
- visible: false,
77
- submitting: false,
78
- allRoleLists: [],
79
- keys: {
80
- label: "name",
81
- value: "code"
82
- },
83
- formData: {
84
- id: null,
85
- username: "",
86
- password: "",
87
- nickname: "",
88
- roleCode: null,
89
- state: 1
90
- }
91
- });
92
-
93
- const $Data2 = $shallowRef({
94
- formRules: {
95
- username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
96
- password: [
97
- { required: true, message: "请输入密码", trigger: "blur" },
98
- { min: 6, message: "密码至少6位", trigger: "blur" }
99
- ],
100
- roleCode: [{ required: true, message: "请选择角色", trigger: "change" }],
101
- nickname: [{ min: 2, max: 50, message: "昵称长度在 2 到 50 个字符", trigger: "blur" }]
102
- }
103
- });
104
-
105
- // 方法集合
106
- const $Method = {
107
- async initData() {
108
- $Method.onShow();
109
- await $Method.apiRoleLists();
110
- if ($Prop.actionType === "upd" && $Prop.rowData.id) {
111
- $Data.formData = { ...$Prop.rowData };
112
- }
113
- },
114
-
115
- onShow() {
116
- setTimeout(() => {
117
- $Data.visible = $Prop.modelValue;
118
- }, 100);
119
- },
120
-
121
- onClose() {
122
- $Data.visible = false;
123
- setTimeout(() => {
124
- $Emit("update:modelValue", false);
125
- }, 300);
126
- },
127
-
128
- async apiRoleLists() {
129
- try {
130
- const result = await $Http("/addon/admin/role/all");
131
- $Data.allRoleLists = result.data || [];
132
- } catch (error) {
133
- MessagePlugin.error("加载角色列表失败");
134
- }
135
- },
136
-
137
- async onSubmit() {
138
- try {
139
- const valid = await $From.form.validate();
140
- if (!valid) return;
141
-
142
- $Data.submitting = true;
143
- const formData = $Prop.actionType === "add" ? fieldClear($Data.formData, { omitKeys: ["id", "state"] }) : fieldClear($Data.formData, { omitKeys: ["password"] });
144
-
145
- // 添加管理员时,对密码进行 SHA-256 加密
146
- if ($Prop.actionType === "add" && formData.password) {
147
- formData.password = await hashPassword(formData.password);
148
- }
149
-
150
- const result = await $Http($Prop.actionType === "upd" ? "/addon/admin/admin/upd" : "/addon/admin/admin/ins", formData);
151
-
152
- MessagePlugin.success(result.msg);
153
- $Emit("success");
154
- $Method.onClose();
155
- } catch (error) {
156
- MessagePlugin.error(error.msg || "提交失败");
157
- } finally {
158
- $Data.submitting = false;
159
- }
160
- }
161
- };
162
-
163
- $Method.initData();
164
- </script>
165
-
166
- <style scoped lang="scss">
167
- // 可根据需要添加样式
168
- </style>
@@ -1,240 +0,0 @@
1
- <template>
2
- <div class="page-admin 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
-
20
- <div class="main-content">
21
- <div class="main-table">
22
- <TTable
23
- :data="$Data.tableData"
24
- :columns="$Data.columns"
25
- :loading="$Data.loading"
26
- :active-row-keys="$Data.activeRowKeys"
27
- row-key="id"
28
- height="calc(100vh - var(--search-height) - var(--pagination-height) - var(--layout-gap) * 4)"
29
- active-row-type="single"
30
- @active-change="$Method.onActiveChange"
31
- >
32
- <template #state="{ row }">
33
- <TTag v-if="row.state === 1" shape="round" theme="success" variant="light-outline">正常</TTag>
34
- <TTag v-else-if="row.state === 2" shape="round" theme="warning" variant="light-outline">禁用</TTag>
35
- <TTag v-else-if="row.state === 0" shape="round" theme="danger" variant="light-outline">删除</TTag>
36
- </template>
37
- <template #operation="{ row }">
38
- <TDropdown trigger="click" placement="bottom-right" @click="(data) => $Method.onAction(data.value, row)">
39
- <TButton theme="primary" size="small">
40
- 操作
41
- <template #suffix> <ILucideChevronDown /></template>
42
- </TButton>
43
- <TDropdownMenu slot="dropdown">
44
- <TDropdownItem value="upd">
45
- <ILucidePencil />
46
- 编辑
47
- </TDropdownItem>
48
- <TDropdownItem value="del" :divider="true">
49
- <ILucideTrash2 />
50
- 删除
51
- </TDropdownItem>
52
- </TDropdownMenu>
53
- </TDropdown>
54
- </template>
55
- </TTable>
56
- </div>
57
-
58
- <div class="main-detail">
59
- <DetailPanel :data="$Data.currentRow" :fields="$Data.columns" />
60
- </div>
61
- </div>
62
-
63
- <div class="main-page">
64
- <TPagination :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.limit" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @page-size-change="$Method.handleSizeChange" />
65
- </div>
66
-
67
- <!-- 编辑对话框组件 -->
68
- <EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="$Method.apiAdminList" />
69
- </div>
70
- </template>
71
-
72
- <script setup>
73
- 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";
74
- import ILucidePlus from "~icons/lucide/plus";
75
- import ILucideRotateCw from "~icons/lucide/rotate-cw";
76
- import ILucidePencil from "~icons/lucide/pencil";
77
- import ILucideTrash2 from "~icons/lucide/trash-2";
78
- import ILucideChevronDown from "~icons/lucide/chevron-down";
79
- import EditDialog from "./components/edit.vue";
80
- import DetailPanel from "@/components/DetailPanel.vue";
81
- import { $Http } from "@/plugins/http";
82
- import { withDefaultColumns } from "befly-vite/utils/withDefaultColumns";
83
-
84
- definePage({
85
- meta: {
86
- title: "管理员",
87
- order: 1
88
- }
89
- });
90
-
91
- // 响应式数据
92
- const $Data = $ref({
93
- tableData: [],
94
- loading: false,
95
- columns: withDefaultColumns([
96
- { colKey: "username", title: "用户名", fixed: "left" },
97
- { colKey: "id", title: "序号" },
98
- { colKey: "nickname", title: "昵称" },
99
- { colKey: "roleCode", title: "角色" },
100
- { colKey: "state", title: "状态" },
101
- { colKey: "operation", title: "操作" }
102
- ]),
103
- pagerConfig: {
104
- currentPage: 1,
105
- limit: 30,
106
- total: 0,
107
- align: "right",
108
- layout: "total, prev, pager, next, jumper"
109
- },
110
- editVisible: false,
111
- actionType: "add",
112
- rowData: {},
113
- currentRow: null,
114
- activeRowKeys: []
115
- });
116
-
117
- // 方法
118
- const $Method = {
119
- async initData() {
120
- await $Method.apiAdminList();
121
- },
122
-
123
- // 加载管理员列表
124
- async apiAdminList() {
125
- $Data.loading = true;
126
- try {
127
- const res = await $Http("/addon/admin/admin/list", {
128
- page: $Data.pagerConfig.currentPage,
129
- limit: $Data.pagerConfig.limit
130
- });
131
- $Data.tableData = res.data.lists || [];
132
- $Data.pagerConfig.total = res.data.total || 0;
133
-
134
- // 自动高亮第一行
135
- if ($Data.tableData.length > 0) {
136
- $Data.currentRow = $Data.tableData[0];
137
- $Data.activeRowKeys = [$Data.tableData[0].id];
138
- } else {
139
- $Data.currentRow = null;
140
- $Data.activeRowKeys = [];
141
- }
142
- } catch (error) {
143
- MessagePlugin.error("加载数据失败");
144
- } finally {
145
- $Data.loading = false;
146
- }
147
- },
148
-
149
- // 删除管理员
150
- async apiAdminDel(row) {
151
- let dialog = null;
152
- let destroyed = false;
153
-
154
- const destroy = () => {
155
- if (destroyed) return;
156
- destroyed = true;
157
- if (dialog && typeof dialog.destroy === "function") {
158
- dialog.destroy();
159
- }
160
- };
161
-
162
- dialog = DialogPlugin.confirm({
163
- header: "确认删除",
164
- body: `确认删除管理员“${row.username}”吗?`,
165
- status: "warning",
166
- confirmBtn: "删除",
167
- cancelBtn: "取消",
168
- onConfirm: async () => {
169
- if (dialog && typeof dialog.setConfirmLoading === "function") {
170
- dialog.setConfirmLoading(true);
171
- }
172
-
173
- try {
174
- await $Http("/addon/admin/admin/del", { id: row.id });
175
- MessagePlugin.success("删除成功");
176
- destroy();
177
- await $Method.apiAdminList();
178
- } catch (error) {
179
- MessagePlugin.error("删除失败");
180
- } finally {
181
- if (dialog && typeof dialog.setConfirmLoading === "function") {
182
- dialog.setConfirmLoading(false);
183
- }
184
- }
185
- },
186
- onClose: () => {
187
- destroy();
188
- }
189
- });
190
- },
191
-
192
- // 刷新
193
- handleRefresh() {
194
- $Method.apiAdminList();
195
- },
196
-
197
- // 分页改变
198
- onPageChange({ currentPage }) {
199
- $Data.pagerConfig.currentPage = currentPage;
200
- $Method.apiAdminList();
201
- },
202
-
203
- // 每页条数改变
204
- handleSizeChange({ pageSize }) {
205
- $Data.pagerConfig.limit = pageSize;
206
- $Data.pagerConfig.currentPage = 1;
207
- $Method.apiAdminList();
208
- },
209
-
210
- // 高亮行变化
211
- onActiveChange(value, context) {
212
- // 禁止取消高亮:如果新值为空,保持当前选中
213
- if (value.length === 0 && $Data.activeRowKeys.length > 0) {
214
- return;
215
- }
216
- $Data.activeRowKeys = value;
217
- // 更新当前高亮的行数据
218
- if (context.activeRowList && context.activeRowList.length > 0) {
219
- $Data.currentRow = context.activeRowList[0].row;
220
- }
221
- },
222
-
223
- // 操作菜单点击
224
- onAction(command, rowData) {
225
- $Data.actionType = command;
226
- $Data.rowData = rowData;
227
- if (command === "add" || command === "upd") {
228
- $Data.editVisible = true;
229
- } else if (command === "del") {
230
- $Method.apiAdminDel(rowData);
231
- }
232
- }
233
- };
234
-
235
- $Method.initData();
236
- </script>
237
-
238
- <style scoped lang="scss">
239
- // 样式继承自全局 page-table
240
- </style>
@@ -1,12 +0,0 @@
1
- <template>
2
- <RouterView />
3
- </template>
4
-
5
- <script setup>
6
- definePage({
7
- meta: {
8
- title: "人员管理",
9
- order: 10
10
- }
11
- });
12
- </script>
@@ -1,149 +0,0 @@
1
- <template>
2
- <div class="page-api page-table">
3
- <div class="main-tool">
4
- <div class="left">
5
- <TInput v-model="$Data.searchKeyword" placeholder="搜索接口名称或路径" clearable style="width: 300px" @enter="$Method.handleSearch" @clear="$Method.handleSearch">
6
- <template #suffix-icon>
7
- <ILucideSearch />
8
- </template>
9
- </TInput>
10
- <span style="margin-left: 16px; color: var(--text-secondary); font-size: 13px">共 {{ $Data.allData.length }} 个接口</span>
11
- </div>
12
- <div class="right">
13
- <TButton shape="circle" @click="$Method.handleRefresh">
14
- <template #icon>
15
- <ILucideRotateCw />
16
- </template>
17
- </TButton>
18
- </div>
19
- </div>
20
-
21
- <div class="main-content">
22
- <div class="main-table">
23
- <TTable :data="$Data.tableData" :columns="$Data.columns" :loading="$Data.loading" :active-row-keys="$Data.activeRowKeys" row-key="id" height="calc(100vh - var(--search-height) - var(--layout-gap) * 2)" active-row-type="single" @active-change="$Method.onActiveChange">
24
- <template #method="{ row }">
25
- <TTag v-if="row.method === 'GET'" shape="round" theme="success" variant="light-outline">GET</TTag>
26
- <TTag v-else-if="row.method === 'POST'" shape="round" theme="primary" variant="light-outline">POST</TTag>
27
- <TTag v-else-if="row.method === 'PUT'" shape="round" theme="warning" variant="light-outline">PUT</TTag>
28
- <TTag v-else-if="row.method === 'DELETE'" shape="round" theme="danger" variant="light-outline">DELETE</TTag>
29
- <TTag v-else shape="round" variant="light-outline">{{ row.method }}</TTag>
30
- </template>
31
- <template #addonName="{ row }">
32
- <TTag v-if="row.addonName" shape="round" variant="light-outline">{{ row.addonTitle || row.addonName }}</TTag>
33
- <span v-else>项目</span>
34
- </template>
35
- </TTable>
36
- </div>
37
-
38
- <div class="main-detail">
39
- <DetailPanel :data="$Data.currentRow" :fields="$Data.columns">
40
- <template #method="{ value }">
41
- <TTag v-if="value === 'GET'" shape="round" theme="success" variant="light-outline">GET</TTag>
42
- <TTag v-else-if="value === 'POST'" shape="round" theme="primary" variant="light-outline">POST</TTag>
43
- <TTag v-else-if="value === 'PUT'" shape="round" theme="warning" variant="light-outline">PUT</TTag>
44
- <TTag v-else-if="value === 'DELETE'" shape="round" theme="danger" variant="light-outline">DELETE</TTag>
45
- <TTag v-else shape="round" variant="light-outline">{{ value }}</TTag>
46
- </template>
47
- </DetailPanel>
48
- </div>
49
- </div>
50
- </div>
51
- </template>
52
-
53
- <script setup>
54
- import { Button as TButton, Table as TTable, Tag as TTag, Input as TInput, MessagePlugin } from "tdesign-vue-next";
55
- import ILucideRotateCw from "~icons/lucide/rotate-cw";
56
- import ILucideSearch from "~icons/lucide/search";
57
- import { $Http } from "@/plugins/http";
58
- import { withDefaultColumns } from "befly-vite/utils/withDefaultColumns";
59
- import DetailPanel from "@/components/DetailPanel.vue";
60
-
61
- definePage({
62
- meta: {
63
- title: "接口列表",
64
- order: 3
65
- }
66
- });
67
-
68
- // 响应式数据
69
- const $Data = $ref({
70
- tableData: [],
71
- allData: [],
72
- loading: false,
73
- searchKeyword: "",
74
- columns: withDefaultColumns([
75
- { colKey: "name", title: "接口名称" },
76
- { colKey: "id", title: "序号" },
77
- { colKey: "path", title: "接口路径" },
78
- { colKey: "method", title: "请求方法" },
79
- { colKey: "addonName", title: "所属组件" }
80
- ]),
81
- currentRow: null,
82
- activeRowKeys: []
83
- });
84
-
85
- // 方法
86
- const $Method = {
87
- async initData() {
88
- await $Method.loadApiAll();
89
- },
90
-
91
- // 加载全部接口
92
- async loadApiAll() {
93
- $Data.loading = true;
94
- try {
95
- const res = await $Http("/addon/admin/api/all");
96
- const list = res.data?.lists || [];
97
- $Data.allData = list;
98
- $Data.tableData = list;
99
-
100
- // 自动高亮第一行
101
- if ($Data.tableData.length > 0) {
102
- $Data.currentRow = $Data.tableData[0];
103
- $Data.activeRowKeys = [$Data.tableData[0].id];
104
- } else {
105
- $Data.currentRow = null;
106
- $Data.activeRowKeys = [];
107
- }
108
- } catch (error) {
109
- MessagePlugin.error("加载数据失败");
110
- } finally {
111
- $Data.loading = false;
112
- }
113
- },
114
-
115
- // 刷新
116
- handleRefresh() {
117
- $Method.loadApiAll();
118
- },
119
-
120
- // 搜索
121
- handleSearch() {
122
- if (!$Data.searchKeyword) {
123
- $Data.tableData = $Data.allData;
124
- return;
125
- }
126
- const keyword = $Data.searchKeyword.toLowerCase();
127
- $Data.tableData = $Data.allData.filter((item) => item.name?.toLowerCase().includes(keyword) || item.path?.toLowerCase().includes(keyword));
128
- },
129
-
130
- // 高亮行变化
131
- onActiveChange(value, context) {
132
- // 禁止取消高亮:如果新值为空,保持当前选中
133
- if (value.length === 0 && $Data.activeRowKeys.length > 0) {
134
- return;
135
- }
136
- $Data.activeRowKeys = value;
137
- // 更新当前高亮的行数据
138
- if (context.activeRowList && context.activeRowList.length > 0) {
139
- $Data.currentRow = context.activeRowList[0].row;
140
- }
141
- }
142
- };
143
-
144
- $Method.initData();
145
- </script>
146
-
147
- <style scoped lang="scss">
148
- // 样式继承自全局 page-table
149
- </style>
@@ -1,12 +0,0 @@
1
- <template>
2
- <RouterView />
3
- </template>
4
-
5
- <script setup>
6
- definePage({
7
- meta: {
8
- title: "权限设置",
9
- order: 20
10
- }
11
- });
12
- </script>