feat: introduce a new Config page for managing site settings and proxy configurations, and add a Team Registration page with backend API support.
This commit is contained in:
@@ -44,6 +44,10 @@ type TeamRegState struct {
|
||||
cmd *exec.Cmd
|
||||
cancel context.CancelFunc
|
||||
stdin io.WriteCloser
|
||||
// 自动导入与退出控制
|
||||
autoImporting bool
|
||||
autoImported bool
|
||||
exitSignaled bool
|
||||
// 403 错误检测
|
||||
error403Count int // 403 错误计数
|
||||
error403Start time.Time // 计数开始时间
|
||||
@@ -104,6 +108,9 @@ func HandleTeamRegStart(w http.ResponseWriter, r *http.Request) {
|
||||
teamRegState.Logs = make([]string, 0)
|
||||
teamRegState.OutputFile = ""
|
||||
teamRegState.Imported = 0
|
||||
teamRegState.autoImporting = false
|
||||
teamRegState.autoImported = false
|
||||
teamRegState.exitSignaled = false
|
||||
teamRegState.error403Count = 0
|
||||
teamRegState.error403Start = time.Now()
|
||||
teamRegState.mu.Unlock()
|
||||
@@ -368,42 +375,25 @@ func runTeamRegProcess(config TeamRegConfig) {
|
||||
addTeamRegLog("[系统] 进程正常完成")
|
||||
}
|
||||
|
||||
// 查找输出文件
|
||||
outputFile := findLatestOutputFile(workDir)
|
||||
if outputFile != "" {
|
||||
teamRegState.mu.Lock()
|
||||
teamRegState.OutputFile = outputFile
|
||||
teamRegState.mu.Unlock()
|
||||
addTeamRegLog(fmt.Sprintf("[系统] 输出文件: %s", filepath.Base(outputFile)))
|
||||
// 查找输出文件
|
||||
outputFile := findLatestOutputFile(workDir)
|
||||
if outputFile != "" {
|
||||
teamRegState.mu.Lock()
|
||||
teamRegState.OutputFile = outputFile
|
||||
teamRegState.mu.Unlock()
|
||||
addTeamRegLog(fmt.Sprintf("[系统] 输出文件: %s", filepath.Base(outputFile)))
|
||||
|
||||
// 自动导入
|
||||
if config.AutoImport {
|
||||
addTeamRegLog("[系统] 自动导入账号到数据库...")
|
||||
count, err := importAccountsFromJSON(outputFile)
|
||||
if err != nil {
|
||||
addTeamRegLog(fmt.Sprintf("[错误] 导入失败: %v", err))
|
||||
} else {
|
||||
teamRegState.mu.Lock()
|
||||
teamRegState.Imported = count
|
||||
teamRegState.mu.Unlock()
|
||||
addTeamRegLog(fmt.Sprintf("[系统] 成功导入 %d 个账号", count))
|
||||
|
||||
// 导入成功后删除 JSON 文件
|
||||
if err := os.Remove(outputFile); err != nil {
|
||||
addTeamRegLog(fmt.Sprintf("[警告] 删除临时文件失败: %v", err))
|
||||
} else {
|
||||
addTeamRegLog(fmt.Sprintf("[系统] 已清理临时文件: %s", filepath.Base(outputFile)))
|
||||
}
|
||||
// 自动导入
|
||||
if config.AutoImport {
|
||||
addTeamRegLog("[系统] 自动导入账号到数据库...")
|
||||
tryAutoImport(outputFile, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发送回车退出程序(如果还在运行)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
if stdin != nil {
|
||||
fmt.Fprintf(stdin, "\n")
|
||||
// 发送回车退出程序(如果还在运行)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
signalTeamRegExit()
|
||||
}
|
||||
}
|
||||
|
||||
// readOutput 读取进程输出
|
||||
func readOutput(reader io.Reader, workDir string, config TeamRegConfig) {
|
||||
@@ -415,23 +405,26 @@ func readOutput(reader io.Reader, workDir string, config TeamRegConfig) {
|
||||
if trimmed != "" {
|
||||
addTeamRegLog(trimmed)
|
||||
|
||||
// 检测输出文件名(例如:结果已保存到: accounts-2-20260201-071558.json)
|
||||
if strings.Contains(trimmed, "结果已保存到") || strings.Contains(trimmed, "accounts-") && strings.Contains(trimmed, ".json") {
|
||||
// 尝试提取文件名
|
||||
if idx := strings.Index(trimmed, "accounts-"); idx >= 0 {
|
||||
endIdx := strings.Index(trimmed[idx:], ".json")
|
||||
if endIdx > 0 {
|
||||
fileName := trimmed[idx : idx+endIdx+5] // 包含 .json
|
||||
// 构建完整路径
|
||||
fullPath := filepath.Join(workDir, fileName)
|
||||
if _, err := os.Stat(fullPath); err == nil {
|
||||
// 检测输出文件名(例如:结果已保存到: accounts-2-20260201-071558.json)
|
||||
if strings.Contains(trimmed, "结果已保存到") || strings.Contains(trimmed, "accounts-") && strings.Contains(trimmed, ".json") {
|
||||
// 尝试提取文件名
|
||||
if idx := strings.Index(trimmed, "accounts-"); idx >= 0 {
|
||||
endIdx := strings.Index(trimmed[idx:], ".json")
|
||||
if endIdx > 0 {
|
||||
fileName := trimmed[idx : idx+endIdx+5] // 包含 .json
|
||||
// 构建完整路径
|
||||
fullPath := filepath.Join(workDir, fileName)
|
||||
teamRegState.mu.Lock()
|
||||
teamRegState.OutputFile = fullPath
|
||||
teamRegState.mu.Unlock()
|
||||
if config.AutoImport {
|
||||
go tryAutoImport(fullPath, config)
|
||||
}
|
||||
// 发送回车提示退出(有些程序会在完成后等待回车)
|
||||
signalTeamRegExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检测 403 错误
|
||||
if strings.Contains(trimmed, "403") {
|
||||
@@ -482,6 +475,80 @@ func check403AndStop() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// tryAutoImport 尝试自动导入(仅执行一次)
|
||||
func tryAutoImport(filePath string, config TeamRegConfig) {
|
||||
if !config.AutoImport || filePath == "" {
|
||||
return
|
||||
}
|
||||
|
||||
teamRegState.mu.Lock()
|
||||
if teamRegState.autoImported || teamRegState.autoImporting {
|
||||
teamRegState.mu.Unlock()
|
||||
return
|
||||
}
|
||||
teamRegState.autoImporting = true
|
||||
teamRegState.mu.Unlock()
|
||||
|
||||
var (
|
||||
count int
|
||||
err error
|
||||
)
|
||||
|
||||
// 等待文件稳定写入(最多重试几次)
|
||||
for i := 0; i < 5; i++ {
|
||||
if _, statErr := os.Stat(filePath); statErr != nil {
|
||||
err = statErr
|
||||
} else {
|
||||
count, err = importAccountsFromJSON(filePath)
|
||||
}
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
}
|
||||
|
||||
teamRegState.mu.Lock()
|
||||
teamRegState.autoImporting = false
|
||||
if err == nil {
|
||||
teamRegState.Imported = count
|
||||
teamRegState.autoImported = true
|
||||
}
|
||||
teamRegState.mu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
addTeamRegLog(fmt.Sprintf("[错误] 导入失败: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
addTeamRegLog(fmt.Sprintf("[系统] 成功导入 %d 个账号", count))
|
||||
|
||||
// 导入成功后删除 JSON 文件
|
||||
if err := os.Remove(filePath); err != nil {
|
||||
addTeamRegLog(fmt.Sprintf("[警告] 删除临时文件失败: %v", err))
|
||||
} else {
|
||||
addTeamRegLog(fmt.Sprintf("[系统] 已清理临时文件: %s", filepath.Base(filePath)))
|
||||
}
|
||||
}
|
||||
|
||||
// signalTeamRegExit 发送回车并关闭 stdin,提示程序退出
|
||||
func signalTeamRegExit() {
|
||||
teamRegState.mu.Lock()
|
||||
if teamRegState.exitSignaled {
|
||||
teamRegState.mu.Unlock()
|
||||
return
|
||||
}
|
||||
teamRegState.exitSignaled = true
|
||||
stdin := teamRegState.stdin
|
||||
teamRegState.mu.Unlock()
|
||||
|
||||
if stdin == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintln(stdin)
|
||||
_ = stdin.Close()
|
||||
}
|
||||
|
||||
// addTeamRegLog 添加日志
|
||||
func addTeamRegLog(log string) {
|
||||
teamRegState.mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user