using Elasticsearch.Net; 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 { /// /// 保存用户信息到ES。创建新的或者更新部分字段 /// 必须包含id字段 /// 是否忽略更新文章索引中用户昵称(暂时仅用于用户注销时,指定为true) /// public static async Task UserInfoSave2ES(this DbRESTFulRepository repository, object userInfo, bool ignorePost = false) { var id = userInfo.GetType().GetProperty("id").GetValue(userInfo); var idStr = id.ToString(); bool exist = await ESHelper.CheckExist("user", idStr); if (exist) { var rsp = await ESHelper.Client.UpdateAsync("user", idStr, PostData.Serializable(new { doc = userInfo })); if (!rsp.Success) { LoggerManager.Logger.Error("更新用户信息到ES失败:" + rsp.Body); return; } // 如果存在,还需要更新 Post 中的用户昵称 if (IsPropertyExist(userInfo, "alias")) { string alias = userInfo.GetType().GetProperty("alias").GetValue(userInfo) as string; alias = alias.Replace("'", ""); var query = new { script = new { source = $"ctx._source['userAlias']='{alias}'" }, query = new { term = new { userId = id } } }; rsp = await ESHelper.Client.UpdateByQueryAsync(ESConstants.ESIndexName.Post, PostData.Serializable(query)); if (!rsp.Success) { LoggerManager.Logger.Error("更新ES中POST用户信息失败:" + rsp.Body); } } } else { var rsp = await ESHelper.Client.CreateAsync("user", idStr, PostData.Serializable(userInfo)); if (!rsp.Success) { LoggerManager.Logger.Error("创建用户信息到ES失败:" + rsp.Body); return; } } } /// /// 通过用户Id加载用户信息 /// id(string), alias, authType, authName, vip, headImage, domainTalent, publicTags, official, curProvince,watermark /// /// /// 可以为空 /// public static async Task> UsersInfoByIds(this DbRESTFulRepository repository, IEnumerable userIds, IDbConnection conn = null) where T : UserInfoBase { userIds = userIds.Distinct(); var list = await repository.QueryAsync("select id, alias, authType, authName, vip, headImage, domainTalent, description, publicTags, official, curProvince,watermark from n_user where id in @userIds", new { userIds }, conn); var dic = new Dictionary(userIds.Count()); foreach (var id in userIds) { dic[id] = list.FirstOrDefault(e => id.ToString() == e.id); } return dic; } /// /// 通过用户Id加载用户信息 /// id(string), username, alias, authType, authName, vip, headImage, domainTalent, mpRole, publicTags, official, curProvince,watermark /// /// /// 可以为空 /// public static async Task> UsersInfoFullByIds(this DbRESTFulRepository repository, IEnumerable userIds, IDbConnection conn = null) where T : UserInfoFull { userIds = userIds.Distinct(); var list = await repository.QueryAsync("select id, username, alias, authType, authName, vip, headImage, domainTalent, description, mpRole, superior, publicTags, official, curProvince,watermark from n_user where id in @userIds", new { userIds }, conn); var dic = new Dictionary(userIds.Count()); foreach (var id in userIds) { dic[id] = list.FirstOrDefault(e => id.ToString() == e.id); } return dic; } /// /// 通过用户Id加载用户信息,附带是否关注 /// id(string), alias, authType, authName, vip, headImage, domainTalent, publicTags, official, curProvince, focused,watermark /// /// 当前用户 /// 可以为空 /// 忽略当前用户关注用户列表的状态 /// 忽略用户列表是否关注当前用户的状态 /// public static async Task> UsersInfoWithFocusStateByIds(this DbRESTFulRepository repository, long userId, IEnumerable userIds, IDbConnection conn = null, bool ignoreFocusState = false, bool ignoreFanState = false) where T : UserInfoBaseWithFocusState { userIds = userIds.Distinct(); var dic = new Dictionary(userIds.Count()); if (userIds.Count() == 0) { return dic; } if (userId < 1) { ignoreFanState = true; ignoreFocusState = true; } var list = await repository.QueryAsync("select id, alias, authType, authName, vip, headImage, domainTalent, description, publicTags, official, curProvince,watermark,growLevel level from n_user where id in @userIds", new { userIds }, conn); HashSet focusState = null; if (!ignoreFocusState) { focusState = await CheckFocusState(repository, userId, userIds, conn); } HashSet fanState = null; if (!ignoreFanState) { fanState = await CheckFanState(repository, userId, userIds, conn); } foreach (var id in userIds) { var user = list.FirstOrDefault(e => id.ToString() == e.id); if (user != null) { if (focusState != null) user.focused = focusState.Contains(id) ? 1 : 0; if (fanState != null) user.isFan = fanState.Contains(id) ? 1 : 0; } dic[id] = user; } return dic; } /// /// 返回 userIds 参数中 userId 所关注的用户Id列表 /// public static async Task> CheckFocusState(this DbRESTFulRepository repository, long userId, IEnumerable userIds, IDbConnection conn = null) { var list = await repository.QueryAsync("select userId from n_user_fan where fanId=@userId and userId in @userIds", new { userId, userIds }, conn); var count = list.Count(); if (count > 0) { return list.ToHashSet(); } return new HashSet(0); } /// /// 返回 userIds 参数中 userId 所被关注的用户Id列表 /// public static async Task> CheckFanState(this DbRESTFulRepository repository, long userId, IEnumerable userIds, IDbConnection conn = null) { var list = await repository.QueryAsync("select fanId from n_user_fan where userId=@userId and fanId in @userIds", new { userId, userIds }, conn); var count = list.Count(); if (count > 0) { return list.ToHashSet(); } return new HashSet(0); } /// /// 通过用户编号查询用户的隐私设置 /// public static async Task GetPrivacySettingByUserId(this DbRESTFulRepository repository, long userId, RedisCacheProvider cacheProvider, IDbConnection conn = null) { var cacheKey = CacheKeys.UserPrivacySetting(userId); var cacheVal = await cacheProvider.Get(cacheKey); if (cacheVal != null) { return UserPrivacySetting.InstanceByIntValue(cacheVal.Value); } else { UserPrivacySetting setting = await repository.QuerySingleOrDefaultAsync($"select likePostRecordsHidden, collectPostRecordsHidden, focusRecordsHidden, fansHidden, personalRecommend from n_user_settings where userId={userId}", null, conn); bool watermark = await repository.QuerySingleOrDefaultAsync($"SELECT watermark FROM n_user WHERE id={userId}", null, conn); if (setting == null) setting = new UserPrivacySetting(); setting.watermark = watermark; await cacheProvider.Set(cacheKey, setting.GetIntValue(), CacheKeys.UserPrivacySettingCacheSecs); return setting; } } public static async Task GetUserState(this DbRESTFulRepository repository, long userId, RedisCacheProvider cacheProvider, IDbConnection conn = null) { var cacheKey = CacheKeys.UserStateValue(userId); var cacheVal = await cacheProvider.Get(cacheKey); if (cacheVal != null) { return cacheVal.Value; } else { var info = await repository.QuerySingleOrDefaultAsync($"select state from n_user where id={userId}", null, conn); var state = info?.state ?? -1; await cacheProvider.Set(cacheKey, state, CacheKeys.UserStateValueCacheSecs); return state; } } } }