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;
}
}
}