using HoneyBox.Core.Interfaces; using HoneyBox.Model.Data; using HoneyBox.Model.Entities; using HoneyBox.Model.Models.Task; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace HoneyBox.Core.Services; /// /// 任务服务实现 /// public class TaskService : ITaskService { private readonly HoneyBoxDbContext _dbContext; private readonly ILogger _logger; public TaskService(HoneyBoxDbContext dbContext, ILogger logger) { _dbContext = dbContext; _logger = logger; } /// public async Task GetTaskListAsync(int userId, int type) { // 获取任务列表 var tasks = await _dbContext.Tasks .Where(t => t.Type == type && t.DeletedAt == null) .OrderByDescending(t => t.Sort) .ThenByDescending(t => t.Id) .ToListAsync(); var taskDtos = new List(); foreach (var task in tasks) { // 计算任务周期时间范围 var (startTime, endTime) = GetTaskPeriod(task.Type); // 计算任务进度 int completedCount = await CalculateTaskProgress(userId, task.Cate, startTime); // 判断是否已完成 int targetNumber = task.Number ?? 0; int isComplete; int percentage; int ywcCount; if (completedCount >= targetNumber) { isComplete = 1; percentage = 100; ywcCount = targetNumber; } else { isComplete = 0; percentage = targetNumber > 0 ? (int)Math.Round((double)completedCount / targetNumber * 100) : 0; ywcCount = completedCount; } // 检查是否已领取 var hasClaimed = await _dbContext.UserTasks .AnyAsync(ut => ut.UserId == userId && ut.TaskId == task.Id && ut.CreatedAt >= startTime && ut.CreatedAt <= endTime && ut.DeletedAt == null); if (hasClaimed) { isComplete = 2; // 已领取 } taskDtos.Add(new TaskDto { Id = task.Id, Type = task.Type, Cate = task.Cate, Title = task.Title, Number = targetNumber, ZNumber = task.ZNumber ?? 0, IsComplete = isComplete, Percentage = percentage, YwcCount = ywcCount }); } return new TaskListResponse { TaskList = taskDtos }; } /// public async Task ClaimTaskRewardAsync(int userId, int taskListId) { // 获取任务信息 var task = await _dbContext.Tasks .FirstOrDefaultAsync(t => t.Id == taskListId && t.DeletedAt == null); if (task == null) { throw new InvalidOperationException("任务不存在"); } // 计算任务周期时间范围 var (startTime, endTime) = GetTaskPeriod(task.Type); // 检查任务是否已完成 int completedCount = await CalculateTaskProgress(userId, task.Cate, startTime); int targetNumber = task.Number ?? 0; if (completedCount < targetNumber) { throw new InvalidOperationException("任务未完成"); } // 检查是否已领取 var hasClaimed = await _dbContext.UserTasks .AnyAsync(ut => ut.UserId == userId && ut.TaskId == taskListId && ut.CreatedAt >= startTime && ut.CreatedAt <= endTime && ut.DeletedAt == null); if (hasClaimed) { throw new InvalidOperationException("你已经领取过了"); } // 开始事务 using var transaction = await _dbContext.Database.BeginTransactionAsync(); try { var now = DateTime.Now; // 创建用户任务记录 var userTask = new UserTask { UserId = userId, TaskId = taskListId, Type = task.Type, Cate = task.Cate, IsImportant = task.IsImportant, Number = task.Number, ZNumber = task.ZNumber, CreatedAt = now, UpdatedAt = now }; await _dbContext.UserTasks.AddAsync(userTask); // 发放欧气值奖励 int reward = task.ZNumber ?? 0; int currentOuQi = 0; if (reward > 0) { var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.Id == userId); if (user != null) { user.OuQi = (user.OuQi ?? 0) + reward; currentOuQi = user.OuQi ?? 0; // 重新计算欧气等级 user.OuQiLevel = CalculateOuQiLevel(currentOuQi); user.UpdatedAt = now; // 记录欧气值变动 var profitOuQi = new ProfitOuQi { UserId = userId, ChangeMoney = reward, Money = currentOuQi, Type = 1, // 完成任务 Content = "完成任务", CreatedAt = now }; await _dbContext.ProfitOuQis.AddAsync(profitOuQi); } } await _dbContext.SaveChangesAsync(); await transaction.CommitAsync(); _logger.LogInformation("用户 {UserId} 领取任务 {TaskId} 奖励 {Reward} 欧气值", userId, taskListId, reward); return new ClaimTaskRewardResponse { Reward = reward, CurrentOuQi = currentOuQi }; } catch (Exception ex) { await transaction.RollbackAsync(); _logger.LogError(ex, "用户 {UserId} 领取任务 {TaskId} 奖励失败", userId, taskListId); throw new InvalidOperationException("网络故障, 请稍后再试"); } } /// /// 获取任务周期时间范围 /// /// 任务类型: 1=每日, 2=每周 /// 开始时间和结束时间 private (DateTime startTime, DateTime endTime) GetTaskPeriod(int taskType) { var now = DateTime.Now; if (taskType == 1) { // 每日任务: 当天 00:00:00 到 23:59:59 var startTime = now.Date; var endTime = now.Date.AddDays(1).AddSeconds(-1); return (startTime, endTime); } else { // 每周任务: 本周一 00:00:00 到 本周日 23:59:59 var dayOfWeek = (int)now.DayOfWeek; // 周日是0,需要转换为7 if (dayOfWeek == 0) dayOfWeek = 7; var startTime = now.Date.AddDays(-(dayOfWeek - 1)); // 本周一 var endTime = startTime.AddDays(7).AddSeconds(-1); // 本周日 23:59:59 return (startTime, endTime); } } /// /// 计算任务进度 /// /// 用户ID /// 任务分类: 1=邀请, 2=抽赏 /// 开始时间 /// 完成数量 private async Task CalculateTaskProgress(int userId, int taskCate, DateTime startTime) { if (taskCate == 1) { // 邀请好友注册: 统计推荐人为当前用户且注册时间在周期内的用户数 return await _dbContext.Users .CountAsync(u => u.Pid == userId && u.CreatedAt >= startTime); } else if (taskCate == 2) { // 抽赏任务: 统计已支付订单数 (pay_type < 10 且 status = 1) // 将DateTime转换为Unix时间戳进行比较 var startTimestamp = (int)((DateTimeOffset)startTime).ToUnixTimeSeconds(); return await _dbContext.Orders .CountAsync(o => o.UserId == userId && o.PayType < 10 && o.Status == 1 && o.Addtime >= startTimestamp); } return 0; } /// /// 根据欧气值计算欧气等级 /// /// 当前欧气值 /// 欧气等级 private static int CalculateOuQiLevel(int ouQi) { // 等级阈值: 0=普通, 1=青铜(100), 2=白银(500), 3=黄金(1000), // 4=铂金(3000), 5=钻石(6000), 6=星耀(10000), 7=王者(20000) if (ouQi >= 20000) return 7; if (ouQi >= 10000) return 6; if (ouQi >= 6000) return 5; if (ouQi >= 3000) return 4; if (ouQi >= 1000) return 3; if (ouQi >= 500) return 2; if (ouQi >= 100) return 1; return 0; } }