From 40a9da0809b315a49d7bdad1354c2c2fb290d53c Mon Sep 17 00:00:00 2001 From: kyx236 Date: Sat, 7 Feb 2026 02:20:50 +0800 Subject: [PATCH] fix(team_process): Clean up stuck processing owners on startup and batch completion - Add CleanupStuckProcessingOwners database method to reset owners stuck in processing status back to valid state - Call cleanup routine on application startup to recover from previous abnormal exits - Call cleanup routine after batch processing completes to ensure no orphaned processing states remain - Add markOwnerResult calls in processSingleTeam when team invitations are full to properly track owner status - Prevents owners from being permanently stuck in processing state due to unexpected shutdowns or errors --- backend/cmd/main.go | 5 +++++ backend/internal/api/team_process.go | 9 +++++++++ backend/internal/database/sqlite.go | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/backend/cmd/main.go b/backend/cmd/main.go index 0445a1b..3991581 100644 --- a/backend/cmd/main.go +++ b/backend/cmd/main.go @@ -85,6 +85,11 @@ func main() { fmt.Printf("%s[清理]%s 已清理 %d 个遗留的运行中批次记录\n", colorYellow, colorReset, affected) } + // 启动时清理遗留的 processing 状态母号(上次异常退出可能残留) + if affected, err := database.Instance.CleanupStuckProcessingOwners(); err == nil && affected > 0 { + fmt.Printf("%s[清理]%s 已重置 %d 个残留的处理中母号为有效状态\n", colorYellow, colorReset, affected) + } + // 启动自动补号检查器(需在前端开启开关才会实际补号) api.StartAutoAddService() diff --git a/backend/internal/api/team_process.go b/backend/internal/api/team_process.go index 621e88f..ddc2242 100644 --- a/backend/internal/api/team_process.go +++ b/backend/internal/api/team_process.go @@ -367,6 +367,13 @@ func runTeamProcess(req TeamProcessRequest) { defer func() { teamProcessState.Running = false + // 清理残留的 processing 状态母号,重置为 valid + if database.Instance != nil { + if affected, err := database.Instance.CleanupStuckProcessingOwners(); err == nil && affected > 0 { + logger.Warning(fmt.Sprintf("批次结束,重置了 %d 个残留的处理中母号为有效状态", affected), "", "team") + } + } + // 无论任务是正常完成还是异常中断,都更新批次记录状态 if database.Instance != nil && batchID > 0 { errorsStr := "" @@ -993,6 +1000,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul result.AddedToS2A = int(atomic.LoadInt32(&s2aSuccessCount)) result.Errors = append(result.Errors, "Team 邀请已满") result.DurationMs = time.Since(startTime).Milliseconds() + markOwnerResult(result.AddedToS2A > 0) return result } @@ -1027,6 +1035,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul result.AddedToS2A = int(atomic.LoadInt32(&s2aSuccessCount)) result.Errors = append(result.Errors, "Team 邀请已满") result.DurationMs = time.Since(startTime).Milliseconds() + markOwnerResult(result.AddedToS2A > 0) return result } diff --git a/backend/internal/database/sqlite.go b/backend/internal/database/sqlite.go index ba077b5..03cd12c 100644 --- a/backend/internal/database/sqlite.go +++ b/backend/internal/database/sqlite.go @@ -627,6 +627,15 @@ func (d *DB) CleanupStuckBatchRuns() (int64, error) { return result.RowsAffected() } +// CleanupStuckProcessingOwners 清理卡住的 processing 状态母号,重置为 valid +func (d *DB) CleanupStuckProcessingOwners() (int64, error) { + result, err := d.db.Exec(`UPDATE team_owners SET status = 'valid' WHERE status = 'processing'`) + if err != nil { + return 0, err + } + return result.RowsAffected() +} + // GetBatchRunStats 获取批次统计 func (d *DB) GetBatchRunStats() map[string]interface{} { stats := make(map[string]interface{})