166 lines
9.1 KiB
C#
166 lines
9.1 KiB
C#
using CoreCms.Net.Caching.AutoMate.RedisCache;
|
||
using CoreCms.Net.Configuration;
|
||
using CoreCms.Net.IServices;
|
||
|
||
using DotLiquid.Tags;
|
||
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
|
||
using SqlSugar;
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinUserInfoBatchGetRequest.Types;
|
||
|
||
namespace CoreCms.Net.Task
|
||
{
|
||
/// <summary>
|
||
/// 预约定时清理
|
||
/// </summary>
|
||
public class SQReservationJob
|
||
{
|
||
private readonly ISQReservationsServices _reservationsServices;
|
||
private readonly ISQReservationParticipantsServices _participantsServices;
|
||
private readonly IRedisOperationRepository _redisOperationRepository;
|
||
public SQReservationJob(ISQReservationsServices reservationsServices,
|
||
ISQReservationParticipantsServices participantsServices,
|
||
IRedisOperationRepository redisOperationRepository)
|
||
{
|
||
_reservationsServices = reservationsServices;
|
||
_participantsServices = participantsServices;
|
||
_redisOperationRepository = redisOperationRepository;
|
||
}
|
||
|
||
public async System.Threading.Tasks.Task Execute()
|
||
{
|
||
Console.WriteLine($"[SQReservationJob] 执行开始 @ {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||
var now = DateTime.Now;
|
||
Console.WriteLine("[SQReservationJob] 步骤1:将已到结束时间的预约置为已结束(3)");
|
||
// 1) 将已到结束时间的预约置为已结束(3)
|
||
var endedList = await _reservationsServices.QueryListByClauseAsync(
|
||
r => r.status == 2 && r.end_time <= now,
|
||
r => r.id, OrderByType.Asc);
|
||
Console.WriteLine($"[SQReservationJob] 步骤1:查询到待结束记录数量 = {endedList?.Count ?? 0}");
|
||
if (endedList != null && endedList.Count > 0)
|
||
{
|
||
var changedCount = 0;
|
||
foreach (var item in endedList)
|
||
{
|
||
Console.WriteLine($"[SQReservationJob] 步骤1:预约ID={item.id} 从状态2->3,end_time={item.end_time:yyyy-MM-dd HH:mm:ss}");
|
||
item.status = 3;
|
||
item.updated_at = now;
|
||
changedCount++;
|
||
}
|
||
Console.WriteLine($"[SQReservationJob] 步骤1:批量更新记录数 = {changedCount}");
|
||
await _reservationsServices.UpdateAsync(endedList);
|
||
}
|
||
//Console.WriteLine("[SQReservationJob] 步骤2:将开始时间已到且未结束的预约置为进行中(2)");
|
||
//// 2) 将开始时间已到且未结束的预约置为进行中(2)
|
||
//var startedList = await _reservationsServices.QueryListByClauseAsync(
|
||
// r => r.status == 1 && r.start_time <= now && r.end_time > now,
|
||
// r => r.id, OrderByType.Asc);
|
||
//Console.WriteLine($"[SQReservationJob] 步骤2:查询到待置为进行中记录数量 = {startedList?.Count ?? 0}");
|
||
//if (startedList != null && startedList.Count > 0)
|
||
//{
|
||
// var changedCount = 0;
|
||
// foreach (var item in startedList)
|
||
// {
|
||
// Console.WriteLine($"[SQReservationJob] 步骤2:预约ID={item.id} 从状态1->2,start_time={item.start_time:yyyy-MM-dd HH:mm:ss} end_time={item.end_time:yyyy-MM-dd HH:mm:ss}");
|
||
// item.status = 2;
|
||
// item.updated_at = now;
|
||
// changedCount++;
|
||
// }
|
||
// Console.WriteLine($"[SQReservationJob] 步骤2:批量更新记录数 = {changedCount}");
|
||
// await _reservationsServices.UpdateAsync(startedList);
|
||
//}
|
||
|
||
|
||
// 2.5) 到达开始时间但人数未满的预约置为取消(4)
|
||
Console.WriteLine("[SQReservationJob] 步骤2.5:到达开始时间但人数未满的预约置为取消(4)");
|
||
var toCancelList = await _reservationsServices.QueryListByClauseAsync(
|
||
r => r.status == 0 && r.start_time <= now && r.end_time > now,
|
||
r => r.id, OrderByType.Asc);
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:查询到候选取消记录数量 = {toCancelList?.Count ?? 0}");
|
||
if (toCancelList != null && toCancelList.Count > 0)
|
||
{
|
||
var examineCount = 0;
|
||
foreach (var item in toCancelList)
|
||
{
|
||
var count = await _participantsServices.GetCountAsync(p => p.reservation_id == item.id && p.status == 0);
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:预约ID={item.id} 参与人数={count}/{item.player_count},start_time={item.start_time:yyyy-MM-dd HH:mm:ss}");
|
||
if (count < item.player_count)
|
||
{
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:预约ID={item.id} 人数未满,置为取消(4)");
|
||
item.status = 4;
|
||
item.updated_at = now;
|
||
}
|
||
examineCount++;
|
||
}
|
||
var toCancelChanged = toCancelList.Where(x => x.status == 4).ToList();
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:需要更新为取消的记录数 = {toCancelChanged.Count}");
|
||
if (toCancelChanged.Count > 0)
|
||
{
|
||
await _reservationsServices.UpdateAsync(toCancelChanged);
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:已更新为取消的记录数 = {toCancelChanged.Count}");
|
||
foreach (var item in toCancelChanged)
|
||
{
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:准备通知预约ID={item.id} 的参与用户");
|
||
var userList = await _participantsServices.QueryListByClauseAsync(p => p.reservation_id == item.id && p.status == 0);
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:预约ID={item.id} 需通知用户数量 = {userList.Count}");
|
||
await _reservationsServices.NotifyReservationFailedAsync(item, userList);
|
||
Console.WriteLine($"[SQReservationJob] 步骤2.5:预约ID={item.id} 组局失败通知入队完成");
|
||
}
|
||
}
|
||
}
|
||
|
||
// 3) 开始前30分钟内,人数已凑齐则置为锁定(1)
|
||
Console.WriteLine("[SQReservationJob] 步骤3:开始前30分钟内,人数已凑齐则置为锁定(1)");
|
||
var threshold = now.AddMinutes(30);
|
||
var toLockList = await _reservationsServices.QueryListByClauseAsync(
|
||
r => r.status == 0 && r.start_time > now && r.start_time <= threshold,
|
||
r => r.id, OrderByType.Asc);
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:查询到候选锁定记录数量 = {toLockList?.Count ?? 0},阈值时间={threshold:yyyy-MM-dd HH:mm:ss}");
|
||
if (toLockList != null && toLockList.Count > 0)
|
||
{
|
||
foreach (var item in toLockList)
|
||
{
|
||
// 当前有效参与人数(未退出)
|
||
var count = await _participantsServices.GetCountAsync(p => p.reservation_id == item.id && p.status == 0);
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:预约ID={item.id} 参与人数={count}/{item.player_count},start_time={item.start_time:yyyy-MM-dd HH:mm:ss}");
|
||
if (count >= item.player_count)
|
||
{
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:预约ID={item.id} 人数已满,置为锁定(1)");
|
||
item.status = 1;
|
||
item.updated_at = now;
|
||
}
|
||
}
|
||
// 仅更新被修改的项
|
||
var changed = toLockList.Where(x => x.status == 1).ToList();
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:需要更新为锁定的记录数 = {changed.Count}");
|
||
if (changed.Count > 0)
|
||
{
|
||
await _reservationsServices.UpdateAsync(changed);
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:已更新为锁定的记录数 = {changed.Count}");
|
||
foreach (var item in changed)
|
||
{
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:准备通知预约ID={item.id} 的参与用户");
|
||
var userList = await _participantsServices.QueryListByClauseAsync(p => p.reservation_id == item.id && p.status == 0);
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:预约ID={item.id} 需通知用户数量 = {userList.Count}");
|
||
await _reservationsServices.NotifyReservationSuccessAsync(item, userList);
|
||
Console.WriteLine($"[SQReservationJob] 步骤3:预约ID={item.id} 组局成功通知入队完成");
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
Console.WriteLine($"[SQReservationJob] 执行结束 @ {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||
}
|
||
}
|
||
}
|