瀏覽代碼

chặn tránh trả giải thừa, thiếu khi hệ thống lỗi

student 3 周之前
父節點
當前提交
c68dc50df5
共有 1 個文件被更改,包括 56 次插入7 次删除
  1. 56 7
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/Services/GameMonthlyWinnerWorker.cs

+ 56 - 7
Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/Services/GameMonthlyWinnerWorker.cs

@@ -9,8 +9,9 @@ namespace Kitty_Fall.Woker.Services
     public class GameMonthlyWinnerWorker : BackgroundService
     {
         private const byte DrawStatusNew = 0;
-        private const byte DrawStatusTicketReady = 1;
-        private const byte DrawStatusWinnerDraft = 2;
+        private const byte DrawStatusLocked = 1;
+        private const byte DrawStatusDrawing = 2;
+        private const byte DrawStatusCompleted = 3;
 
         private const byte WinnerStatusDraft = 0;
         private const byte WinnerStatusAnnounced = 1;
@@ -58,12 +59,22 @@ namespace Kitty_Fall.Woker.Services
             var monthKey = targetMonth.Year * 100 + targetMonth.Month;
 
             var draw = await EnsureDrawAsync(dbContext, monthKey, cancellationToken);
+            if (draw.Status >= DrawStatusCompleted)
+            {
+                log.Debug($"Monthly winner already completed. monthKey={monthKey}, drawId={draw.DrawId}");
+                return;
+            }
+
             await EnsureTicketsAsync(dbContext, draw, cancellationToken);
 
             if (GetBool("MonthlyWinner:AutoSelectDraftWinners", true))
             {
                 await EnsureDraftWinnersAsync(dbContext, draw, cancellationToken);
             }
+            else
+            {
+                await MarkDrawCompletedAsync(dbContext, draw, cancellationToken);
+            }
         }
 
         private async Task<GameMonthlyDraw> EnsureDrawAsync(ModelContext dbContext, int monthKey, CancellationToken cancellationToken)
@@ -92,10 +103,18 @@ namespace Kitty_Fall.Woker.Services
 
         private async Task EnsureTicketsAsync(ModelContext dbContext, GameMonthlyDraw draw, CancellationToken cancellationToken)
         {
+            if (draw.Status >= DrawStatusLocked) return;
+
             var hasTicket = await dbContext.GameMonthlyDrawTickets
                 .AsNoTracking()
                 .AnyAsync(x => x.DrawId == draw.DrawId, cancellationToken);
-            if (hasTicket) return;
+            if (hasTicket)
+            {
+                draw.Status = DrawStatusLocked;
+                draw.UpdatedTime = DateTime.Now;
+                await dbContext.SaveChangesAsync(cancellationToken);
+                return;
+            }
 
             var now = DateTime.Now;
             // Chi user dat diem toi thieu moi duoc sinh ticket tham gia giai thang.
@@ -159,7 +178,7 @@ namespace Kitty_Fall.Woker.Services
 
             draw.TotalEligible = totalEligible;
             draw.TotalTicket = totalTicket;
-            draw.Status = DrawStatusTicketReady;
+            draw.Status = DrawStatusLocked;
             draw.UpdatedTime = now;
 
             await dbContext.SaveChangesAsync(cancellationToken);
@@ -167,20 +186,34 @@ namespace Kitty_Fall.Woker.Services
 
         private async Task EnsureDraftWinnersAsync(ModelContext dbContext, GameMonthlyDraw draw, CancellationToken cancellationToken)
         {
+            if (draw.Status >= DrawStatusCompleted) return;
+
             var prizeConfigs = await dbContext.GameMonthlyPrizeConfigs
                 .AsNoTracking()
                 .Where(x => x.Status != false)
                 .OrderBy(x => x.DisplayOrder)
                 .ThenBy(x => x.PrizeConfigId)
                 .ToListAsync(cancellationToken);
-            if (prizeConfigs.Count == 0) return;
+            if (prizeConfigs.Count == 0)
+            {
+                await MarkDrawCompletedAsync(dbContext, draw, cancellationToken);
+                return;
+            }
 
             var tickets = await dbContext.GameMonthlyDrawTickets
                 .AsNoTracking()
                 .Where(x => x.DrawId == draw.DrawId)
                 .OrderBy(x => x.TicketNo)
                 .ToListAsync(cancellationToken);
-            if (tickets.Count == 0) return;
+            if (tickets.Count == 0)
+            {
+                await MarkDrawCompletedAsync(dbContext, draw, cancellationToken);
+                return;
+            }
+
+            draw.Status = DrawStatusDrawing;
+            draw.UpdatedTime = DateTime.Now;
+            await dbContext.SaveChangesAsync(cancellationToken);
 
             var excludedMsisdns = await GetRecentWinnerMsisdnsAsync(dbContext, draw.MonthKey, cancellationToken);
             var existingWinners = await dbContext.GameMonthlyWinners
@@ -234,11 +267,27 @@ namespace Kitty_Fall.Woker.Services
                 }
             }
 
-            draw.Status = DrawStatusWinnerDraft;
+            draw.Status = DrawStatusCompleted;
             draw.DrawTime = now;
             draw.UpdatedTime = now;
 
             await dbContext.SaveChangesAsync(cancellationToken);
+            log.Info($"Monthly winner completed. monthKey={draw.MonthKey}, drawId={draw.DrawId}, totalEligible={draw.TotalEligible}, totalTicket={draw.TotalTicket}");
+        }
+
+        private static async Task MarkDrawCompletedAsync(
+            ModelContext dbContext,
+            GameMonthlyDraw draw,
+            CancellationToken cancellationToken)
+        {
+            if (draw.Status >= DrawStatusCompleted) return;
+
+            var now = DateTime.Now;
+            draw.Status = DrawStatusCompleted;
+            draw.DrawTime ??= now;
+            draw.UpdatedTime = now;
+            await dbContext.SaveChangesAsync(cancellationToken);
+            log.Info($"Monthly winner completed without auto selection. monthKey={draw.MonthKey}, drawId={draw.DrawId}, totalEligible={draw.TotalEligible}, totalTicket={draw.TotalTicket}");
         }
 
         private async Task<HashSet<string>> GetRecentWinnerMsisdnsAsync(