mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-25 14:25:23 +00:00
fixed: Fixed an issue where the total number of cross-page multiple selections was the number of selected pages
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<el-table
|
<el-table
|
||||||
ref="table"
|
ref="table"
|
||||||
v-loading="loading"
|
v-loading="tableLoading"
|
||||||
:data="data"
|
:data="data"
|
||||||
:row-class-name="rowClassName"
|
:row-class-name="rowClassName"
|
||||||
v-bind="tableAttrs"
|
v-bind="tableAttrs"
|
||||||
@@ -749,7 +749,7 @@ export default {
|
|||||||
page: defaultFirstPage,
|
page: defaultFirstPage,
|
||||||
// https://github.com/ElemeFE/element/issues/1153
|
// https://github.com/ElemeFE/element/issues/1153
|
||||||
total: null,
|
total: null,
|
||||||
loading: false,
|
tableLoading: false,
|
||||||
// 多选项的数组
|
// 多选项的数组
|
||||||
selected: [],
|
selected: [],
|
||||||
|
|
||||||
@@ -940,11 +940,11 @@ export default {
|
|||||||
},
|
},
|
||||||
getListFromStaticData({ loading = true } = {}) {
|
getListFromStaticData({ loading = true } = {}) {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
this.loading = true
|
this.tableLoading = true
|
||||||
}
|
}
|
||||||
if (!this.hasPagination) {
|
if (!this.hasPagination) {
|
||||||
this.data = this.totalData
|
this.data = this.totalData
|
||||||
this.loading = false
|
this.tableLoading = false
|
||||||
if (this.isTree) {
|
if (this.isTree) {
|
||||||
this.data = this.tree2Array(this.data, this.expandAll)
|
this.data = this.tree2Array(this.data, this.expandAll)
|
||||||
}
|
}
|
||||||
@@ -957,7 +957,7 @@ export default {
|
|||||||
const end = (page + pageOffset) * this.size
|
const end = (page + pageOffset) * this.size
|
||||||
this.$log.debug(`page: ${page}, size: ${this.size}, start: ${start}, end: ${end}`)
|
this.$log.debug(`page: ${page}, size: ${this.size}, start: ${start}, end: ${end}`)
|
||||||
this.data = this.totalData.slice(start, end)
|
this.data = this.totalData.slice(start, end)
|
||||||
this.loading = false
|
this.tableLoading = false
|
||||||
this.data = this.tree2Array(this.data, this.expandAll)
|
this.data = this.tree2Array(this.data, this.expandAll)
|
||||||
return this.data
|
return this.data
|
||||||
},
|
},
|
||||||
@@ -983,7 +983,7 @@ export default {
|
|||||||
queryUtil.stringify(query, '=', '&')
|
queryUtil.stringify(query, '=', '&')
|
||||||
|
|
||||||
// 请求开始
|
// 请求开始
|
||||||
this.loading = loading
|
this.tableLoading = loading
|
||||||
|
|
||||||
// 存储query记录, 便于后面恢复
|
// 存储query记录, 便于后面恢复
|
||||||
if (this.saveQuery) {
|
if (this.saveQuery) {
|
||||||
@@ -1023,7 +1023,7 @@ export default {
|
|||||||
this.total === 0 &&
|
this.total === 0 &&
|
||||||
(_isEmpty(formValue) || _values(formValue).every(isFalsey))
|
(_isEmpty(formValue) || _values(formValue).every(isFalsey))
|
||||||
|
|
||||||
this.loading = false
|
this.tableLoading = false
|
||||||
/**
|
/**
|
||||||
* 请求返回, 数据更新后触发
|
* 请求返回, 数据更新后触发
|
||||||
* @property {object} data - table的数据
|
* @property {object} data - table的数据
|
||||||
@@ -1043,7 +1043,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
this.$emit('error', err)
|
this.$emit('error', err)
|
||||||
this.total = 0
|
this.total = 0
|
||||||
this.loading = false
|
this.tableLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
search(attrs, reset) {
|
search(attrs, reset) {
|
||||||
@@ -1106,9 +1106,13 @@ export default {
|
|||||||
this.page = val
|
this.page = val
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
handleSelectAll(e, canSelect) {
|
handleSelectAll(selection, selectable = () => true) {
|
||||||
this.loading = true
|
this.tableLoading = true
|
||||||
this.selectStrategy.onSelectAll(e, canSelect)
|
try {
|
||||||
|
this.selectStrategy.onSelectAll(selection, selectable)
|
||||||
|
} finally {
|
||||||
|
this.tableLoading = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否
|
* 切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否
|
||||||
|
@@ -53,102 +53,100 @@ class StrategyNormal extends StrategyAbstract {
|
|||||||
class StrategyPersistSelection extends StrategyAbstract {
|
class StrategyPersistSelection extends StrategyAbstract {
|
||||||
/**
|
/**
|
||||||
* 批量处理表格选择状态
|
* 批量处理表格选择状态
|
||||||
* @param {Array} rows 需要处理的行数据
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
*/
|
||||||
batchProcessSelection(rows) {
|
batchProcessSelection(rows) {
|
||||||
return new Promise((resolve) => {
|
// 先清空当前页的选择状态
|
||||||
// 先清空当前页的选择状态
|
this.elTable.clearSelection()
|
||||||
this.elTable.clearSelection()
|
|
||||||
|
|
||||||
const batchSize = 50
|
// 直接处理当前页的选择状态
|
||||||
const batches = Math.ceil(rows.length / batchSize)
|
rows.forEach(row => {
|
||||||
|
this.elTable.toggleRowSelection(row, true)
|
||||||
const processBatch = (batchIndex) => {
|
|
||||||
if (batchIndex >= batches) {
|
|
||||||
// 所有批次处理完成后,关闭加载状态并resolve
|
|
||||||
this.elDataTable.loading = false
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const start = batchIndex * batchSize
|
|
||||||
const end = Math.min(start + batchSize, rows.length)
|
|
||||||
|
|
||||||
rows.slice(start, end).forEach(row => {
|
|
||||||
this.elTable.toggleRowSelection(row, true, false)
|
|
||||||
})
|
|
||||||
|
|
||||||
requestAnimationFrame(() => processBatch(batchIndex + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(() => processBatch(0))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理选择变化事件
|
||||||
|
*/
|
||||||
|
onSelectionChange(val) {
|
||||||
|
const { id, data, selected } = this.elDataTable
|
||||||
|
|
||||||
|
// 如果当前页选中数量等于当前页数据量,说明是全选操作
|
||||||
|
const isSelectAll = val.length === data.length
|
||||||
|
|
||||||
|
if (isSelectAll) {
|
||||||
|
// 将当前页所有数据添加到 selected 中(如果还没有添加的话)
|
||||||
|
data.forEach(row => {
|
||||||
|
const foundIndex = selected.findIndex(r => r[id] === row[id])
|
||||||
|
if (foundIndex === -1) {
|
||||||
|
selected.push(row)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 非全选情况:将不在 val 中的当前页数据从 selected 中移除
|
||||||
|
const selectedIds = new Set(val.map(r => r[id]))
|
||||||
|
data.forEach(row => {
|
||||||
|
const foundIndex = selected.findIndex(r => r[id] === row[id])
|
||||||
|
if (!selectedIds.has(row[id]) && foundIndex > -1) {
|
||||||
|
selected.splice(foundIndex, 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发事件,传递所有选中的数据
|
||||||
|
this.elDataTable.$emit('selection-change', selected)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户切换某一行的多选
|
* 用户切换某一行的多选
|
||||||
*/
|
*/
|
||||||
onSelect(selection, row) {
|
onSelect(selection, row) {
|
||||||
const isChosen = selection.indexOf(row) > -1
|
const { id, selected } = this.elDataTable
|
||||||
|
const foundIndex = selected.findIndex(r => r[id] === row[id])
|
||||||
|
const isSelected = selection.includes(row)
|
||||||
|
|
||||||
this.toggleRowSelection(row, isChosen)
|
if (isSelected && foundIndex === -1) {
|
||||||
|
selected.push(row)
|
||||||
|
} else if (!isSelected && foundIndex > -1) {
|
||||||
|
selected.splice(foundIndex, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只更新这一行的选择状态
|
||||||
|
this.elTable.toggleRowSelection(row, isSelected)
|
||||||
|
|
||||||
|
this.elDataTable.$emit('selection-change', selected)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户切换当前页的多选
|
* 用户切换当前页的多选
|
||||||
*/
|
*/
|
||||||
onSelectAll(selection, selectable = () => true) {
|
onSelectAll(selection, selectable = () => true) {
|
||||||
const { id, selected, data } = this.elDataTable
|
const { id, selected, data } = this.elDataTable
|
||||||
|
|
||||||
// 获取可选择的行
|
|
||||||
const selectableRows = data.filter(selectable)
|
const selectableRows = data.filter(selectable)
|
||||||
|
|
||||||
// 使用selection参数来判断是全选还是取消全选
|
|
||||||
const isSelected = selection.length > 0
|
const isSelected = selection.length > 0
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// 全选
|
// 将当前页所有可选择的数据添加到 selected 中
|
||||||
const rowsToAdd = selectableRows.filter(row =>
|
const rowsToAdd = selectableRows.filter(row =>
|
||||||
!selected.find(r => r[id] === row[id])
|
!selected.find(r => r[id] === row[id])
|
||||||
)
|
)
|
||||||
selected.push(...rowsToAdd)
|
selected.push(...rowsToAdd)
|
||||||
|
this.batchProcessSelection(selectableRows)
|
||||||
// 触发选择事件
|
|
||||||
rowsToAdd.forEach(row => {
|
|
||||||
this.elDataTable.$emit('toggle-row-selection', true, row)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
// 取消全选
|
// 从 selected 中移除当前页的数据
|
||||||
// 1. 先找出当前页面中已选中的行
|
selectableRows.forEach(row => {
|
||||||
const currentPageSelected = selectableRows.filter(row =>
|
|
||||||
selected.find(r => r[id] === row[id])
|
|
||||||
)
|
|
||||||
|
|
||||||
// 2. 从selected中移除这些行
|
|
||||||
currentPageSelected.forEach(row => {
|
|
||||||
const index = selected.findIndex(r => r[id] === row[id])
|
const index = selected.findIndex(r => r[id] === row[id])
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
selected.splice(index, 1)
|
selected.splice(index, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
this.elTable.clearSelection()
|
||||||
// 3. 触发取消选择事件
|
|
||||||
currentPageSelected.forEach(row => {
|
|
||||||
this.elDataTable.$emit('toggle-row-selection', false, row)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新表格选择状态
|
this.elDataTable.$emit('selection-change', selected)
|
||||||
const selectedIds = new Set(selected.map(r => r[id]))
|
|
||||||
const currentPageSelectedRows = data.filter(r => selectedIds.has(r[id]))
|
|
||||||
|
|
||||||
return this.batchProcessSelection(currentPageSelectedRows)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toggleRowSelection和clearSelection管理elDataTable的selected数组
|
* toggleRowSelection和clearSelection管理elDataTable的selected数组
|
||||||
* 记得最后要将状态同步到el-table中
|
|
||||||
*/
|
*/
|
||||||
toggleRowSelection(row, isSelected) {
|
toggleRowSelection(row, isSelected) {
|
||||||
const { id, selected } = this.elDataTable
|
const { id, selected } = this.elDataTable
|
||||||
@@ -180,13 +178,19 @@ class StrategyPersistSelection extends StrategyAbstract {
|
|||||||
const { data, id, selected } = this.elDataTable
|
const { data, id, selected } = this.elDataTable
|
||||||
|
|
||||||
if (!this.elTable) {
|
if (!this.elTable) {
|
||||||
return Promise.resolve()
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedIds = new Set(selected.map(r => r[id]))
|
// 先清空当前页选择状态
|
||||||
const currentPageSelectedRows = data.filter(r => selectedIds.has(r[id]))
|
this.elTable.clearSelection()
|
||||||
|
|
||||||
return this.batchProcessSelection(currentPageSelectedRows)
|
// 只处理当前页的数据
|
||||||
|
data.forEach(row => {
|
||||||
|
const isSelected = selected.some(r => r[id] === row[id])
|
||||||
|
if (isSelected) {
|
||||||
|
this.elTable.toggleRowSelection(row, true)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user