Просмотр исходного кода

update có thể add giải tháng thủ công hoặc tự động

student 3 недель назад
Родитель
Сommit
33009d77a5

+ 27 - 12
Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/Services/GameMonthlyWinnerWorker.cs

@@ -84,15 +84,40 @@ namespace Kitty_Fall.Woker.Services
             var monthKey = targetMonth.Year * 100 + targetMonth.Month;
 
             var draw = await EnsureDrawAsync(dbContext, monthKey, cancellationToken);
-            if (draw.Status >= DrawStatusCompleted)
+            if (draw.Status == DrawStatusCompleted)
             {
                 log.Debug($"Monthly winner already completed. monthKey={monthKey}, drawId={draw.DrawId}");
                 return;
             }
 
+            if (draw.Status != DrawStatusNew)
+            {
+                // LOCKED/DRAWING la ky da tung bat dau. Khong tu tiep tuc sau loi/restart;
+                // admin phai doi soat va quyet dinh xu ly thu cong.
+                log.Warn($"Monthly winner requires manual review. monthKey={monthKey}, drawId={draw.DrawId}, status={draw.Status}");
+                return;
+            }
+
+            var startedAt = DateTime.Now;
+            // Claim ky quay truoc khi sinh ticket/chon winner. UPDATE co dieu kien bao dam
+            // nhieu instance worker khong the cung xu ly mot thang.
+            var claimed = await dbContext.GameMonthlyDraws
+                .Where(x => x.DrawId == draw.DrawId && x.Status == DrawStatusNew)
+                .ExecuteUpdateAsync(setters => setters
+                    .SetProperty(x => x.Status, DrawStatusDrawing)
+                    .SetProperty(x => x.UpdatedTime, startedAt), cancellationToken);
+            if (claimed != 1)
+            {
+                log.Warn($"Monthly winner was claimed by another worker. monthKey={monthKey}, drawId={draw.DrawId}");
+                return;
+            }
+
+            draw.Status = DrawStatusDrawing;
+            draw.UpdatedTime = startedAt;
+
             await EnsureTicketsAsync(dbContext, draw, cancellationToken);
 
-            if (GetBool("MonthlyWinner:AutoSelectDraftWinners", true))
+            if (GetBool("MonthlyWinner:AutoSelectDraftWinners", false))
             {
                 await EnsureDraftWinnersAsync(dbContext, draw, cancellationToken);
             }
@@ -128,16 +153,11 @@ 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)
             {
-                draw.Status = DrawStatusLocked;
-                draw.UpdatedTime = DateTime.Now;
-                await dbContext.SaveChangesAsync(cancellationToken);
                 return;
             }
 
@@ -203,7 +223,6 @@ namespace Kitty_Fall.Woker.Services
 
             draw.TotalEligible = totalEligible;
             draw.TotalTicket = totalTicket;
-            draw.Status = DrawStatusLocked;
             draw.UpdatedTime = now;
 
             await dbContext.SaveChangesAsync(cancellationToken);
@@ -236,10 +255,6 @@ namespace Kitty_Fall.Woker.Services
                 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
                 .AsNoTracking()

+ 5 - 3
Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/appsettings.Development.json

@@ -18,9 +18,11 @@
   "MonthlyWinner": {
     // Bat/tat worker tu sinh ky quay, ticket va winner draft cho giai thang.
     "AutoGenerate": true,
-    // Neu true, worker tu chon winner nhap tu danh sach ticket de CMS duyet.
-    "AutoSelectDraftWinners": true,
-    // Neu true, winner duoc cong bo luon; neu false CMS doi status 0 -> 1.
+    // false: worker chi sinh ticket, admin tu chon winner tren CMS.
+    // true: worker tu chon winner draft tu ticket, CMS van phai duyet.
+    "AutoSelectDraftWinners": false,
+    // Chi co tac dung khi AutoSelectDraftWinners=true.
+    // true: winner tu dong ANNOUNCED; false: winner o DRAFT cho CMS duyet.
     "AutoAnnounceWinners": false,
     // So giay giua moi lan worker quet xu ly giai thang.
     "IntervalSeconds": 3600,

+ 5 - 3
Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/appsettings.json

@@ -18,9 +18,11 @@
   "MonthlyWinner": {
     // Bat/tat worker tu sinh ky quay, ticket va winner draft cho giai thang.
     "AutoGenerate": true,
-    // Neu true, worker tu chon winner nhap tu danh sach ticket de CMS duyet.
-    "AutoSelectDraftWinners": true,
-    // Neu true, winner duoc cong bo luon; neu false CMS doi status 0 -> 1.
+    // false: worker chi sinh ticket, admin tu chon winner tren CMS.
+    // true: worker tu chon winner draft tu ticket, CMS van phai duyet.
+    "AutoSelectDraftWinners": false,
+    // Chi co tac dung khi AutoSelectDraftWinners=true. Production nen de false.
+    // true: winner tu dong ANNOUNCED; false: winner o DRAFT cho CMS duyet.
     "AutoAnnounceWinners": false,
     // So giay giua moi lan worker quet xu ly giai thang.
     "IntervalSeconds": 3600,