Skip to content

Commit b309109

Browse files
committed
feat: implement pagination for tags in TagDrawer component
1 parent 43b940f commit b309109

File tree

2 files changed

+56
-19
lines changed

2 files changed

+56
-19
lines changed

ui/src/views/document/tag/MulAddTagDialog.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
v-model="tag.key"
3131
@change="tagKeyChange(tag)"
3232
filterable
33+
:filter-method="filterMethod"
3334
:placeholder="$t('views.document.tag.requiredMessage1')"
3435
:loading="optionLoading"
3536
>
@@ -139,7 +140,8 @@ const optionLoading = ref<boolean>(false)
139140
const FormRef = ref()
140141
const dialogVisible = ref<boolean>(false)
141142
const tagList = ref<Array<any>>([])
142-
const keyOptions = ref()
143+
const keyOptions = ref([])
144+
const allKeyOptions = ref([])
143145
144146
const add = () => {
145147
tagList.value.push({})
@@ -174,10 +176,15 @@ function getTags(Key?: string) {
174176
loadSharedApi({ type: 'knowledge', systemType: props.apiType, isShared: isShared.value })
175177
.getTags(id, {}, optionLoading)
176178
.then((res: any) => {
177-
keyOptions.value = res.data
179+
keyOptions.value = res.data.slice(0, 100)
180+
allKeyOptions.value = res.data
178181
})
179182
}
180183
184+
function filterMethod(val: string) {
185+
keyOptions.value = allKeyOptions.value.filter((item: any) => item.key.indexOf(val) > -1).slice(0, 100)
186+
}
187+
181188
const createTagDialogRef = ref()
182189
183190
function openCreateTagDialog(row?: any) {

ui/src/views/document/tag/TagDrawer.vue

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
/>
3030
</div>
3131
<el-table
32-
:data="tableData"
32+
:data="pagedTableData"
3333
:span-method="spanMethod"
3434
v-loading="loading"
35+
:max-height="tableMaxHeight"
3536
@selection-change="handleSelectionChange"
3637
@cell-mouse-enter="cellMouseEnter"
3738
@cell-mouse-leave="cellMouseLeave"
@@ -114,6 +115,15 @@
114115
</template>
115116
</el-table-column>
116117
</el-table>
118+
<div class="app-table__pagination mt-16">
119+
<el-pagination
120+
v-model:current-page="pageNum"
121+
v-model:page-size="pageSize"
122+
:total="groupedByKey.length"
123+
layout="total, prev, pager, next, sizes"
124+
:page-sizes="[10, 20, 50, 100]"
125+
/>
126+
</div>
117127
</el-drawer>
118128
<CreateTagDialog ref="createTagDialogRef" @refresh="getList" />
119129
<EditTagDialog ref="editTagDialogRef" @refresh="getList" />
@@ -159,6 +169,9 @@ const debugVisible = ref(false)
159169
const filterText = ref('')
160170
const tags = ref<Array<any>>([])
161171
const currentMouseId = ref<number | null>(null)
172+
const pageNum = ref(1)
173+
const pageSize = ref(20)
174+
const tableMaxHeight = computed(() => `calc(100vh - 260px)`)
162175
163176
function cellMouseEnter(row: any) {
164177
currentMouseId.value = row.id
@@ -168,7 +181,7 @@ function cellMouseLeave() {
168181
currentMouseId.value = null
169182
}
170183
171-
// 将原始数据转换为表格数据
184+
// 1) 仍然把后端全量 tags 转成“扁平行”,每行带上 keyIndex
172185
const tableData = computed(() => {
173186
const result: any[] = []
174187
tags.value.forEach((tag: any) => {
@@ -178,31 +191,46 @@ const tableData = computed(() => {
178191
id: value.id,
179192
key: tag.key,
180193
value: value.value,
181-
keyIndex: index, // 用于判断是否为第一行
194+
keyIndex: index, // 同一个 key 下第几行
182195
})
183196
})
184197
}
185198
})
186199
return result
187200
})
188201
189-
// 合并单元格方法
190-
const spanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
202+
// 2) 按 key 分组(保持 key 的出现顺序)
203+
const groupedByKey = computed(() => {
204+
const map = new Map<string, any[]>()
205+
for (const row of tableData.value) {
206+
if (!map.has(row.key)) map.set(row.key, [])
207+
map.get(row.key)!.push(row)
208+
}
209+
// 每个元素代表一个 key 分组
210+
return Array.from(map.entries()).map(([key, rows]) => ({ key, rows }))
211+
})
212+
213+
// 3) 按“key 分组”做分页:每页 pageSize 个 key
214+
const pagedGroups = computed(() => {
215+
const start = (pageNum.value - 1) * pageSize.value
216+
const end = start + pageSize.value
217+
return groupedByKey.value.slice(start, end)
218+
})
219+
220+
// 4) 当前页表格数据:把当前页的若干个 key 分组展开为行
221+
const pagedTableData = computed(() => {
222+
return pagedGroups.value.flatMap((g) => g.rows)
223+
})
224+
225+
// 5) 合并单元格:只在当前页内合并,同一个 key 的第一行 rowspan=该 key 在当前页的行数
226+
const spanMethod = ({ row, columnIndex }: any) => {
227+
// 注意:你现在有 selection 列,所以 key 列索引是 1;如需同时合并 value 列按需调整
191228
if (columnIndex === 0 || columnIndex === 1) {
192-
// key列 (由于添加了选择列,索引变为1)
193229
if (row.keyIndex === 0) {
194-
// 计算当前key有多少个值
195-
const sameKeyCount = tableData.value.filter((item) => item.key === row.key).length
196-
return {
197-
rowspan: sameKeyCount,
198-
colspan: 1,
199-
}
200-
} else {
201-
return {
202-
rowspan: 0,
203-
colspan: 0,
204-
}
230+
const sameKeyCount = pagedTableData.value.filter((item) => item.key === row.key).length
231+
return { rowspan: sameKeyCount, colspan: 1 }
205232
}
233+
return { rowspan: 0, colspan: 0 }
206234
}
207235
}
208236
@@ -281,12 +309,14 @@ function getList() {
281309
.getTags(id, params, loading)
282310
.then((res: any) => {
283311
tags.value = res.data
312+
pageNum.value = 1
284313
})
285314
}
286315
287316
const open = () => {
288317
filterText.value = ''
289318
debugVisible.value = true
319+
pageNum.value = 1
290320
getList()
291321
}
292322

0 commit comments

Comments
 (0)