perf: optimize batch task creation with single transaction

批量创建任务使用单事务数据库插入,显著提升性能。
移除任务列表的批量取消/删除进度显示(批处理接口无意义)。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 17:24:06 +08:00
parent 0ac6570da9
commit c8ee9685b9
2 changed files with 73 additions and 87 deletions
+6 -57
View File
@@ -55,34 +55,10 @@ export class TaskRoute implements VanComponent {
t.selected.val && !t.deleting.val && (t.statusState.val == 'waiting' || t.statusState.val == 'running')
))
/** 批量操作进度 */
batchProgress = van.state(0)
batchTotal = van.state(0)
batchOperation = van.state<'cancel' | 'delete' | ''>('')
batchInProgress = van.derive(() => this.batchTotal.val > 0 && this.batchProgress.val < this.batchTotal.val)
constructor() {
this.element = this.Root()
}
/** 固定在顶部的进度条 */
BatchProgressBar() {
return div({
class: 'sticky-top bg-body p-3 border-bottom',
hidden: () => !this.batchInProgress.val,
style: 'z-index: 10;'
},
div({ class: 'text-center fs-5' }, () => {
const op = this.batchOperation.val == 'cancel' ? '取消' : '删除'
return `正在批量${op}任务 (${this.batchProgress.val}/${this.batchTotal.val})`
}),
div({ class: 'progress' }, div({
class: 'progress-bar progress-bar-striped progress-bar-animated bg-primary',
style: () => `width: ${this.batchProgress.val / this.batchTotal.val * 100}%`
})),
)
}
Root() {
const _that = this
return Route({
@@ -91,8 +67,6 @@ export class TaskRoute implements VanComponent {
return div(
() => _that.loading.val ? LoadingBox() : '',
() => div({ class: 'vstack gap-3', hidden: _that.loading.val },
// 固定在顶部的批量操作进度条
_that.BatchProgressBar(),
// 批量操作工具栏
div({ class: 'hstack gap-2', hidden: () => _that.taskList.val.length == 0 },
input({
@@ -110,54 +84,29 @@ export class TaskRoute implements VanComponent {
button({
class: 'btn btn-sm btn-outline-danger',
hidden: () => _that.selectedCancellable.val.length == 0,
disabled: () => _that.batchInProgress.val,
onclick() {
if (!confirm(`确定要取消选中的 ${_that.selectedCancellable.val.length} 个任务吗?`)) return
const tasks = [..._that.selectedCancellable.val]
_that.batchOperation.val = 'cancel'
_that.batchTotal.val = tasks.length
_that.batchProgress.val = 0
let completed = 0
tasks.forEach(t => {
cancelTask(t.id).then(() => {
const ids = _that.selectedCancellable.val.map(t => t.id)
cancelTasks(ids).then(() => {
_that.selectedCancellable.val.forEach(t => {
t.statusState.val = 'error'
t.selected.val = false
}).finally(() => {
completed++
_that.batchProgress.val = completed
if (completed >= tasks.length) {
setTimeout(() => {
_that.batchTotal.val = 0
_that.batchProgress.val = 0
}, 500)
}
})
}).catch(error => {
alert(error.message)
})
}
}, () => `批量取消 (${_that.selectedCancellable.val.length})`),
button({
class: 'btn btn-sm btn-outline-secondary',
hidden: () => _that.selectedDeletable.val.length == 0,
disabled: () => _that.batchInProgress.val,
onclick() {
if (!confirm(`确定要删除选中的 ${_that.selectedDeletable.val.length} 个任务吗?`)) return
const tasks = [..._that.selectedDeletable.val]
_that.batchOperation.val = 'delete'
_that.batchTotal.val = tasks.length
_that.batchProgress.val = 0
const ids = tasks.map(t => t.id)
const ids = _that.selectedDeletable.val.map(t => t.id)
deleteTasks(ids).then(() => {
_that.batchProgress.val = tasks.length
_that.taskList.val = _that.taskList.val.filter(taskInDB => !ids.includes(taskInDB.id))
}).catch(error => {
alert(error.message)
}).finally(() => {
setTimeout(() => {
_that.batchTotal.val = 0
_that.batchProgress.val = 0
}, 500)
})
}
}, () => `批量删除 (${_that.selectedDeletable.val.length})`),