+ {/* Header */}
+
+
+
+
+ RT 批量导入
+
+
+ 上传 Refresh Token 文件,验证并批量创建 S2A 账号
+
+
+
+
+
+ {/* Connection Warning */}
+ {!hasConfig && (
+
+
+
+
+
请先配置 S2A 连接
+
+
+
+
+
+
+ )}
+
+ {/* Status Overview */}
+
+
+
+ {isRunning ? (
+
+ ) : (
+
+ )}
+
+
状态
+
+ {isRunning ? '导入中' : '空闲'}
+
+
+
+
+
+
总计
+
{status?.total || tokens.length || 0}
+
+
+
成功
+
{status?.success || 0}
+
+
+
失败
+
{status?.failed || 0}
+
+
+
+ {/* Progress Bar */}
+ {isRunning && status && (
+
+
+ 进度: {status.completed}/{status.total}
+ {progressPercent}%
+
+
+
+ )}
+
+
+ {/* Left: Upload & Config */}
+
+ {/* File Upload */}
+
+
+
+
+ 上传 RT 文件
+
+
+
+
+ fileInputRef.current?.click()}
+ onDragOver={(e) => { e.preventDefault(); setDragOver(true) }}
+ onDragLeave={() => setDragOver(false)}
+ onDrop={handleDrop}
+ >
+
+
+ 点击或拖拽上传 refresh_tokens.txt
+
+
+ 每行一个 Refresh Token
+
+
+
+ {/* File info / error */}
+ {fileName && tokens.length > 0 && (
+
+
+
+ {fileName}: 共 {tokens.length} 个 Refresh Token
+
+
+ )}
+ {fileError && (
+
+ )}
+
+
+
+ {/* Config */}
+
+
+
+
+ 导入配置
+
+
+
+ {/* Prefix selection */}
+
+
+
+
+
+
+
+
+ {/* Parameters */}
+
+ setConcurrency(Number(e.target.value))}
+ disabled={isRunning}
+ />
+ setPriority(Number(e.target.value))}
+ disabled={isRunning}
+ />
+ setRateMultiplier(Number(e.target.value))}
+ disabled={isRunning}
+ />
+
+
+ {/* Action Buttons */}
+
+ {isRunning ? (
+ }
+ >
+ 停止导入
+
+ ) : (
+ }
+ >
+ 开始导入 ({tokens.length} 个)
+
+ )}
+
+
+
+
+
+ {/* Right: Results */}
+
+
+
+
+ 导入结果
+ {status && status.results.length > 0 && (
+
+ ({status.results.length} 条)
+
+ )}
+
+
+
+ {(!status || status.results.length === 0) ? (
+
+
+
暂无导入记录
+
上传 RT 文件并开始导入后,结果将显示在这里
+
+ ) : (
+
+ {status.results.map((r) => (
+
+ {r.success ? (
+
+ ) : (
+
+ )}
+
+ #{r.index}
+
+
+ {r.email || r.rt}
+
+ {r.success && r.account_id ? (
+
+ ID: {r.account_id}
+
+ ) : r.error ? (
+
+ {r.error}
+
+ ) : null}
+
+ ))}
+
+ )}
+
+ {/* Summary */}
+ {status && !status.running && status.completed > 0 && (
+
+
导入完成
+
+
+
总计
+
{status.completed}
+
+
+
成功
+
{status.success}
+
+
+
+
+ 耗时: {(status.elapsed_ms / 1000).toFixed(1)} 秒
+
+
+ )}
+
+
+
+
+ )
+}
diff --git a/frontend/src/pages/index.ts b/frontend/src/pages/index.ts
index dfd4745..8d44ce5 100644
--- a/frontend/src/pages/index.ts
+++ b/frontend/src/pages/index.ts
@@ -10,5 +10,6 @@ export { default as Cleaner } from './Cleaner'
export { default as TeamReg } from './TeamReg'
export { default as CodexProxyConfig } from './CodexProxyConfig'
export { default as S2AStats } from './S2AStats'
+export { default as BatchRTImport } from './BatchRTImport'