(payload, count, sourceLabel, options = {})
| 1101 | } |
| 1102 | |
| 1103 | async function runBatchRefreshTask(payload, count, sourceLabel, options = {}) { |
| 1104 | const showToast = options.showToast !== false; |
| 1105 | const reloadAfter = options.reloadAfter !== false; |
| 1106 | const onProgress = typeof options.onProgress === 'function' ? options.onProgress : null; |
| 1107 | isBatchRefreshing = true; |
| 1108 | updateBatchButtons(); |
| 1109 | |
| 1110 | try { |
| 1111 | const task = await api.post('/accounts/batch-refresh/async', payload, { |
| 1112 | timeoutMs: 20000, |
| 1113 | retry: 0, |
| 1114 | requestKey: 'accounts:batch-refresh', |
| 1115 | cancelPrevious: true, |
| 1116 | }); |
| 1117 | const taskId = task?.id; |
| 1118 | if (!taskId) { |
| 1119 | throw new Error('任务创建失败:未返回任务 ID'); |
| 1120 | } |
| 1121 | trackBatchTask('refresh', { |
| 1122 | id: taskId, |
| 1123 | domain: 'accounts', |
| 1124 | status: task?.status || 'pending', |
| 1125 | paused: Boolean(task?.paused), |
| 1126 | }); |
| 1127 | |
| 1128 | if (showToast) { |
| 1129 | toast.info(`${sourceLabel}任务已启动(${taskId.slice(0, 8)})`); |
| 1130 | } |
| 1131 | const finalTask = await watchAccountTask(taskId, (progressTask) => { |
| 1132 | patchBatchTask('refresh', { |
| 1133 | status: progressTask?.status || 'running', |
| 1134 | paused: Boolean(progressTask?.paused), |
| 1135 | pause_requested: Boolean(progressTask?.pause_requested), |
| 1136 | }); |
| 1137 | const progress = progressTask?.progress || {}; |
| 1138 | const completed = Number(progress.completed || 0); |
| 1139 | const total = Number(progress.total || count); |
| 1140 | const paused = Boolean(progressTask?.paused) || String(progressTask?.status || '').toLowerCase() === 'paused'; |
| 1141 | elements.batchRefreshBtn.textContent = paused ? `已暂停 ${completed}/${total}` : `刷新中 ${completed}/${total}`; |
| 1142 | if (elements.quickRefreshBtn && !isQuickWorkflowRunning) { |
| 1143 | elements.quickRefreshBtn.textContent = paused ? `⚡ 已暂停 ${completed}/${total}` : `⚡ 刷新中 ${completed}/${total}`; |
| 1144 | } |
| 1145 | if (onProgress) { |
| 1146 | onProgress({ completed, total, task: progressTask }); |
| 1147 | } |
| 1148 | }); |
| 1149 | patchBatchTask('refresh', { |
| 1150 | status: finalTask?.status || 'completed', |
| 1151 | paused: false, |
| 1152 | pause_requested: false, |
| 1153 | }); |
| 1154 | const result = finalTask?.result || {}; |
| 1155 | const status = String(finalTask?.status || '').toLowerCase(); |
| 1156 | if (status === 'completed') { |
| 1157 | if (showToast) { |
| 1158 | toast.success(`成功刷新 ${result.success_count || 0} 个,失败 ${result.failed_count || 0} 个`); |
| 1159 | } |
| 1160 | } else if (status === 'cancelled') { |
no test coverage detected