using System.Threading.Tasks; using System; using Wicture.DbRESTFul.Infrastructure.Repository; using System.Linq; using Newtonsoft.Json.Linq; using System.Collections.Generic; using System.Data; using Wicture.DbRESTFul.Cache; using System.Security.Cryptography.X509Certificates; using Newtonsoft.Json; using System.Runtime.Intrinsics.X86; using JiaZhiQuan.Common.Models.VO; using JiaZhiQuan.Common.Models.PO; namespace JiaZhiQuan.Common { public static partial class RepositoryExtension { public class ActivityCzdTaskRecord { public int id { get; set; } public long userId { get; set; } public int betPoints { get; set; } public int betType { get; set; } public DateTime createAt { get; set; } public int gainPoints { get; set; } public int gameResult { get; set; } } public class ActivityCzdMockModel { public int fallUsers { get; set; } public int riseUsers { get; set; } public int points { get; set; } public DateTime execTime { get; set; } } public static async Task> GetCzdPointListByContract(this DbRESTFulRepository repository, RedisCacheProvider cacheProvider, int contractId) { var key = CacheKeys.ActivityCzdPointList(contractId); var list = await cacheProvider.Get>(key); if (list == null) { list = (await repository.QuerySingleOrDefaultAsync($"select pointsList from n_activity_czd_contract where id={contractId}") ?? string.Empty) .Split(',', StringSplitOptions.RemoveEmptyEntries) .Select(e => int.Parse(e)).ToList(); await cacheProvider.Set(key, list, CacheKeys.ActivityCzdPointListCacheSecs); } return list; } /// /// 获取随机人数和随机价值币 /// /// 包含 /// 包含 /// 0 双方都加同样的,2 仅跌的,1 仅涨的 public static async Task GenerateActivityCzdMockData(this DbRESTFulRepository repository, RedisCacheProvider cacheProvider, int contractId, int taskId, int minCount, int maxCount, int minutes, int mode = 0) { var pointsArr = await repository.GetCzdPointListByContract(cacheProvider, contractId); if (pointsArr.Count == 0) return false; var rand = new Random(); var count = rand.Next(minCount, maxCount + 1); if (count == 0) return true; var list = new List(); var maxBatch = Math.Min(count, 10); for (var i = 0; i < count; i++) { var time = DateTime.Now.AddMinutes(rand.NextDouble() * minutes); var batch = rand.Next(1, maxBatch + 1); var model = new ActivityCzdMockModel { execTime = time }; if (mode == 2 || mode == 0) { model.fallUsers = batch; } if (mode == 1 || mode == 0) { model.riseUsers = batch; } for (var j = 0; j < batch; j++) { model.points += pointsArr[rand.Next(Math.Min(3, pointsArr.Count))]; } if (mode == 0) { model.points *= 2; } list.Add(model); i += batch - 1; } await repository.QueryAsync($"insert into n_activity_czd_mock_action (taskId, fallUsers, riseUsers, points, execTime, createAt) values ({taskId}, @fallUsers, @riseUsers, @points, @execTime, now())", list, null, null, false); return true; } /// /// 结束某一个任务 /// /// 合约组编号 /// yyyy-MM-dd /// 1 涨 2 跌 3 平 public static async Task EndActivityCzdTask(this DbRESTFulRepository repository, int contractId, string date, int contractResult) { var task = await repository.QuerySingleOrDefaultAsync($"select t.id, t.activityId, t.contractId, c.contractName, t.date from n_activity_czd_task as t left join n_activity_czd_contract as c on t.contractId=c.id where t.contractId={contractId} and t.date='{date}' and t.contractResult=0"); if (task == null) return false; // 判断是否是最新的已结束的任务 var isNewTask = (await repository.QuerySingleOrDefaultAsync( $"select id from n_activity_czd_task where id>{task.id} and contractResult>0 limit 1")) == 0; var activityId = task.activityId; var activityName = await repository.QuerySingleOrDefaultAsync( $"select title from n_activity where id={activityId}"); var pointChangeDescription = $"活动奖励-{activityName}"; var allRecords = (await repository.QueryAsync($"select id, userId, betType, betPoints, createAt from n_activity_czd_task_records where taskId={task.id}")).ToList(); var risePoints = 0; var fallPoints = 0; foreach (var record in allRecords) { // 跌 if (record.betType == 2) { fallPoints += record.betPoints; } // 涨 else { risePoints += record.betPoints; } } var platformTotalPoints = 0; // 平台所出价值币 var totalWinPoints = 0; // 赢方总获取的价值币(不记成本) int totalPoints = contractResult == 2 ? risePoints : fallPoints; // 瓜分总价值币 int totalWinBetPoints = contractResult == 2 ? fallPoints : risePoints; // 赢方总投注价值币 var rate = totalWinBetPoints > 0 ? (double)totalPoints / totalWinBetPoints : 0; var winUserIds = new List(); foreach (var record in allRecords) { var win = (record.betType == 2 && contractResult == 2) || (record.betType != 2 && contractResult != 2); record.gameResult = win ? 1 : 2; if (win) { var p = (int)Math.Floor(rate * record.betPoints); if (p < 20) p = 20; totalWinPoints += p; record.gainPoints = record.betPoints + p; winUserIds.Add(record.userId); } else { record.gainPoints = 0; } } platformTotalPoints = totalWinPoints - totalPoints; var updateRecords = allRecords.Select(e => { return new { e.id, e.gainPoints, e.gameResult, }; }).ToList(); var updateStats = allRecords.Select(e => { return new { e.userId, e.createAt, win = e.gameResult == 1 ? 1 : 0, points = e.gainPoints - e.betPoints, }; }).ToList(); var pointsRecords = allRecords.Where(e => e.gainPoints > 0).Select(e => { return new { e.userId, points = e.gainPoints, }; }).ToList(); var execCount = 0; var taskEndTime = ((DateTime)task.date).ToString("yyyy-MM-dd 15:00:00"); using var conn = repository.ConnectionManager.GetConnection(false); conn.Open(); var trans = conn.BeginTransaction(); try { execCount = await repository.QuerySingleOrDefaultAsync($"update n_activity_czd_task set contractResult={contractResult}, extraPoints={platformTotalPoints} where id={task.id} and contractResult=0; select row_count() as count;", null, conn, trans); if (execCount > 0) { await repository.QueryAsync("update n_activity_czd_task_records set gainPoints=@gainPoints, remind=1, gameResult=@gameResult where id=@id and gameResult=0;", updateRecords, conn, trans); if (isNewTask) { await repository.QueryAsync(@$"update n_activity_czd_task_statistic set winTimes=winTimes+@win, continuousTimes=(case @win when 1 then continuousTimes+1 else 0 end), totalEarnPoints=totalEarnPoints+@points, lastJoinAt=(case @createAt($"update n_activity_czd_task_statistic set continuousTimes=0 where contractId={contractId} [and userId not in @userIds]", new { userIds = winUserIds.Count > 0 ? winUserIds : null }, conn, trans); } else { await repository.QueryAsync(@$"update n_activity_czd_task_statistic set winTimes=winTimes+@win, totalEarnPoints=totalEarnPoints+@points, lastJoinAt=(case @createAt 0) { await repository.QueryAsync($"insert into n_user_points_record(userId, points, `way`, extra, description, createAt, createAtDate) values(@userId, @points, 'ACTIVITY', '{activityId}', '{pointChangeDescription}', now(), now())", pointsRecords, conn, trans); await repository.QueryAsync($"update n_user_statistic set points=points+@points where userId=@userId", pointsRecords, conn, trans); } } trans.Commit(); } catch (Exception ex) { trans.Rollback(); throw ex; } if (execCount > 0 && !isNewTask) { // 更新用户的连中次数,最多50次 var taskIds = (await repository.QueryAsync( $"select id from n_activity_czd_task where contractId={contractId} and contractResult>0 order by id desc limit 50", null, conn)).ToList(); // 查询出所有参与记录 var records = (await repository.QueryAsync( $"select taskId, userId from n_activity_czd_task_records where taskId in @taskIds and gameResult=1", new { taskIds })).ToList(); // 按人进行统计 var userIdCountMap = new Dictionary(); var completedUserIds = new HashSet(); var first = true; foreach (var taskId in taskIds) { var uids = records.Where(e => e.taskId == taskId).Select(e => (long)e.userId).ToHashSet(); if (first) { records.ForEach(e => { if (!userIdCountMap.ContainsKey(e.userId)) { userIdCountMap.Add(e.userId, uids.Contains(e.userId) ? 1 : 0); } }); first = false; } else { userIdCountMap.Keys.ForEach(uid => { if (completedUserIds.Contains(uid)) return; if (uids.Contains(uid) && userIdCountMap.ContainsKey(uid) && userIdCountMap[uid] != 0) userIdCountMap[uid]++; else completedUserIds.Add(uid); }); } } // 更新记录 if (userIdCountMap.Count > 0) { var query = userIdCountMap.Select(e => new { userId = e.Key, count = e.Value }).ToList(); await repository.QueryAsync( $"update n_activity_czd_task_statistic set continuousTimes=@count where contractId={contractId} and userId=@userId", query, conn, null, false); } } return execCount > 0; } /// /// 根据给定变更的奖励任务编号列表来更新活动的报名状态 /// private static async Task UpdateActivitySignupState(this DbRESTFulRepository repository, List rewardIds, IDbConnection conn) { var rewards = (await repository.QueryAsync( "select id, activityId, name, requirement, signupLimit from n_activity_reward where id in @ids and signupLimit>0", new { ids = rewardIds }, conn)).ToList(); if (rewards.Count == 0) return; var allActivityIds = rewards.Select(e => (int)e.activityId).Distinct().ToList(); rewardIds = rewards.Select(e => (int)e.id).ToList(); var completeStat = (await repository.QueryAsync( @"select rewardId, count(1) as count from n_activity_reward_user_state where rewardId in @rewardIds and state in(0, 1) group by rewardId", new { rewardIds }, conn)).ToList(); if (completeStat.Count == 0) return; var cannotSignupActivityIds = new HashSet(); var updateRecords = new List(); rewards.ForEach(p => { if (cannotSignupActivityIds.Contains(p.activityId)) return; var existStat = completeStat.FirstOrDefault(e => e.rewardId == p.id); if (existStat == null) return; if (existStat.count >= p.signupLimit) { cannotSignupActivityIds.Add(p.activityId); updateRecords.Add(new { p.name, p.activityId, p.requirement, existStat.count, p.signupLimit }); } }); var canSignupActivityIds = allActivityIds.Where(i => !cannotSignupActivityIds.Contains(i)).ToList(); var activityInfos = (await repository.QueryAsync("select id, signupState, signupCount, signupStartAt, signupEndAt from n_activity where id in @ids", new { ids = allActivityIds }, conn)).ToList(); // 过滤掉当前不可报名的活动编号,不可报名的无需更新 var validCannotSignupActivityIds = cannotSignupActivityIds .Where(i => !activityInfos.Any(a => a.id == i && a.signupState == 1)).ToList(); if (validCannotSignupActivityIds.Count > 0) { await repository.QueryAsync( $"update n_activity set signupState=1 where id in @ids", new { ids = validCannotSignupActivityIds }, conn, null, false); await repository.QueryAsync($"insert into n_activity_signup_state_change(activityId, `event`, createAt) values (@activityId, @eventTxt, now())", validCannotSignupActivityIds.Select( i => { var r = updateRecords.First(r => r.activityId == i); var name = string.IsNullOrEmpty(r.name) ? $"邀请{r.requirement}人" : r.name; return new { activityId = i, eventTxt = $"停止报名(原因:任务\"{name}\"完成人数{r.count}达到上限)" }; })); } if (canSignupActivityIds.Count > 0) { var now = DateTime.Now; var needCheckSignupLimitActivityIds = new List(); // 过滤掉当前可报名的活动编号,可报名的无需更新 var validCanSignupActivityIds = canSignupActivityIds.Where(i => { var activityInfo = activityInfos.FirstOrDefault(a => a.id == i); if (activityInfo == null) return false; // 忽略非不可报名状态 if (activityInfo.signupState != 1) return false; // 如果时间不满足或者自定义报名人数不满足 也忽略 if (activityInfo.signupStartAt > now || activityInfo.signupEndAt < now) return false; if (activityInfo.signupCount == 0) return false; if (activityInfo.signupCount > 0) needCheckSignupLimitActivityIds.Add(i); return true; }).ToList(); // 进一步统计报名人数并判断是否满足 if (needCheckSignupLimitActivityIds.Count > 0) { // 查出活动当前报名人数 var userCountStat = (await repository.QueryAsync( "select activityId, count(1) as count from n_activity_signup_records where activityId in @activityIds and state=1", new { activityIds = needCheckSignupLimitActivityIds }, conn)).ToList(); validCanSignupActivityIds = validCanSignupActivityIds.Where(i => { var activityInfo = activityInfos.First(a => a.id == i); var userCount = userCountStat.FirstOrDefault(s => s.activityId == i)?.count ?? 0; return activityInfo.signupCount > userCount; }).ToList(); } if (validCanSignupActivityIds.Count > 0) { await repository.QueryAsync( $"update n_activity set signupState=0 where id in @ids", new { ids = validCanSignupActivityIds }, conn, null, false); await repository.QueryAsync($"insert into n_activity_signup_state_change(activityId, `event`, createAt) values (@activityId, @eventTxt, now())", validCanSignupActivityIds.Select( i => new { activityId = i, eventTxt = "开始报名" })); } } } /// /// 更新邀请好友活动的统计值(各活动任务完成状态/排行数据) /// public static async Task UpdateActivityYqhyStatBySingleUser(this DbRESTFulRepository repository, long userId, IDbConnection conn) { // 如果邀请好友活动未超出领取时间,才需要更新排名数据 var needUpdateActivities = (await repository.QueryAsync( @"select id, startTime, endTime, config, signupEnabled, rewardRule,hotValue from n_activity where state=1 and type='yqhy' and startTimenow())", null, conn)).ToList(); if (needUpdateActivities.Count == 0) return; //更新热度值 List activityInfos = needUpdateActivities.Where(a => (DateTime)a.endTime >= DateTime.Now && (int)a.signupEnabled == 0).Select(e => new ActivityHotVO { id = e.id, userId = userId, oldHotValue = e.hotValue, signupEnabled = (int)e.signupEnabled }).ToList(); //活动参与热度记录 await AddActivityHotRecords(repository, activityInfos, conn); var activityIds = needUpdateActivities.Where(e => e.signupEnabled == 1).Select(e => (int)e.id).ToList(); var signupTimeDic = new Dictionary(); // 如果启用报名的,则需要过滤掉未报名活动 if (activityIds.Count > 0) { var validActivityInfos = (await repository.QueryAsync( $"select activityId, createAt from n_activity_signup_records where activityId in @activityIds and userId={userId} and state=1", new { activityIds }, conn)).ToList(); validActivityInfos.ForEach(e => { signupTimeDic[(int)e.activityId] = (DateTime)e.createAt; }); var validActivityIds = validActivityInfos.Select(e => (int)e.activityId).ToList(); needUpdateActivities = needUpdateActivities .Where(e => activityIds.All(i => i != e.id) || validActivityIds.Any(i => i == e.id)) .ToList(); } if (needUpdateActivities.Count == 0) return; var typedActivitiesDic = new Dictionary(); var activitiesDic = new Dictionary(); var allRewardIds = new List(); var minTime = DateTime.MaxValue; var maxTime = DateTime.MinValue; var now = DateTime.Now; foreach (var activity in needUpdateActivities) { var config = JsonConvert.DeserializeObject((string)activity.config); typedActivitiesDic[activity.id] = config; activitiesDic[activity.id] = activity; allRewardIds.AddRange(config.rewardIds); if (activity.startTime < minTime) minTime = activity.startTime; if (activity.endTime > maxTime) maxTime = activity.endTime; } // 统计此用户此期间所有的有效的邀请记录 var records = (await repository.QueryAsync( $"select createAt, activeAt, hasProfit from n_user_invitation_record where userId={userId} and state=1 and invalid=0 and (createAt>=@minTime and createAt<=@maxTime) and (activeAt>=@minTime and activeAt<=@maxTime)", new { minTime, maxTime }, conn)).ToList(); // 统计不同活动用户成功邀请次数 var countDic = new Dictionary(); var lastCompletedTime = new Dictionary(); records.ForEach(r => { needUpdateActivities.ForEach(a => { var aid = (int)a.id; var config = typedActivitiesDic[aid]; var startTime = a.startTime; if (signupTimeDic.ContainsKey(aid) && signupTimeDic[aid] > startTime) { startTime = signupTimeDic[aid]; } // 如果配置不允许获利邀请计入且当前条目是获利,则不计入 if ((!config.ignoreProfit || r.hasProfit == 0) && (a.endTime == null || a.endTime >= r.activeAt) && startTime <= r.activeAt) { if (countDic.ContainsKey(aid)) { countDic[aid]++; } else { countDic[aid] = 1; } if (!lastCompletedTime.ContainsKey(aid) || lastCompletedTime[aid] < r.activeAt) { lastCompletedTime[aid] = r.activeAt; } } }); }); // 更新奖励状态记录 if (allRewardIds.Count > 0) { var completed = new List(); var uncompleted = new List(); // 查出所有活动的奖励配置 var rewards = await repository.QueryAsync( "select id, activityId, requirement from n_activity_reward where id in @ids and invalid=0 order by displayOrder asc", new { ids = allRewardIds }, conn); // 用于设置仅发最后一个任务的奖励 var activityIdHashSet = new HashSet(); // 检测各活动用户奖励是否达标 rewards.ForEach(r => { int requirement = int.Parse(r.requirement); int aid = (int)r.activityId; var activityInfo = activitiesDic[aid]; var count = countDic.ContainsKey(aid) ? countDic[aid] : 0; var time = lastCompletedTime.ContainsKey(aid) ? lastCompletedTime[aid] : now; if (requirement <= count) { // 如果活动设置的是只能领取最后奖励,则需要将除最高任务的其他任务设置成未达成 if (activityInfo.rewardRule == 1) { if (!activityIdHashSet.Contains(aid)) { completed.Add(new { rewardId = r.id, r.activityId, latestCompleteAt = time }); activityIdHashSet.Add(aid); } else { uncompleted.Add(r.id); } } else { completed.Add(new { rewardId = r.id, r.activityId, latestCompleteAt = time }); } } else { uncompleted.Add(r.id); } }); if (completed.Count > 0) { await repository.QueryAsync(@$"insert into n_activity_reward_user_state (userId, rewardId, activityId, state, latestCompleteAt) values ({userId}, @rewardId, @activityId, 0, @latestCompleteAt) ON DUPLICATE KEY update state=if(state=-1, 0, state), latestCompleteAt=if(state=-1, @latestCompleteAt, latestCompleteAt)", completed, conn, null, false); } if (uncompleted.Count > 0) { await repository.QueryAsync(@$"update n_activity_reward_user_state set state=-1 where userId={userId} and rewardId in @ids and state=0", new { ids = uncompleted }, conn, null, false); } } if (countDic.Count > 0) { // 更新排行数据 var rankingdata = countDic.Select(e => new { activityId = e.Key, score = e.Value, lastRecordTime = lastCompletedTime.ContainsKey(e.Key) ? lastCompletedTime[e.Key] : now }); await repository.QueryAsync($@"insert into n_activity_ranking (activityId, userId, score, lastRecordTime) values (@activityId, {userId}, @score, @lastRecordTime) ON DUPLICATE KEY update score=@score, lastRecordTime=@lastRecordTime", rankingdata, conn, null, false); } // 更新报名状态 if (allRewardIds.Count > 0) { await repository.UpdateActivitySignupState(allRewardIds, conn); } } /// /// 更新每日话题活动的统计值(各活动任务完成状态/排行数据) /// public static async Task UpdateActivityMrhtStatBySinglePost(this DbRESTFulRepository repository, long postId, IDbConnection conn) { // 如果每日话题活动未超出领取时间,才需要更新排名数据 var needUpdateActivities = (await repository.QueryAsync( "select id, startTime, endTime, config, signupEnabled, rewardRule,hotValue from n_activity where type='mrht' and state=1 and startTimenow())", null, conn)).ToList(); if (needUpdateActivities.Count == 0) return; var postInfo = await repository.QuerySingleOrDefaultAsync($"select userId, categoryType, originalTopicNames, createAt from n_post where id={postId}", null, conn); if (postInfo == null) return; var userId = (long)postInfo.userId; //更新热度值 List activityInfos = needUpdateActivities.Where(a => (DateTime)a.endTime >= DateTime.Now && (int)a.signupEnabled == 0).Select(e => new ActivityHotVO { id = e.id, userId = userId, oldHotValue = e.hotValue, signupEnabled = (int)e.signupEnabled }).ToList(); //活动参与热度记录 await AddActivityHotRecords(repository, activityInfos, conn); { var activityIds = needUpdateActivities.Where(e => e.signupEnabled == 1).Select(e => (int)e.id).ToList(); // 如果启用报名的,则需要过滤掉未报名活动 if (activityIds.Count > 0) { var validActivityIds = (await repository.QueryAsync( $"select activityId from n_activity_signup_records where activityId in @activityIds and userId={userId} and state=1", new { activityIds }, conn)).ToList(); needUpdateActivities = needUpdateActivities .Where(e => !activityIds.Contains(e.id) || validActivityIds.Contains(e.id)) .ToList(); } } if (needUpdateActivities.Count == 0) return; var topicNames = ((string)postInfo.originalTopicNames).Split('\n', StringSplitOptions.RemoveEmptyEntries); if (topicNames.Length == 0) return; var topicIds = (await repository.QueryAsync("select id from n_topic where title in @names", new { names = topicNames }, conn)).ToList(); if (topicIds.Count == 0) return; var createDate = ((DateTime)postInfo.createAt).Date; // 筛选出此文章话题相关的所有活动 needUpdateActivities = needUpdateActivities.Where(e => { var config = JsonConvert.DeserializeObject((string)e.config); if (config.topics == null) return false; var validTopicId = config.topics.LastOrDefault(i => i.date.Date <= createDate && i.topicId > 0) ?.topicId ?? 0; return validTopicId > 0 && topicIds.Contains(validTopicId); }).ToList(); if (needUpdateActivities.Count == 0) return; var relativeActivityIds = needUpdateActivities.Select(e => e.id).ToList(); // 找出此用户在所有有效每日话题中的活动记录 var allRelativeRecords = (await repository.QueryAsync( $"select activityId, `date`, topicId, postId, createAt from n_activity_mrht_records where userId={userId} and state=1 and activityId in @activityIds", new { activityIds = relativeActivityIds }, conn)).ToList(); if (allRelativeRecords.Count == 0) return; // 查出相关活动的奖励配置列表 var rewards = (await repository.QueryAsync( "select id, activityId, requirement, displayOrder from n_activity_reward where activityId in @activityIds and invalid=0 order by displayOrder asc", new { activityIds = relativeActivityIds }, conn)) .Select(e => new { e.id, e.activityId, requirement = int.Parse(e.requirement), e.displayOrder }).ToList(); if (rewards.Count == 0) return; // 查出已达成和未达成的任务 var completedRecords = (await repository.QueryAsync( $"select rewardId, latestCompleteAt from n_activity_reward_user_state where userId={userId} and rewardId in @rewardIds and state in (0, 1)", new { rewardIds = rewards.Select(e => e.id) }, conn)).ToList(); var completed = completedRecords.Select(e => (int)e.rewardId).ToList(); var uncompleted = rewards.Where(e => !completed.Contains(e.id)); var insertRecords = new List(); // 待插入或更新的达成记录(除去了最高任务奖励类型) var singleRewardInsertRecords = new List(); // 待插入或更新的达成记录(仅包含最高任务奖励类型) // 判断达成情况 uncompleted.ForEach(e => { var curActivityRecords = allRelativeRecords.Where(i => i.activityId == e.activityId).ToList(); // 查出此任务所有的完成的记录数量 var dates = curActivityRecords.Select(i => i.date).Distinct().OrderBy(d => d).ToList(); var count = dates.Count; if (count >= e.requirement && e.requirement > 0) { // 达成活动的日期 var date = dates[e.requirement - 1]; // 找出达成的那天最早的发布时间 var latestCompleteAt = curActivityRecords.Where(i => i.date == date).Select(i => i.date).Min(); // 添加到更新列表中 insertRecords.Add(new { rewardId = e.id, e.activityId, latestCompleteAt }); } }); // 如果活动设置的是只能领取最后奖励,则需要将除最高任务的其他任务设置成未达成 var singleRewardActivityList = needUpdateActivities.Where(e => e.rewardRule == 1).ToList(); if (singleRewardActivityList.Count > 0) { var set = new HashSet(); rewards.ForEach(e => { if (singleRewardActivityList.All(a => a.id != e.activityId)) return; var existRecord = completedRecords.FirstOrDefault(r => r.rewardId == e.id); if (existRecord == null) existRecord = insertRecords.FirstOrDefault(r => r.rewardId == e.id); if (existRecord == null) return; if (set.Contains(e.activityId)) return; set.Add(e.activityId); singleRewardInsertRecords.Add(new { rewardId = e.id, e.activityId, existRecord.latestCompleteAt }); }); // 先在更新列表中移除只领一个奖励的任务 insertRecords = insertRecords.Where(e => singleRewardActivityList.All(a => a.id != e.activityId)) .ToList(); } // 更新此用户所有有效的每日话题活动总参与次数 var rankingdata = new List(); allRelativeRecords.GroupBy(e => e.activityId).ForEach(group => { var activityId = group.Key; var list = group.ToList(); var sgroup = list.GroupBy(i => i.date); var count = sgroup.Count(); var minTime = sgroup.OrderBy(m => m.Key).Last().First().createAt; rankingdata.Add(new { activityId, score = count, lastRecordTime = minTime }); }); List validUpdatedRecordIds = new List(); if (insertRecords.Count > 0) { await repository.QueryAsync(@$"insert into n_activity_reward_user_state (userId, rewardId, activityId, state, latestCompleteAt) values ({userId}, @rewardId, @activityId, 0, @latestCompleteAt) ON DUPLICATE KEY update state=if(state=-1, 0, state), latestCompleteAt=if(state=-1, @latestCompleteAt, latestCompleteAt)", insertRecords, conn, null, false); validUpdatedRecordIds.AddRange(insertRecords.Select(e => (int)e.rewardId)); } if (singleRewardActivityList.Count > 0) { // 如果活动设置的是只能领取最后奖励,先重置非达成的状态,然后再插入或更新达成的状态 var activityIds = singleRewardActivityList.Select(a => a.id); dynamic rewardIds = singleRewardInsertRecords.Count > 0 ? singleRewardInsertRecords.Select(e => e.rewardId) : null; await repository.QueryAsync( $"update n_activity_reward_user_state set state=-1 where activityId in @activityIds and userId={userId} [and rewardId not in @rewardIds]", new { activityIds, rewardIds }, conn, null, false); if (singleRewardInsertRecords.Count > 0) { await repository.QueryAsync(@$"insert into n_activity_reward_user_state (userId, rewardId, activityId, state, latestCompleteAt) values ({userId}, @rewardId, @activityId, 0, @latestCompleteAt) ON DUPLICATE KEY update state=if(state=-1, 0, state), latestCompleteAt=if(state=-1, @latestCompleteAt, latestCompleteAt)", singleRewardInsertRecords, conn, null, false); validUpdatedRecordIds.AddRange(singleRewardInsertRecords.Select(e => (int)e.rewardId)); } } if (rankingdata.Count > 0) { await repository.QueryAsync($@"insert into n_activity_ranking (activityId, userId, score, lastRecordTime) values (@activityId, {userId}, @score, @lastRecordTime) ON DUPLICATE KEY update score=@score, lastRecordTime=@lastRecordTime", rankingdata, conn, null, false); } // 更新报名状态 if (validUpdatedRecordIds.Count > 0) { await repository.UpdateActivitySignupState(validUpdatedRecordIds, conn); } } /// /// 活动参与热度记录 /// /// /// /// /// /// public static async Task AddActivityHotRecords(this DbRESTFulRepository repository, List hotInfos, IDbConnection conn) { if (hotInfos != null && hotInfos.Count > 0) { //所有活动id var ids = hotInfos.Select(s => s.id); //该用户已经参与活动已经加过热度了 var activityIds = await repository.QueryAsync( $"select activityId from n_activity_hot_records where activityId in @ids and userId=@userId limit 1", new { ids, hotInfos[0].userId }, conn, null, false); if (activityIds != null && activityIds.Count() > 0) { hotInfos = hotInfos.Where(s => !activityIds.ToList().Contains(s.id)).ToList(); } if (hotInfos != null && hotInfos.Count > 0) { //报名:每个账号报名成功时,随机加1~10; //热度:每个账号完成每个活动的第1次任务时,随机加5~15 hotInfos.ForEach(item => { item.addHotValue = item.signupEnabled == 1 ? new Random().Next(1, 10) : new Random().Next(5, 15); }); await repository.QueryAsync( "update n_activity set hotValue=hotValue+@addHotValue where id=@id;", hotInfos, conn, null, false); await repository.QueryAsync( $@"insert into n_activity_hot_records(activityId,userId, oldHotValue,addHotValue, createAt) values (@id,@userId, @oldHotValue,@addHotValue, now())", hotInfos, conn, null, false); } } } } }