diff --git a/Build_God_Api/Build_God_Api/Services/DailyMissionService.cs b/Build_God_Api/Build_God_Api/Services/DailyMissionService.cs index 08552c0..5760e58 100644 --- a/Build_God_Api/Build_God_Api/Services/DailyMissionService.cs +++ b/Build_God_Api/Build_God_Api/Services/DailyMissionService.cs @@ -22,7 +22,8 @@ namespace Build_God_Api.Services Task ClaimReward(int characterId, int dailyMissionId); /// - /// 检查并完成所有到期任务 + /// 检查进行中任务的时限:仅在客观目标(击杀/收集等)已全部达成时标记为完成; + /// 超时且未达成的重置为待接取并清除进度记录。 /// Task CheckAndCompleteExpiredMissions(); @@ -316,6 +317,25 @@ namespace Build_God_Api.Services return true; } + private async Task AreDailyMissionObjectivesSatisfied(int dailyMissionId, Mission mission) + { + if (mission.Progresses == null || mission.Progresses.Count == 0) + return false; + + var characterProgressList = await _db.Queryable() + .Where(x => x.DailyMissionId == dailyMissionId) + .ToListAsync(); + + foreach (var p in mission.Progresses) + { + var cp = characterProgressList.FirstOrDefault(x => x.MissionProgressId == p.Id); + if (cp == null || cp.CurrentCount < p.TargetCount) + return false; + } + + return true; + } + public async Task CheckAndCompleteExpiredMissions() { var now = GetBeijingTime(); @@ -324,12 +344,45 @@ namespace Build_God_Api.Services .Where(x => x.Status == DailyMissionStatus.InProgress && x.EndTime <= now) .ToListAsync(); - foreach (var mission in expiredMissions) + foreach (var dm in expiredMissions) { - mission.Status = DailyMissionStatus.Completed; - await _db.Updateable(mission).ExecuteCommandAsync(); + var mission = await _db.Queryable() + .Includes(x => x.Progresses) + .FirstAsync(x => x.Id == dm.MissionId); + + if (mission == null) + continue; + + if (await AreDailyMissionObjectivesSatisfied(dm.Id, mission)) + { + dm.Status = DailyMissionStatus.Completed; + await _db.Updateable(dm).ExecuteCommandAsync(); - _logger.LogInformation("任务 {MissionId} 已自动完成,等待角色 {CharacterId} 领取", mission.MissionId, mission.CharacterId); + _logger.LogInformation( + "每日任务实例 {DailyMissionId}(配置 {MissionId})已在时限内达成目标,角色 {CharacterId} 待领取", + dm.Id, dm.MissionId, dm.CharacterId); + } + else + { + await _db.Deleteable() + .Where(x => x.DailyMissionId == dm.Id) + .ExecuteCommandAsync(); + + dm.Status = DailyMissionStatus.Pending; + dm.StartTime = null; + dm.EndTime = null; + await _db.Updateable(dm).ExecuteCommandAsync(); + + var character = await _db.Queryable() + .FirstAsync(x => x.Id == dm.CharacterId); + + var msg = $"【{mission.Title}】未在限时内完成目标,任务已重置为待接取。"; + await _chatService.AddMessageAsync(dm.CharacterId, character?.Name ?? "玩家", msg, ChatMessageType.System); + + _logger.LogInformation( + "角色 {CharacterId} 的每日任务实例 {DailyMissionId} 超时未完成,已重置为待接取", + dm.CharacterId, dm.Id); + } } } diff --git a/Build_God_Game/src/views/DailyMissionView.vue b/Build_God_Game/src/views/DailyMissionView.vue index e306164..176a082 100644 --- a/Build_God_Game/src/views/DailyMissionView.vue +++ b/Build_God_Game/src/views/DailyMissionView.vue @@ -214,10 +214,10 @@ const MissionCardContent = defineComponent({ h('span', { class: ['card-status', getStatusClass(props.mission.status)] }, getStatusText(props.mission.status)), ]), h('div', { class: 'card-desc' }, props.mission.missionDescription), - //h('div', { class: 'card-meta-row' }, [ - //h('span', { class: ['difficulty-badge', getDifficultyClass(props.mission.difficulty)] }, getDifficultyLabel(props.mission.difficulty)), - //h('span', { class: 'time-badge' }, `预计 ${props.mission.spendTimeMinutes} 分钟`), - //]), + h('div', { class: 'card-meta-row' }, [ + //h('span', { class: ['difficulty-badge', getDifficultyClass(props.mission.difficulty)] }, getDifficultyLabel(props.mission.difficulty)), + h('span', { class: 'time-badge' }, `限时 ${props.mission.spendTimeMinutes} 分钟`), + ]), props.mission.progresses && props.mission.progresses.length > 0 ? h('div', { class: 'objective-panel' }, [ h('span', { class: 'objective-label' }, '任务目标'), @@ -599,14 +599,11 @@ const MissionCardContent = defineComponent({ font-weight: 700; } -.time-badge { - padding: 4px 10px; - border-radius: 999px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.08); - color: #9ca3af; - font-size: 0.72rem; - font-weight: 600; +:deep(.time-badge) { + color: #aaaaaa; + font-size: 0.84rem; + line-height: 1.55; + margin: 0; } .difficulty-normal {