@befly-addon/admin 1.5.2 → 1.6.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.
@@ -75,7 +75,7 @@ const $Data = $ref({
75
75
  columns: withDefaultColumns([
76
76
  { colKey: "name", title: "接口名称" },
77
77
  { colKey: "auth", title: "登录" },
78
- { colKey: "routePath", title: "接口路径" },
78
+ { colKey: "path", title: "接口路径" },
79
79
  { colKey: "method", title: "请求方法" },
80
80
  { colKey: "addonName", title: "所属组件" }
81
81
  ]),
@@ -125,7 +125,7 @@ const $Method = {
125
125
  return;
126
126
  }
127
127
  const keyword = $Data.searchKeyword.toLowerCase();
128
- $Data.tableData = $Data.allData.filter((item) => item.name?.toLowerCase().includes(keyword) || item.routePath?.toLowerCase().includes(keyword));
128
+ $Data.tableData = $Data.allData.filter((item) => item.name?.toLowerCase().includes(keyword) || item.path?.toLowerCase().includes(keyword));
129
129
  },
130
130
 
131
131
  // 高亮行变化
@@ -12,10 +12,10 @@
12
12
 
13
13
  <!-- 接口分组列表 -->
14
14
  <div class="api-container">
15
- <div class="api-group" v-for="group in $Data.filteredApiData" :key="group.name">
16
- <div class="group-header">{{ group.title }}</div>
17
- <div class="api-checkbox-list">
18
- <TCheckboxGroup v-model="$Data.checkedApiPaths">
15
+ <TCheckboxGroup v-model="$Data.checkedApiPaths">
16
+ <div class="api-group" v-for="group in $Data.filteredApiData" :key="group.name">
17
+ <div class="group-header">{{ group.title }}</div>
18
+ <div class="api-checkbox-list">
19
19
  <TCheckbox v-for="api in group.apis" :key="api.value" :value="api.value">
20
20
  <div class="api-checkbox-label">
21
21
  <div class="api-label-main">
@@ -23,25 +23,25 @@
23
23
  </div>
24
24
  </div>
25
25
  </TCheckbox>
26
- </TCheckboxGroup>
26
+ </div>
27
27
  </div>
28
- </div>
28
+ </TCheckboxGroup>
29
29
  </div>
30
30
  </div>
31
31
 
32
32
  <template #footer>
33
33
  <div class="dialog-footer">
34
- <t-space>
34
+ <TSpace>
35
35
  <TButton theme="default" @click="$Method.onClose">取消</TButton>
36
36
  <TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">保存</TButton>
37
- </t-space>
37
+ </TSpace>
38
38
  </div>
39
39
  </template>
40
40
  </TDialog>
41
41
  </template>
42
42
 
43
43
  <script setup lang="ts">
44
- import { Dialog as TDialog, Input as TInput, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, MessagePlugin } from "tdesign-vue-next";
44
+ import { Dialog as TDialog, Input as TInput, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, Space as TSpace, MessagePlugin } from "tdesign-vue-next";
45
45
  import ILucideSearch from "~icons/lucide/search";
46
46
  import { $Http } from "@/plugins/http";
47
47
 
@@ -85,7 +85,8 @@ const $Method = {
85
85
  const apis = group && group.apis;
86
86
  const list = Array.isArray(apis) ? apis : [];
87
87
  for (const api of list) {
88
- if (api && api.auth === 0 && typeof api.value === "string" && api.value) {
88
+ const isPublic = api && (api.auth === 0 || api.auth === "0" || api.auth === false);
89
+ if (isPublic && typeof api.value === "string" && api.value) {
89
90
  merged.add(api.value);
90
91
  }
91
92
  }
@@ -113,32 +114,54 @@ const $Method = {
113
114
  try {
114
115
  const res = await $Http("/addon/admin/api/all");
115
116
 
116
- // 将接口列表按 addonTitle 分组
117
+ // 将接口列表按 parentPath 分组展示(routePath 已迁移为 path)
117
118
  const apiMap = new Map();
118
119
 
119
- res.data.lists.forEach((api) => {
120
- const addonTitle = api.addonTitle || api.addonName || "项目接口";
121
- const addonName = api.addonName || "app";
120
+ const lists = res && res.data && Array.isArray(res.data.lists) ? res.data.lists : [];
121
+ for (const api of lists) {
122
+ const apiPath = api && typeof api.path === "string" ? api.path : "";
123
+ if (!apiPath) {
124
+ continue;
125
+ }
126
+
127
+ const parentPath = api && typeof api.parentPath === "string" ? api.parentPath : "";
128
+ const groupKey = parentPath || "(未分组)";
122
129
 
123
- if (!apiMap.has(addonName)) {
124
- apiMap.set(addonName, {
125
- name: addonName,
126
- title: addonTitle,
130
+ if (!apiMap.has(groupKey)) {
131
+ apiMap.set(groupKey, {
132
+ name: groupKey,
133
+ title: groupKey,
127
134
  apis: []
128
135
  });
129
136
  }
130
137
 
131
- apiMap.get(addonName).apis.push({
132
- value: api.routePath,
133
- name: api.name || "",
134
- path: api.routePath || "",
135
- label: `${api.name || ""} ${api.routePath ? `(${api.routePath})` : ""}`.trim(),
136
- description: api.description,
137
- auth: api.auth
138
+ apiMap.get(groupKey).apis.push({
139
+ value: apiPath,
140
+ name: (api && typeof api.name === "string" ? api.name : "") || apiPath,
141
+ path: apiPath,
142
+ label: `${(api && typeof api.name === "string" ? api.name : "") || ""} ${apiPath ? `(${apiPath})` : ""}`.trim(),
143
+ description: api ? api.description : undefined,
144
+ auth: api ? api.auth : undefined,
145
+ parentPath: parentPath
146
+ });
147
+ }
148
+
149
+ const groups = Array.from(apiMap.values());
150
+ for (const group of groups) {
151
+ group.apis.sort((a, b) => {
152
+ const ap = typeof a.path === "string" ? a.path : "";
153
+ const bp = typeof b.path === "string" ? b.path : "";
154
+ return ap.localeCompare(bp);
138
155
  });
156
+ }
157
+
158
+ groups.sort((a, b) => {
159
+ const at = typeof a.title === "string" ? a.title : "";
160
+ const bt = typeof b.title === "string" ? b.title : "";
161
+ return at.localeCompare(bt);
139
162
  });
140
163
 
141
- $Data.apiData = Array.from(apiMap.values());
164
+ $Data.apiData = groups;
142
165
  } catch (error) {
143
166
  MessagePlugin.error("加载接口失败");
144
167
  }
@@ -169,7 +192,12 @@ const $Method = {
169
192
  const searchLower = $Data.searchText.toLowerCase();
170
193
  $Data.filteredApiData = $Data.apiData
171
194
  .map((group) => {
172
- const apis = group.apis.filter((api) => api.label.toLowerCase().includes(searchLower));
195
+ const apis = group.apis.filter((api) => {
196
+ const label = api && typeof api.label === "string" ? api.label : "";
197
+ const name = api && typeof api.name === "string" ? api.name : "";
198
+ const path = api && typeof api.path === "string" ? api.path : "";
199
+ return label.toLowerCase().includes(searchLower) || name.toLowerCase().includes(searchLower) || path.toLowerCase().includes(searchLower);
200
+ });
173
201
  return {
174
202
  name: group.name,
175
203
  title: group.title,
@@ -218,6 +246,12 @@ $Method.initData();
218
246
  flex: 1;
219
247
  overflow-y: auto;
220
248
 
249
+ /* CheckboxGroup 默认可能是 inline 布局,容易被内容撑开;这里强制占满容器宽度 */
250
+ :deep(.t-checkbox-group) {
251
+ display: block;
252
+ width: 100%;
253
+ }
254
+
221
255
  .api-group {
222
256
  margin-bottom: 16px;
223
257
  border: 1px solid var(--border-color);
@@ -225,7 +259,22 @@ $Method.initData();
225
259
  overflow: hidden;
226
260
 
227
261
  .api-checkbox-list {
228
- padding: 10px;
262
+ padding: 12px 16px;
263
+ display: flex;
264
+ flex-wrap: wrap;
265
+ gap: 12px;
266
+
267
+ :deep(.t-checkbox) {
268
+ margin: 0;
269
+ flex: 0 0 calc(33.333% - 8px);
270
+ min-width: 0;
271
+
272
+ .t-checkbox__label {
273
+ white-space: nowrap;
274
+ overflow: hidden;
275
+ text-overflow: ellipsis;
276
+ }
277
+ }
229
278
  }
230
279
 
231
280
  &:last-child {
@@ -135,8 +135,3 @@ const $Method = {
135
135
 
136
136
  $Method.initData();
137
137
  </script>
138
-
139
- <style scoped lang="scss">
140
- .comp-role-edit {
141
- }
142
- </style>
package/apis/api/list.ts CHANGED
@@ -11,7 +11,7 @@ export default {
11
11
  const result = await befly.db.getList({
12
12
  table: "addon_admin_api",
13
13
  where: {
14
- $or: ctx.body.keyword ? [{ name$like: `%${ctx.body.keyword}%` }, { routePath$like: `%${ctx.body.keyword}%` }] : undefined
14
+ $or: ctx.body.keyword ? [{ name$like: `%${ctx.body.keyword}%` }, { path$like: `%${ctx.body.keyword}%` }] : undefined
15
15
  },
16
16
  orderBy: ["id#ASC"],
17
17
  page: ctx.body.page,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@befly-addon/admin",
3
- "version": "1.5.2",
4
- "gitHead": "990c7108a9a791b9816c447309ec586d08b96ab4",
3
+ "version": "1.6.0",
4
+ "gitHead": "0d60e323a83a1fc53822147de877af19cdb972c0",
5
5
  "private": false,
6
6
  "description": "Befly - 管理后台功能组件",
7
7
  "keywords": [
package/tables/api.json CHANGED
@@ -14,13 +14,20 @@
14
14
  "default": 1,
15
15
  "detail": "0=免登录,1=需登录"
16
16
  },
17
- "routePath": {
17
+ "path": {
18
18
  "name": "接口路径",
19
19
  "type": "string",
20
20
  "min": 1,
21
21
  "max": 200,
22
22
  "index": true
23
23
  },
24
+ "parentPath": {
25
+ "name": "父级路径",
26
+ "type": "string",
27
+ "min": 1,
28
+ "max": 200,
29
+ "index": true
30
+ },
24
31
  "addonName": {
25
32
  "name": "所属插件",
26
33
  "type": "string",