diff --git a/frontend/src/views/live/List.vue b/frontend/src/views/live/List.vue index fd70276..6679869 100644 --- a/frontend/src/views/live/List.vue +++ b/frontend/src/views/live/List.vue @@ -102,6 +102,44 @@ async function onDelete(a: LiveAccount): Promise { } } +// #81 批量删除:多选仅可选非运行行(运行中先停止),循环既有 DELETE 接口 +const selection = ref([]) +function onSelChange(rows: LiveAccount[]): void { + selection.value = rows +} +const canBatch = (row: LiveAccount): boolean => row.status !== 'running' +const batchLoading = ref(false) +async function onBatchDelete(): Promise { + const rows = selection.value + if (!rows.length) return + const names = rows.map((r) => `#${r.id} ${r.name}`).slice(0, 5).join('、') + + (rows.length > 5 ? ` 等 ${rows.length} 个` : '') + try { + await ElMessageBox.confirm( + `删除 ${rows.length} 个实盘实例:${names}?成交/持仓/余额数据将一并删除,不可恢复。`, + '批量删除确认', + { type: 'warning' }, + ) + } catch { + return + } + batchLoading.value = true + let ok = 0 + const failed: string[] = [] + for (const r of rows) { + try { + await deleteLive(r.id) + ok++ + } catch (e: unknown) { + failed.push(`#${r.id}(${e instanceof Error ? e.message : '失败'})`) + } + } + batchLoading.value = false + if (failed.length) ElMessage.warning(`已删 ${ok} 个;失败 ${failed.length} 个:${failed.join('、')}`) + else ElMessage.success(`已删除 ${ok} 个实盘实例`) + await refreshSilent() +} + // 编辑(仅 stopped 可改;后端运行中会 400) // 代码快照(§12.6 补:查看该账户发起时的代码 vs 当前) const snapshotRow = ref<{ instanceId: number; codeHash: string; label: string } | null>(null) @@ -197,10 +235,14 @@ async function onStop(a: LiveAccount): Promise { 刷新 + + 批量删除({{ selection.length }}) + - + +