Compare commits

...

2 Commits

Author SHA1 Message Date
zhaojisen
cf094cbb88 perf:Optimize the execution efficiency of all and reverse selection 2024-12-05 12:47:05 +08:00
feng
66532f4d4b fix: ticket duplicate submission 2024-11-26 16:27:27 +08:00
2 changed files with 120 additions and 21 deletions

View File

@@ -34,12 +34,14 @@ class StrategyNormal extends StrategyAbstract {
onSelectionChange(val) { onSelectionChange(val) {
this.elDataTable.selected = val this.elDataTable.selected = val
} }
/** /**
* toggleRowSelection和clearSelection的表现与el-table一致 * toggleRowSelection和clearSelection的表现与el-table一致
*/ */
toggleRowSelection(...args) { toggleRowSelection(...args) {
return this.elTable.toggleRowSelection(...args) return this.elTable.toggleRowSelection(...args)
} }
clearSelection() { clearSelection() {
return this.elTable.clearSelection() return this.elTable.clearSelection()
} }
@@ -63,18 +65,62 @@ class StrategyPersistSelection extends StrategyAbstract {
*/ */
onSelect(selection, row) { onSelect(selection, row) {
const isChosen = selection.indexOf(row) > -1 const isChosen = selection.indexOf(row) > -1
this.toggleRowSelection(row, isChosen) this.toggleRowSelection(row, isChosen)
} }
/** /**
* 用户切换当前页的多选 * 用户切换当前页的多选
*/ */
onSelectAll(selection, selectable = () => true) { onSelectAll(selection, selectable = () => true) {
const isSelected = !!selection.length const { id, selected, data } = this.elDataTable
this.elDataTable.data.forEach(r => {
const selectedIds = new Set(selected.map(r => r[id]))
// 获取当前所有已选择的项
const selectedRows = data.filter(r => selection.includes(r))
// 判断是否已全选
const isSelected = data.every(r => selectable(r) && selectedRows.includes(r))
const rowsToSelect = []
const rowsToDeselect = []
data.forEach(r => {
if (selectable(r)) { if (selectable(r)) {
this.toggleRowSelection(r, isSelected) const isRowSelected = selectedIds.has(r[id])
if (isSelected && !isRowSelected) {
rowsToSelect.push(r)
} else if (!isSelected && isRowSelected) {
rowsToDeselect.push(r)
}
} }
}) })
if (isSelected) {
rowsToSelect.forEach(row => {
selected.push(row)
selectedIds.add(row[id])
})
rowsToDeselect.forEach(row => {
this.elDataTable.toggleRowSelection(row, true)
})
} else {
rowsToDeselect.forEach(row => {
const index = selected.findIndex(item => item[id] === row[id])
if (index !== -1) {
selected.splice(index, 1)
}
selectedIds.delete(row[id])
})
rowsToSelect.forEach(row => {
this.elDataTable.toggleRowSelection(row, false)
})
}
// this.elTable.selected = Array.from(selectedIds).map(id => {
// return data.find(r => r[id] === id)
// })
} }
/** /**
* toggleRowSelection 和 clearSelection 管理 elDataTable 的 selected 数组 * toggleRowSelection 和 clearSelection 管理 elDataTable 的 selected 数组
@@ -83,33 +129,42 @@ class StrategyPersistSelection extends StrategyAbstract {
toggleRowSelection(row, isSelected) { toggleRowSelection(row, isSelected) {
const { id, selected } = this.elDataTable const { id, selected } = this.elDataTable
const foundIndex = selected.findIndex(r => r[id] === row[id]) const foundIndex = selected.findIndex(r => r[id] === row[id])
if (typeof isSelected === 'undefined') { if (typeof isSelected === 'undefined') {
isSelected = foundIndex <= -1 isSelected = foundIndex <= -1
} }
if (isSelected && foundIndex === -1) { if (isSelected && foundIndex === -1) {
selected.push(row) selected.push(row)
} else if (!isSelected && foundIndex > -1) { } else if (!isSelected && foundIndex > -1) {
selected.splice(foundIndex, 1) selected.splice(foundIndex, 1)
} }
this.elDataTable.$emit('toggle-row-selection', isSelected, row) this.elDataTable.$emit('toggle-row-selection', isSelected, row)
this.updateElTableSelection() this.updateElTableSelection()
} }
clearSelection() { clearSelection() {
this.elDataTable.selected = [] this.elDataTable.selected = []
this.updateElTableSelection() this.updateElTableSelection()
} }
/** /**
* 将selected状态同步到el-table中 * 将selected状态同步到el-table中
*/ */
updateElTableSelection() { updateElTableSelection() {
const { data, id, selected } = this.elDataTable const { data, id, selected } = this.elDataTable
// 历史勾选的行已经不在当前页了所以要将当前页的行数据和selected合并 // 历史勾选的行已经不在当前页了所以要将当前页的行数据和selected合并
const mergeData = _.uniqWith([...data, ...selected], _.isEqual) const mergeData = _.uniqWith([...data, ...selected], _.isEqual)
mergeData.forEach(r => { mergeData.forEach(r => {
const isSelected = !!selected.find(r2 => r[id] === r2[id]) const isSelected = !!selected.find(r2 => r[id] === r2[id])
if (!this.elTable) { if (!this.elTable) {
return return
} }
this.elTable.toggleRowSelection(r, isSelected) this.elTable.toggleRowSelection(r, isSelected)
}) })
} }

View File

@@ -27,7 +27,7 @@
<el-form-item style="float: right"> <el-form-item style="float: right">
<template v-if="hasActionPerm"> <template v-if="hasActionPerm">
<el-button <el-button
:disabled="object.status.value === 'closed'" :disabled="isDisabled || object.status.value === 'closed'"
size="small" size="small"
type="primary" type="primary"
@click="handleApprove" @click="handleApprove"
@@ -35,7 +35,7 @@
<i class="fa fa-check" /> {{ $t('tickets.Accept') }} <i class="fa fa-check" /> {{ $t('tickets.Accept') }}
</el-button> </el-button>
<el-button <el-button
:disabled="object.status.value === 'closed'" :disabled="isDisabled || object.status.value === 'closed'"
size="small" size="small"
type="warning" type="warning"
@click="handleReject" @click="handleReject"
@@ -45,7 +45,7 @@
</template> </template>
<el-button <el-button
v-if="isSelfTicket" v-if="isSelfTicket"
:disabled="object.status.value === 'closed'" :disabled="isDisabled || object.status.value === 'closed'"
size="small" size="small"
type="danger" type="danger"
@click="handleClose" @click="handleClose"
@@ -94,6 +94,7 @@ export default {
}, },
data() { data() {
return { return {
isDisabled: false,
comments: '', comments: '',
type_api: '', type_api: '',
imageUrl: require('@/assets/img/avatar.png'), imageUrl: require('@/assets/img/avatar.png'),
@@ -156,17 +157,35 @@ export default {
this.createComment(function() { this.createComment(function() {
}) })
const url = `/api/v1/tickets/${this.type_api}/${this.object.id}/approve/` const url = `/api/v1/tickets/${this.type_api}/${this.object.id}/approve/`
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err)) this.$axios.put(url).then(res => {
this.reloadPage()
}).catch(err => {
this.$message.error(err)
}).finally(() => {
this.isDisabled = false
})
}, },
defaultReject() { defaultReject() {
this.createComment(function() { this.createComment(function() {
}) })
const url = `/api/v1/tickets/${this.type_api}/${this.object.id}/reject/` const url = `/api/v1/tickets/${this.type_api}/${this.object.id}/reject/`
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err)) this.$axios.put(url).then(res => {
this.reloadPage()
}).catch(err => {
this.$message.error(err)
}).finally(() => {
this.isDisabled = false
})
}, },
defaultClose() { defaultClose() {
const url = `/api/v1/tickets/${this.type_api}/${this.object.id}/close/` const url = `/api/v1/tickets/${this.type_api}/${this.object.id}/close/`
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err)) this.$axios.put(url).then(res => {
this.reloadPage()
}).catch(err => {
this.$message.error(err)
}).finally(() => {
this.isDisabled = false
})
}, },
createComment(successCallback) { createComment(successCallback) {
const commentText = this.form.comments const commentText = this.form.comments
@@ -187,17 +206,42 @@ export default {
} }
}) })
}, },
handleApprove() { handleAction(actionType) {
const handler = this.approve || this.defaultApprove if (this.isDisabled) {
return
}
this.isDisabled = true
let handler
switch (actionType) {
case 'approve':
handler = this.approve || this.defaultApprove
break
case 'reject':
handler = this.reject || this.defaultReject
break
case 'close':
handler = this.close || this.defaultClose
break
default:
handler = null
break
}
if (handler) {
handler() handler()
} else {
this.$message.error('No handler for action')
}
},
handleApprove() {
this.handleAction('approve')
}, },
handleReject() { handleReject() {
const handler = this.reject || this.defaultReject this.handleAction('reject')
handler()
}, },
handleClose() { handleClose() {
const handler = this.close || this.defaultClose this.handleAction('close')
handler()
}, },
handleComment() { handleComment() {
this.createComment( this.createComment(