From bfd42f70aec008861ca3c37adf8300dd25384d66 Mon Sep 17 00:00:00 2001 From: claude_dev Date: Sun, 16 Aug 2026 13:55:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20#80=E6=A8=A1=E6=8B=9F?= =?UTF-8?q?=E7=9B=98=E5=91=BD=E5=90=8D=E5=AF=B9=E9=BD=90=E5=AE=9E=E7=9B=98?= =?UTF-8?q?+#81=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4+#82=E5=AE=9E=E7=9B=98?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E5=90=8D=E6=B8=85=E7=A9=BA=E2=80=94=E2=80=94?= =?UTF-8?q?#80:autoName=E6=94=B9{=E5=AE=9E=E4=BE=8B=E5=90=8D}=5Fv{YYYYMMDD?= =?UTF-8?q?}{minor}=E5=90=8C=E5=AE=9E=E4=BE=8B=E5=90=8C=E6=97=A5=E9=80=92?= =?UTF-8?q?=E5=A2=9E=E4=B8=8D=E5=88=86=E6=A8=A1=E5=BC=8F(=E5=8E=9F{?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E5=90=8D}=C2=B7{=E6=A8=A1=E5=BC=8F}v{N}?= =?UTF-8?q?=E8=BF=9E=E6=8E=92+=E8=8B=B1=E6=96=87=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E6=AE=B5,=E7=94=A8=E6=88=B7=E5=AE=9A=E7=A8=BF=E4=B8=8E?= =?UTF-8?q?=E5=AE=9E=E7=9B=98=E5=90=8C=E6=A0=BC=E5=BC=8F);#81:=E6=A8=A1?= =?UTF-8?q?=E6=8B=9F=E7=9B=98/=E5=AE=9E=E7=9B=98=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=8A=A0=E5=A4=9A=E9=80=89=E5=88=97(=E4=BB=85=E9=9D=9E?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E8=A1=8C=E5=8F=AF=E9=80=89=3D=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E4=B8=AD=E5=85=88=E5=81=9C=E6=AD=A2)+=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE(=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E6=89=8D=E6=98=BE=E7=A4=BA=E5=B8=A6=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E5=BE=BD=E6=A0=87,=E7=A1=AE=E8=AE=A4=E6=A1=86=E5=88=97?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E5=90=8D=E5=89=8D5,=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E6=97=A2=E6=9C=89DELETE=E6=8E=A5=E5=8F=A3,N=E6=88=90=E5=8A=9F/?= =?UTF-8?q?M=E5=A4=B1=E8=B4=A5=E6=B1=87=E6=80=BB+=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E6=98=8E=E7=BB=86toast);#82:=E6=96=B0=E5=BB=BA=E5=AE=9E?= =?UTF-8?q?=E7=9B=98=E5=88=9D=E5=A7=8Bname=20live-600000=E6=94=B9=E7=A9=BA?= =?UTF-8?q?=E4=B8=B2,=E6=9C=AA=E9=80=89=E5=AE=9E=E4=BE=8B=E6=97=B6?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E6=98=BE=E7=A4=BA=E5=8D=A0=E4=BD=8D=E3=80=8C?= =?UTF-8?q?=E2=80=94=EF=BC=88=E9=80=89=E5=AE=9E=E4=BE=8B=E5=90=8E=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=94=9F=E6=88=90=EF=BC=89=E3=80=8D(=E5=8E=9F?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC=E9=A1=B6=E6=8E=89=E5=8D=A0=E4=BD=8D?= =?UTF-8?q?=E6=8F=90=E7=A4=BA),=E9=80=89=E5=AE=9E=E4=BE=8B=E5=90=8EautoNam?= =?UTF-8?q?e=E7=94=9F=E6=88=90,=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=85=9C?= =?UTF-8?q?=E5=BA=95(#78)=E5=8F=8C=E4=BF=9D=E9=99=A9;build=E7=BB=BF(vue-ts?= =?UTF-8?q?c)=20[nas]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/live/List.vue | 44 ++++++++++++++++++++++++++++++- frontend/src/views/live/New.vue | 2 +- frontend/src/views/paper/List.vue | 44 ++++++++++++++++++++++++++++++- frontend/src/views/paper/New.vue | 19 ++++++------- 4 files changed, 97 insertions(+), 12 deletions(-) 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 }}) + - + +