123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- using Elasticsearch.Net;
- using JiaZhiQuan.Common.Config;
- using JiaZhiQuan.Common.ElasticSearch;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using Senparc.Weixin.MP.Containers;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Diagnostics;
- using System.Dynamic;
- using System.Linq;
- using System.Net.Http;
- using System.Reflection;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading.Tasks;
- using Wicture.DbRESTFul;
- using Wicture.DbRESTFul.Cache;
- using Wicture.DbRESTFul.Infrastructure.Repository;
- namespace JiaZhiQuan.Common
- {
- public static partial class RepositoryExtension
- {
- public class MockActionGenerationModel
- {
- public long targetId { get; set; }
- public string action { get; set; }
- public string content { get; set; }
- public long mockUserId { get; set; }
- public DateTime execTime { get; set; }
- }
- public static List<DateTime> GenerateMockTimes(this DbRESTFulRepository repository, DateTime startMockTime, int hours, int count)
- {
- var rand = new Random();
- var list = new List<DateTime>();
- if (hours < 25)
- {
- var startTicks = startMockTime.Ticks;
- var endMockTime = startMockTime.AddHours(hours);
- var allSecs = (int)((endMockTime.Ticks - startTicks) / 10000000);
- for (var i = 0; i < count; i++)
- {
- // 给定天内随机,如果在1~6点,则添加16个小时再模拟
- var randSecs = rand.Next(allSecs);
- var curTime = new DateTime(startTicks + randSecs * 10000000L);
- if (curTime.Hour > 1 && curTime.Hour < 6)
- {
- if (rand.Next(100) < 95)
- {
- curTime = curTime.AddHours(16);
- }
- }
- list.Add(curTime);
- }
- return list;
- }
- else
- {
- // 按天来随机
- var days = Math.Ceiling(hours / 24f);
- if (days > 15) days = 15;
- var pro = ConfigFromDb.RandomProbabilities[(int)days - 2];
- var totalProp = pro.Sum();
- // 计算一天的人数数量
- var dayCountDic = new Dictionary<int, int>();
- for (var idx = 0; idx < count; idx++)
- {
- var rnum = rand.Next(totalProp + 1);
- var tmp = 0;
- var curDay = 1;
- for (var i = 0; i < pro.Count; i++)
- {
- if (i == pro.Count - 1 || (rnum >= tmp && rnum <= tmp + pro[i]))
- {
- curDay = i + 1;
- break;
- };
- tmp += pro[i];
- }
- if (dayCountDic.ContainsKey(curDay)) dayCountDic[curDay] = dayCountDic[curDay] + 1;
- else dayCountDic[curDay] = 1;
- }
- var index = 0;
- foreach (var key in dayCountDic.Keys)
- {
- var start = startMockTime.AddDays(key - 1);
- var end = startMockTime.AddDays(key);
- var allSecs = (int)((end.Ticks - start.Ticks) / 10000000);
- for (var idx = 0; idx < dayCountDic[key]; idx++)
- {
- // 给定天内随机,如果在1~6点,则添加16个小时再模拟
- var randSecs = rand.Next(allSecs);
- var curTime = new DateTime(start.Ticks + randSecs * 10000000L);
- if (curTime.Hour > 1 && curTime.Hour < 6)
- {
- if (rand.Next(100) < 95)
- {
- curTime = curTime.AddHours(16);
- }
- }
- list.Add(curTime);
- index++;
- }
- }
- return list;
- }
- }
- /// <summary>
- /// 获取随机用户模拟信息
- /// </summary>
- /// <param name="modelList">如果不传,则从数据库查手机号大于90000000000的用户</param>
- /// <returns></returns>
- public async static Task<List<MockActionGenerationModel>> GenerateMockActions(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long targetId, string action, int expectCount, List<MockActionGenerationModel> modelList = null)
- {
- if (modelList == null)
- {
- modelList = (await GetMockUserIdsRandom(repository, expectCount, 0))
- .Select(e => new MockActionGenerationModel { mockUserId = e }).ToList();
- }
- var rand = new Random();
- if (hours < 25)
- {
- var startTicks = startMockTime.Ticks;
- var endMockTime = startMockTime.AddHours(hours);
- var allSecs = (int)((endMockTime.Ticks - startTicks) / 10000000);
- foreach (var item in modelList)
- {
- item.targetId = targetId;
- item.action = action;
- // 给定天内随机,如果在1~6点,则添加16个小时再模拟
- var randSecs = rand.Next(allSecs);
- var curTime = new DateTime(startTicks + randSecs * 10000000L);
- if (curTime.Hour > 1 && curTime.Hour < 6)
- {
- if (rand.Next(100) < 95)
- {
- curTime = curTime.AddHours(16);
- }
- }
- item.execTime = curTime;
- }
- return modelList;
- }
- else
- {
- // 按天来随机
- var days = Math.Ceiling(hours / 24f);
- if (days > 15) days = 15;
- var pro = ConfigFromDb.RandomProbabilities[(int)days - 2];
- var totalProp = pro.Sum();
- // 计算一天的人数数量
- var dayCountDic = new Dictionary<int, int>();
- for (var idx = 0; idx < modelList.Count; idx++)
- {
- var rnum = rand.Next(totalProp + 1);
- var tmp = 0;
- var curDay = 1;
- for (var i = 0; i < pro.Count; i++)
- {
- if (i == pro.Count - 1 || (rnum >= tmp && rnum <= tmp + pro[i]))
- {
- curDay = i + 1;
- break;
- };
- tmp += pro[i];
- }
- if (dayCountDic.ContainsKey(curDay)) dayCountDic[curDay] = dayCountDic[curDay] + 1;
- else dayCountDic[curDay] = 1;
- }
- var index = 0;
- foreach(var key in dayCountDic.Keys)
- {
- var start = startMockTime.AddDays(key - 1);
- var end = startMockTime.AddDays(key);
- var allSecs = (int)((end.Ticks - start.Ticks) / 10000000);
- for (var idx = 0; idx < dayCountDic[key]; idx++)
- {
- var item = modelList[index];
- item.targetId = targetId;
- item.action = action;
- // 给定天内随机,如果在1~6点,则添加16个小时再模拟
- var randSecs = rand.Next(allSecs);
- var curTime = new DateTime(start.Ticks + randSecs * 10000000L);
- if (curTime.Hour > 1 && curTime.Hour < 6)
- {
- if (rand.Next(100) < 95)
- {
- curTime = curTime.AddHours(16);
- }
- }
- item.execTime = curTime;
- index++;
- }
- }
- return modelList;
- }
- }
- /// <summary>
- /// 给文章添加点赞数量任务
- /// </summary>
- public static async Task AddMockPostThumbsup(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long postId, int expectCount, IDbConnection conn = null)
- {
- var postInfo = await repository.QuerySingleOrDefaultAsync<dynamic>($"select id, state, userId, checkCntLevel from n_post where id={postId}", null, conn);
- if (postInfo == null || postInfo.state != 1 || "D".Equals(postInfo.checkCntLevel)) return;
-
- var list = await repository.GenerateMockActions(startMockTime, hours, postId, "POST_THUMBSUP", expectCount);
- if (list.Count > 0)
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var size = 500;
- for (var i = 0; i < list.Count; i += size)
- {
- var leftCount = list.Count - i;
- var subList = list.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", subList, conn, null, false);
- }
- }
- await repository.QueryAsync<dynamic>("update n_post set mockThumbsupCnt=mockThumbsupCnt+" + list.Count + " where id=" + postId, null, conn, null, false);
- }
- }
- /// <summary>
- /// 给文章添加收藏数量任务
- /// </summary>
- public static async Task AddMockPostCollection(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long postId, int expectCount, IDbConnection conn = null)
- {
- var postInfo = await repository.QuerySingleOrDefaultAsync<dynamic>($"select id, state, userId, checkCntLevel from n_post where id={postId}", null, conn);
- if (postInfo == null || postInfo.state != 1 || "D".Equals(postInfo.checkCntLevel)) return;
-
- var list = await repository.GenerateMockActions(startMockTime, hours, postId, "POST_COLLECTION", expectCount);
- if (list.Count > 0)
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var size = 500;
- for (var i = 0; i < list.Count; i += size)
- {
- var leftCount = list.Count - i;
- var subList = list.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", subList, conn, null, false);
- }
- }
- await repository.QueryAsync<dynamic>("update n_post set mockCollectionCnt=mockCollectionCnt+" + list.Count + " where id=" + postId, null, conn, null, false);
- }
- }
- /// <summary>
- /// 给文章添加分享数量任务
- /// </summary>
- public static async Task AddMockPostShare(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long postId, int expectCount, IDbConnection conn = null)
- {
- var postInfo = await repository.QuerySingleOrDefaultAsync<dynamic>($"select id, state, userId, checkCntLevel from n_post where id={postId}", null, conn);
- if (postInfo == null || postInfo.state != 1 || "D".Equals(postInfo.checkCntLevel)) return;
-
- var list = await repository.GenerateMockActions(startMockTime, hours, postId, "POST_SHARE", expectCount);
- if (list.Count > 0)
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var size = 500;
- for (var i = 0; i < list.Count; i += size)
- {
- var leftCount = list.Count - i;
- var subList = list.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", subList, conn, null, false);
- }
- }
- await repository.QueryAsync<dynamic>("update n_post set mockShareCnt=mockShareCnt+" + list.Count + " where id=" + postId, null, conn, null, false);
- }
- }
-
- /// <summary>
- /// 按文章添加作者主页访问数量任务
- /// </summary>
- public static async Task AddMockPostPPVisit(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long postId, int expectCount, IDbConnection conn = null)
- {
- var postInfo = await repository.QuerySingleOrDefaultAsync<dynamic>($"select id, state, userId, checkCntLevel from n_post where id={postId}", null, conn);
- if (postInfo == null || postInfo.state != 1 || "D".Equals(postInfo.checkCntLevel)) return;
-
- var list = await repository.GenerateMockActions(startMockTime, hours, postId, "POST_PPVISIT", expectCount);
- if (list.Count > 0)
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var size = 500;
- for (var i = 0; i < list.Count; i += size)
- {
- var leftCount = list.Count - i;
- var subList = list.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", subList, conn, null, false);
- }
- }
- }
- }
-
- /// <summary>
- /// 按用户添加主页访问数量任务
- /// </summary>
- public static async Task AddMockUserPPVisit(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long userId, int expectCount, IDbConnection conn = null)
- {
- var userInfo = await repository.QuerySingleOrDefaultAsync<dynamic>($"select id, state from n_user where id={userId}", null, conn);
- if (userInfo == null || userInfo.state != 0) return;
-
- var list = await repository.GenerateMockActions(startMockTime, hours, userId, "USER_PPVISIT", expectCount);
- if (list.Count > 0)
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var size = 500;
- for (var i = 0; i < list.Count; i += size)
- {
- var leftCount = list.Count - i;
- var subList = list.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", subList, conn, null, false);
- }
- }
- }
- }
- /// <summary>
- /// 【已废弃】给文章添加评论数量任务
- /// </summary>
- public static async Task AddMockPostComment(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long postId, int expectCount)
- {
- await Task.CompletedTask;
- // var records = await repository.GenerateMockActions(DateTime.Now, hours, postId, "COMMENT", expectCount);
- // if (records.Count == 0) return;
- // // 获取模拟评论
- // var primaryType = await repository.QuerySingleOrDefaultAsync<int>($"select primaryType from n_post where id={postId}");
- // if (primaryType == 0) return;
- // var contList = (await repository.QueryAsync<string>($"select `comment`, rand() as rid from n_mock_comment_cnt where primaryType={primaryType} order by rid asc limit " + expectCount)).ToList();
- // if (contList.Count == 0) return;
- // if (contList.Count < records.Count)
- // {
- // records = records.Take(contList.Count).ToList();
- // }
- // for (var i = 0; i < contList.Count; i++)
- // {
- // records[i].content = contList[i];
- // }
- // var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- // await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", records, null, null, false);
- }
- /// <summary>
- /// 给某用户添加模拟关注任务
- /// </summary>
- public static async Task AddMockFocusUser(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long userId, int expectCount, IDbConnection conn = null)
- {
- var list = (await repository.QueryAsync<MockActionGenerationModel>("select t.id as mockUserId, rand() as rid from (select id from n_user where autoGenerationType=1 and username>='90000000000' and id not in (select uf.fanId from n_user_fan as uf where uf.userId=@userId)) as t order by rid asc limit " + expectCount, new { userId })).ToList();
- if (list.Count < expectCount)
- {
- var count = expectCount - list.Count;
- var moreList = (await repository.QueryAsync<MockActionGenerationModel>("select t.id as mockUserId, rand() as rid from (select id from n_user where autoGenerationType=2 and username>='90000000000' and id not in (select uf.fanId from n_user_fan as uf where uf.userId=@userId)) as t order by rid asc limit " + count, new { userId })).ToList();
- list.AddRange(moreList);
- list.Shuffle();
- }
- list = await GenerateMockActions(repository, startMockTime, hours, userId, "USER_FOCUS", expectCount, list);
- if (list.Count > 0)
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var size = 500;
- for (var i = 0; i < list.Count; i += size)
- {
- var leftCount = list.Count - i;
- var subList = list.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert ignore into n_mock_action_records (targetId, action, content, mockUserId, execTime, createTime) values (@targetId, @action, @content, @mockUserId, @execTime, '{time}')", subList, conn, null, false);
- }
- }
- await repository.QueryAsync<dynamic>($"update n_user set mockFocusCnt=mockFocusCnt+@count where id=@userId", new { count = list.Count, userId }, conn, null, false);
- }
- }
- /// <summary>
- /// 给某文章添加模拟阅读任务
- /// </summary>
- public static async Task AddMockPostRead(this DbRESTFulRepository repository, DateTime startMockTime, int hours, long postId, int count, IDbConnection conn = null)
- {
- var postInfo = await repository.QuerySingleOrDefaultAsync<dynamic>($"select id, state, userId, checkCntLevel from n_post where id={postId}", null, conn);
- if (postInfo == null || postInfo.state != 1 || "D".Equals(postInfo.checkCntLevel)) return;
- var records = GenerateMockTimes(repository, startMockTime, hours, count).Select(e => new { readAt = e.ToString("yyyy-MM-dd HH:mm:ss") }).ToList();
- // 一次处理500条记录
- var size = 500;
- for (var i = 0; i < records.Count; i += size)
- {
- var leftCount = records.Count - i;
- var subList = records.Skip(i).Take(leftCount >= size ? size : leftCount).ToList();
- if (subList.Count > 0)
- {
- await repository.QueryAsync<dynamic>($"insert into n_mock_read_action_records(postId, readAt) values ({postId}, @readAt)", subList, conn);
- }
- }
- }
- /// <summary>
- /// 获取模拟用户
- /// </summary>
- /// <param name="expectCount">期望获取最多多少个</param>
- /// <returns></returns>
- public static async Task<List<long>> GetMockUserIdsRandom(this DbRESTFulRepository repository, int expectCount, int minPostCount = 0)
- {
- if (minPostCount > 0)
- {
- var userIds = (await repository.QueryAsync<long>("select tt.id from (select t.id, rand() as rid from n_user as t left join n_user_statistic as us on t.id=us.userId where t.autoGenerationType=1 and t.username>='90000000000' and us.post>=@minPostCount order by rid asc limit @expectCount) as tt", new { expectCount, minPostCount })).ToList();
- if (userIds.Count < expectCount)
- {
- var count = expectCount - userIds.Count;
- var moreUserIds = (await repository.QueryAsync<long>("select tt.id from (select t.id, rand() as rid from n_user as t left join n_user_statistic as us on t.id=us.userId where t.autoGenerationType=2 and t.username>='90000000000' and us.post>=@minPostCount order by rid asc limit @expectCount) as tt", new { expectCount = count, minPostCount })).ToList();
- userIds.AddRange(moreUserIds);
- userIds.Shuffle();
- }
- return userIds;
- }
- else
- {
- var userIds = (await repository.QueryAsync<long>("select tt.id from (select t.id, rand() as rid from n_user as t where t.autoGenerationType=1 and t.username>='90000000000' order by rid asc limit @expectCount) as tt", new { expectCount })).ToList();
- if (userIds.Count < expectCount)
- {
- var count = expectCount - userIds.Count;
- var moreUserIds = (await repository.QueryAsync<long>("select tt.id from (select t.id, rand() as rid from n_user as t where t.autoGenerationType=2 and t.username>='90000000000' order by rid asc limit @expectCount) as tt", new { expectCount = count })).ToList();
- userIds.AddRange(moreUserIds);
- userIds.Shuffle();
- }
- return userIds;
- }
- }
- /// <summary>
- /// 获取数据库配置的模拟发文章的用户
- /// </summary>
- public static async Task<List<long>> GetMockUserIdsRandomByCategoryType(this DbRESTFulRepository repository, int expectCount, int categoryType)
- {
- return (await repository.QueryAsync<long>($"select tt.userId from (select t.userId, rand() as rid from s_mock_user_post as t where t.categoryType={categoryType} order by rid asc limit {expectCount}) as tt")).ToList();
- }
- }
- }
|