using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Net; using System.Text; using System.Threading.Tasks; using GxPress.Common.Address; using GxPress.Common.Http; using GxPress.Common.Tools; using GxPress.Repository.Interface; using GxPress.Request.App.ChatRecord; using GxPress.Service.Interface.IM; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Caching.Distributed; using Newtonsoft.Json; using GxPress.Common.Extensions; using GxPress.Service.Interface.GroupChat; namespace GxPress.Service.Implement.IM { public partial class IMService : IIMService { private readonly IWebHostEnvironment _environment; private readonly IDistributedCache _cache; private readonly IChatRecordRepository _chatRecordRepository; private readonly IUserRepository _userRepository; private readonly IGroupChatRepository _groupChatRepository; private readonly IGroupChatService groupChatService; private readonly IGroupChatUserRepository _groupChatUserRepository; private readonly IFileLibraryRepository _fileLibraryRepository; private readonly IBlacklistUserRepository _blacklistUserRepository; private readonly IOftenContactRepository _oftenContactRepository; public IMService(IWebHostEnvironment environment, IDistributedCache cache, IChatRecordRepository chatRecordRepository, IUserRepository userRepository, IFileLibraryRepository fileLibraryRepository, IGroupChatRepository groupChatRepository, IGroupChatUserRepository groupChatUserRepository, IBlacklistUserRepository blacklistUserRepository, IOftenContactRepository oftenContactRepository,IGroupChatService groupChatService) { _environment = environment; _cache = cache; _chatRecordRepository = chatRecordRepository; _userRepository = userRepository; _fileLibraryRepository = fileLibraryRepository; _groupChatRepository = groupChatRepository; _groupChatUserRepository = groupChatUserRepository; _blacklistUserRepository = blacklistUserRepository; _oftenContactRepository = oftenContactRepository; this.groupChatService=groupChatService; } /// /// 获取环信历史记录 /// /// public async Task GatherChatDataAsync() { var token = await _cache.GetAsync("ImToken"); // var times = DateTime.Now.AddHours(-2).ToString("YYYYMMDDHH"); var times = "2019112711"; var headers = new Dictionary { { "Authorization", "Bearer " + token } }; var requestUrl = Address.GetImChatMassageUrl(times); var response = await HttpClientHelper.GetHeadersAsync(requestUrl, headers); //请求成功 if (!response.IsSuccessStatusCode) { //token过期重新拉去 if (response.StatusCode == HttpStatusCode.Unauthorized) { var result = await GetTokenImAsync(); if (result) { headers = new Dictionary {{"Authorization", "Bearer " + await _cache.GetAsync("ImToken")}}; requestUrl = Address.GetImChatMassageUrl(times); response = await HttpClientHelper.GetHeadersAsync(requestUrl, headers); } } else return false; } //获取返回的内容 var content = await response.Content.ReadAsStringAsync(); var dataJson = JsonConvert.DeserializeObject(content); var url = dataJson["data"][0]["url"]; //下载GZ解压包 var gzUrl = await DecompressionGzip(url.ToString()); //获取文本内容 StreamReader sr = new StreamReader(gzUrl, Encoding.Default); string jsonText; while ((jsonText = sr.ReadLine()) != null) { await InsertChatHistory(jsonText); } return true; } /// /// 强制下线 /// /// /// public async Task DisconnectAsync(string phone) { var imServiceUrl = ConfigHelper.GetValue("ServiceAddress:ImUrl"); var token = await _cache.GetAsync("ImToken"); var url = $"{imServiceUrl}/{phone}/disconnect"; var headers = new Dictionary { { "Authorization", "Bearer " + token } }; var response = await HttpClientHelper.GetHeadersAsync(url, headers); if (response.IsSuccessStatusCode) return true; return false; } /// /// 解压GzZIP /// /// public async Task DecompressionGzip(string url) { var response = await HttpClientHelper.GetByteArrayAsync(url); string filePath; //获取路径 var path = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), ".gz", response); //解压 using (FileStream fr = File.OpenRead(path.AbsolutePath)) { using (GZipStream gz = new GZipStream(fr, CompressionMode.Decompress)) { filePath = FileHelper.GetSavePath(StringUtils.GetWebRootPath(_environment.WebRootPath), ".txt") .AbsolutePath; using (FileStream fw = File.OpenWrite(filePath)) { byte[] by = new byte[1024 * 1024]; int r = gz.Read(by, 0, by.Length); while (r > 0) { fw.Write(by, 0, r); r = gz.Read(by, 0, r); } } } } return filePath; } /// /// 分析并插入 /// /// /// public async Task InsertChatHistory(string json) { var dataJson = JsonConvert.DeserializeObject(json); //获取 单聊 或者 群聊 var chatType = dataJson.chat_type; //获取发起人的imId var imId = dataJson.from.ToString(); var toImId = dataJson.to.ToString(); //获取用户 var user = await _userRepository.GetByPhoneAsync(imId); var request = new ChatRecordInRequest { ChatType = chatType.ToString().Equals("chat") ? 1 : 2, SendUserId = user.Id }; if (request.ChatType == 1) { var toUser = await _userRepository.GetByPhoneAsync(imId); request.ReceiveUserId = toUser.Id.ToString(); } else { var toGroupChat = _groupChatRepository.GetGroupChatByImIdAsync(int.Parse(toImId)); request.ReceiveUserId = toGroupChat.GroupChatImId; } foreach (var bodies in dataJson.payload.bodies) { var typeName = bodies.type.ToString(); if (typeName.Equals("txt")) request.MsgType = 1; if (typeName.Equals("loc")) request.MsgType = 6; if (typeName.Equals("audio")) request.MsgType = 5; if (typeName.Equals("video")) request.MsgType = 4; if (typeName.Equals("file")) request.MsgType = 3; if (typeName.Equals("loc")) request.MsgType = 6; if (typeName.Equals("img")) request.MsgType = 2; //判断是否是文本 if (request.MsgType == 1) { string msg = bodies.msg.ToString(); request.Content = msg; } else if (request.MsgType == 6) { string msg = bodies.lat.ToString() + "," + bodies.lng.ToString(); request.Content = msg; } else { //获取用户数据 var url = bodies.url.ToString(); var fileName = bodies.filename.ToString(); var fileType = bodies.type.ToString().Equals("img") ? "image" : (string)Path.GetExtension(fileName); //下载 var response = await HttpClientHelper.GetByteArrayAsync(url); //获取路径 var path = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), fileName, response); var fileLibrary = new Entity.FileLibrary { FileName = fileName, FileType = fileType, FileUrl = path.RelativePath }; //file var fileLibraryId = await _fileLibraryRepository.InsertAsync(fileLibrary); request.Content = fileLibraryId.ToString(); } //保存 await _chatRecordRepository.InsertAsync(request); } return true; } /// /// 获取token /// /// public async Task GetTokenImAsync() { var imServiceUrl = ConfigHelper.GetValue("ServiceAddress:ImUrl"); var grantType = ConfigHelper.GetValue("ServiceAddress:GrantType"); var clientId = ConfigHelper.GetValue("ServiceAddress:ClientId"); var clientSecret = ConfigHelper.GetValue("ServiceAddress:ClientSecret"); var requestUrl = $"{imServiceUrl}/token"; var jsonObj = new { grant_type = grantType, client_id = clientId, client_secret = clientSecret }; var response = await HttpClientHelper.PostAsync(requestUrl, jsonObj); if (!response.IsSuccessStatusCode) { return false; } var key = "ImToken"; var tokenJson = await response.Content.ReadAsStringAsync(); var dataJsonDynamic = JsonConvert.DeserializeObject(tokenJson); string value = dataJsonDynamic.access_token.ToString(); await _cache.SetAsync(key, value, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Convert.ToInt32(dataJsonDynamic.expires_in)) }); return true; } } }