refactor(品牌工具页): 历史批量删除抽为 runBatchDelete
16 个品牌页逐字相同的 batchDeleteHistory 循环(逐条删除 + 容忍个别失败计数) 收敛为 shared/utils/batch-delete.ts 的 runBatchDelete;各页仅保留自己的删除调用 与提示文案。补单测 4 例(空列表 / 全成功 / 部分失败继续 / 非 Error 异常)。 净减约 120 行;vue-tsc 构建与 699 个前端单测通过。
This commit is contained in:
@@ -112,6 +112,7 @@ import {
|
||||
import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const selectedFileNames = ref<string[]>([])
|
||||
const uploadedFiles = ref<UploadFileVo[]>([])
|
||||
@@ -915,19 +916,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -127,6 +127,7 @@ import type { UploadFileVo } from '@/shared/api/upload.ts'
|
||||
import type { UploadedFileRef } from '@/shared/api/types/upload.ts'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const uploadedFiles = ref<UploadFileVo[]>([])
|
||||
const strategy = ref<'Terms' | 'Simple'>('Simple')
|
||||
@@ -532,19 +533,12 @@ onBeforeUnmount(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTask(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTask(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -181,6 +181,7 @@ import {
|
||||
} from '@/shared/api/java-modules'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const COUNTRY_OPTIONS = [
|
||||
{ code: 'DE', label: '德国' },
|
||||
@@ -722,19 +723,12 @@ onBeforeUnmount(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -170,6 +170,7 @@ import { EXCEL_EXTENSIONS, checkSelectedFiles, guardBlocked } from '@/shared/dis
|
||||
import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const convertSelectedPaths = ref<string[]>([])
|
||||
const convertArchiveName = ref('')
|
||||
@@ -411,19 +412,12 @@ onMounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteConvertHistoryRecord(itemSource(view).resultId!)
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteConvertHistoryRecord(itemSource(view).resultId!))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -128,6 +128,7 @@ import { EXCEL_EXTENSIONS, checkSelectedFiles, guardBlocked } from '@/shared/dis
|
||||
import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const cleanAvailableColumns = ref<string[]>([])
|
||||
const cleanSelectedColumns = ref<string[]>([])
|
||||
@@ -443,19 +444,12 @@ onMounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteCleanHistoryRecord(itemSource(view).resultId!)
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteCleanHistoryRecord(itemSource(view).resultId!))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -141,6 +141,7 @@ import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { useZiniaoVersion } from '@/shared/utils/ziniao-version'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
interface SessionDeleteBrandItem extends DeleteBrandResultItem {
|
||||
_pushed?: boolean
|
||||
@@ -1499,19 +1500,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteHistoryRecord(itemSource(view).resultId!)
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteHistoryRecord(itemSource(view).resultId!))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -274,6 +274,7 @@ import {
|
||||
} from "@/shared/country-options";
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { useHistoryPolling } from '@/shared/composables/useHistoryPolling'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const MAX_TRANSIENT_ERRORS = 30;
|
||||
/** 任务终态后等待结果文件(Java 侧异步生成)的最大轮次,12 × 10s ≈ 2 分钟 */
|
||||
@@ -1255,19 +1256,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -259,6 +259,7 @@ import {
|
||||
} from '@/shared/api/java-modules'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const ziniaoVersion = useZiniaoVersion()
|
||||
|
||||
@@ -1660,19 +1661,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -175,6 +175,7 @@ import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import ZiniaoVersionSetting from '@/shared/components/ZiniaoVersionSetting.vue'
|
||||
import { useZiniaoVersion } from '@/shared/utils/ziniao-version'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const shopInput = ref('')
|
||||
const candidates = ref<ProductRiskCandidateVo[]>([])
|
||||
@@ -1256,19 +1257,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -220,6 +220,7 @@ import {
|
||||
import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { useZiniaoVersion, type ZiniaoVersion } from '@/shared/utils/ziniao-version'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const COUNTRY_OPTIONS = [
|
||||
{ code: 'DE', label: '德国' },
|
||||
@@ -1178,19 +1179,12 @@ onBeforeUnmount(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -216,6 +216,7 @@ import ZiniaoVersionSetting from "@/shared/components/ZiniaoVersionSetting.vue";
|
||||
import { useZiniaoVersion } from "@/shared/utils/ziniao-version";
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { useHistoryPolling } from '@/shared/composables/useHistoryPolling'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const MAX_TRANSIENT_ERRORS = 30;
|
||||
const ziniaoVersion = useZiniaoVersion();
|
||||
@@ -1082,19 +1083,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -152,6 +152,7 @@ import {
|
||||
type ShopDataCrawlShopItem,
|
||||
type ShopDataCrawlTaskDetailVo,
|
||||
} from '@/shared/api/java-modules'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const COUNTRY_OPTIONS = [
|
||||
{ code: 'UK', label: '英国' },
|
||||
@@ -583,19 +584,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -121,6 +121,7 @@ import { getTaskPollIntervalMs } from '@/shared/task-progress-config'
|
||||
import { createCategorizedTimers } from '@/shared/utils/categorized-timers'
|
||||
import { saveUrlWithProgress } from '@/shared/utils/download-progress'
|
||||
import { useZiniaoVersion } from '@/shared/utils/ziniao-version'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const COUNTRY_OPTIONS = [{ code: 'DE', label: '德国' }, { code: 'UK', label: '英国' }, { code: 'FR', label: '法国' }, { code: 'IT', label: '意大利' }, { code: 'ES', label: '西班牙' }] as const
|
||||
const shopInput = ref('')
|
||||
@@ -553,19 +554,12 @@ onUnmounted(() => { disposed = true; stopPolling(); stopScheduleHeartbeat(); cle
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -152,6 +152,7 @@ import {
|
||||
import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const selectedFileNames = ref<string[]>([])
|
||||
const uploadedFiles = ref<UploadFileVo[]>([])
|
||||
@@ -1069,19 +1070,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -149,6 +149,7 @@ import { EXCEL_EXTENSIONS, checkSelectedFiles, guardBlocked } from '@/shared/dis
|
||||
import { passGuard } from '@/shared/dispatch-guard-ui'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const splitSelectedPaths = ref<string[]>([])
|
||||
const splitArchiveName = ref('')
|
||||
@@ -399,19 +400,12 @@ onMounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteSplitHistoryRecord(itemSource(view).resultId!)
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteSplitHistoryRecord(itemSource(view).resultId!))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -256,6 +256,7 @@ import ZiniaoVersionSetting from "@/shared/components/ZiniaoVersionSetting.vue";
|
||||
import { useZiniaoVersion } from "@/shared/utils/ziniao-version";
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { useHistoryPolling } from '@/shared/composables/useHistoryPolling'
|
||||
import { runBatchDelete } from '@/shared/utils/batch-delete'
|
||||
|
||||
const MAX_TRANSIENT_ERRORS = 30;
|
||||
const ziniaoVersion = useZiniaoVersion();
|
||||
@@ -1215,19 +1216,12 @@ onUnmounted(() => {
|
||||
* 历史记录批量删除:复用单条删除逻辑(删除后原函数各自刷新列表)
|
||||
*/
|
||||
async function batchDeleteHistory(views: TaskItemView[]) {
|
||||
if (!views.length) return
|
||||
let failed = 0
|
||||
for (const view of views) {
|
||||
try {
|
||||
await deleteTaskRecord(itemSource(view))
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
const { total, failed } = await runBatchDelete(views, (view) => deleteTaskRecord(itemSource(view)))
|
||||
if (!total) return
|
||||
if (failed > 0) {
|
||||
ElMessage.warning(`删除完成,${failed} 条失败`)
|
||||
} else {
|
||||
ElMessage.success(`已删除 ${views.length} 条历史记录`)
|
||||
ElMessage.success(`已删除 ${total} 条历史记录`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
export interface BatchDeleteResult {
|
||||
/** 尝试删除的条数 */
|
||||
total: number
|
||||
/** 删除失败的条数(单条失败不中断整批) */
|
||||
failed: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 历史任务批量删除:逐条删除,容忍个别失败并计数,供各工具页统一提示。
|
||||
*
|
||||
* 单条失败继续删剩下的(不中断整批),返回成功的数量给调用方决定文案。
|
||||
*/
|
||||
export async function runBatchDelete<T>(
|
||||
items: readonly T[],
|
||||
deleteOne: (item: T) => Promise<unknown>,
|
||||
): Promise<BatchDeleteResult> {
|
||||
let failed = 0
|
||||
for (const item of items) {
|
||||
try {
|
||||
await deleteOne(item)
|
||||
} catch {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
return { total: items.length, failed }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { runBatchDelete } from '../src/shared/utils/batch-delete.ts'
|
||||
|
||||
test('空列表不调用删除并返回 0', async () => {
|
||||
let calls = 0
|
||||
const result = await runBatchDelete([], async () => {
|
||||
calls += 1
|
||||
})
|
||||
|
||||
assert.deepEqual(result, { total: 0, failed: 0 })
|
||||
assert.equal(calls, 0)
|
||||
})
|
||||
|
||||
test('全部成功时 failed 为 0', async () => {
|
||||
const seen: number[] = []
|
||||
const result = await runBatchDelete([1, 2, 3], async (n) => {
|
||||
seen.push(n)
|
||||
})
|
||||
|
||||
assert.deepEqual(result, { total: 3, failed: 0 })
|
||||
assert.deepEqual(seen, [1, 2, 3])
|
||||
})
|
||||
|
||||
test('个别失败继续删其余并计数', async () => {
|
||||
const seen: number[] = []
|
||||
const result = await runBatchDelete([1, 2, 3, 4], async (n) => {
|
||||
seen.push(n)
|
||||
if (n === 2 || n === 4) throw new Error('删除失败')
|
||||
})
|
||||
|
||||
assert.deepEqual(result, { total: 4, failed: 2 })
|
||||
assert.deepEqual(seen, [1, 2, 3, 4], '失败后应继续处理后续条目')
|
||||
})
|
||||
|
||||
test('抛出非 Error 也计入失败', async () => {
|
||||
const result = await runBatchDelete(['a'], async () => {
|
||||
throw 'boom'
|
||||
})
|
||||
|
||||
assert.deepEqual(result, { total: 1, failed: 1 })
|
||||
})
|
||||
Reference in New Issue
Block a user