|
|
|
|
using GDZZ.Core;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using GDZZ.Application.Entity;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using K4os.Hash.xxHash;
|
|
|
|
|
using GDZZ.Core.Entity;
|
|
|
|
|
using Furion;
|
|
|
|
|
using GDZZ.Application.Help;
|
|
|
|
|
using Furion.LinqBuilder;
|
|
|
|
|
using System;
|
|
|
|
|
using static K4os.Compression.LZ4.Engine.Pubternal;
|
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
|
|
|
using GDZZ.Application.Service.LiveHistoryContacts.Dto;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using Yitter.IdGenerator;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using ICacheService = GDZZ.Application.Help.ICacheService;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.ComponentModel.Design;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
|
|
|
|
|
namespace GDZZ.Application
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 聊天服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
[ApiDescriptionSettings("Application", Name = "LiveHistoryContacts", Order = 1)]
|
|
|
|
|
public class LiveHistoryContactsService : ILiveHistoryContactsService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private readonly SqlSugarRepository<LiveHistoryContacts> _rep; //聊天历史任务列表仓储
|
|
|
|
|
private readonly SqlSugarRepository<BaseUser> Baseuser; // wx用户仓储
|
|
|
|
|
private readonly SqlSugarRepository<LiveMessage> liveMessageRep; //消息仓储
|
|
|
|
|
private readonly SqlSugarRepository<LiveUserFriend> liveUserFriend; //好友表仓储
|
|
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRep; // 用户表仓储
|
|
|
|
|
private readonly SqlSugarRepository<OnlineUser> _sysOnlineUerRep; // 在线用户表仓储
|
|
|
|
|
private readonly ICacheService cacheService;
|
|
|
|
|
private readonly IHubContext<ChatHub, IChatClient> _chatHubContext;
|
|
|
|
|
private readonly UploadFileOptions _options;
|
|
|
|
|
|
|
|
|
|
public LiveHistoryContactsService(SqlSugarRepository<LiveHistoryContacts> rep,
|
|
|
|
|
ICacheService cacheService,
|
|
|
|
|
IOptions<UploadFileOptions> options,
|
|
|
|
|
SqlSugarRepository<BaseUser> Baseuser,
|
|
|
|
|
SqlSugarRepository<SysUser> _sysUserRep,
|
|
|
|
|
SqlSugarRepository<OnlineUser> sysOnlineUerRep,
|
|
|
|
|
SqlSugarRepository<LiveUserFriend> liveUserFriend,
|
|
|
|
|
IHubContext<ChatHub, IChatClient> chatHubContext,
|
|
|
|
|
SqlSugarRepository<LiveMessage> liveMessageRep)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
_rep = rep;
|
|
|
|
|
_options = options.Value;
|
|
|
|
|
this.Baseuser= Baseuser;
|
|
|
|
|
this.cacheService = cacheService;
|
|
|
|
|
this._chatHubContext= chatHubContext;
|
|
|
|
|
this._sysOnlineUerRep = sysOnlineUerRep;
|
|
|
|
|
this.liveUserFriend = liveUserFriend;
|
|
|
|
|
this.liveMessageRep = liveMessageRep;
|
|
|
|
|
this._sysUserRep = _sysUserRep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 聊天列表
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 新增联系人
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/Mini/LiveHistoryContacts/AddLive")]
|
|
|
|
|
public async Task<dynamic> AddLive(AddLiveFriendInput input)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
SysUser user = new SysUser();
|
|
|
|
|
if (input.CompanyID.IsNullOrZero())
|
|
|
|
|
{
|
|
|
|
|
user = await this._sysUserRep.FirstOrDefaultAsync(x => x.Id == input.UserId);
|
|
|
|
|
if (user.IsNullOrZero())
|
|
|
|
|
throw Oops.Oh(ErrorCode.xg1002);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var buser = await this.Baseuser.FirstOrDefaultAsync(x => x.CompanyID == input.CompanyID);
|
|
|
|
|
user = await this._sysUserRep.Where(x => x.Id == buser.CreatedUserId).SingleAsync();
|
|
|
|
|
if (user.IsNullOrZero())
|
|
|
|
|
throw Oops.Oh(ErrorCode.xg1002);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//判断是是好友
|
|
|
|
|
var fends =await this.liveUserFriend.Where(x => x.FriendID == UserManager.UserId && x.CreatedUserId == user.Id).FirstAsync();
|
|
|
|
|
if (fends.IsNullOrZero())
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
List<LiveUserFriend> friends = new List<LiveUserFriend>();
|
|
|
|
|
if(user.Id != UserManager.UserId)
|
|
|
|
|
{
|
|
|
|
|
friends.Add(new LiveUserFriend()
|
|
|
|
|
{
|
|
|
|
|
FriendID = user.Id,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
friends.Add(new LiveUserFriend()
|
|
|
|
|
{
|
|
|
|
|
FriendID = UserManager.UserId,
|
|
|
|
|
CreatedUserId = user.Id
|
|
|
|
|
});
|
|
|
|
|
foreach (var item in friends)
|
|
|
|
|
{
|
|
|
|
|
await this.liveUserFriend.InsertAsync(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!await this.cacheService.DelLiveHistoryService(UserManager.UserId))
|
|
|
|
|
throw Oops.Oh(ErrorCode.B1004);
|
|
|
|
|
return user;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 咨询聊天
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/Mini/LiveHistoryContacts/AddConsultLive")]
|
|
|
|
|
public async Task<dynamic> AddConsultLive(AddLiveFriendInput input)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var user = await this._sysUserRep.Where(x => x.Id == input.UserId).SingleAsync();
|
|
|
|
|
if (user.IsNullOrZero())
|
|
|
|
|
throw Oops.Oh(ErrorCode.xg1002);
|
|
|
|
|
|
|
|
|
|
//判断是是好友
|
|
|
|
|
var fends = await this.liveUserFriend.Where(x => x.FriendID == UserManager.UserId && x.CreatedUserId == user.Id).FirstAsync();
|
|
|
|
|
if (fends.IsNullOrZero())
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
List<LiveUserFriend> friends = new List<LiveUserFriend>();
|
|
|
|
|
if (user.Id != UserManager.UserId)
|
|
|
|
|
{
|
|
|
|
|
friends.Add(new LiveUserFriend()
|
|
|
|
|
{
|
|
|
|
|
FriendID = user.Id,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
friends.Add(new LiveUserFriend()
|
|
|
|
|
{
|
|
|
|
|
FriendID = UserManager.UserId,
|
|
|
|
|
CreatedUserId = user.Id
|
|
|
|
|
});
|
|
|
|
|
foreach (var item in friends)
|
|
|
|
|
{
|
|
|
|
|
await this.liveUserFriend.InsertAsync(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await this.cacheService.DelLiveHistoryService(UserManager.UserId);
|
|
|
|
|
return user;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取联系人列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("/Mini/LiveHistoryContacts/list")]
|
|
|
|
|
public async Task<List<LiveHistoryLists>> List()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var history = await this.cacheService.GetLiveHistoryService(UserManager.UserId);
|
|
|
|
|
if (!history.IsNullOrEmpty())
|
|
|
|
|
return history;
|
|
|
|
|
|
|
|
|
|
List<LiveHistoryLists> historyLists = new List<LiveHistoryLists>();
|
|
|
|
|
//获取好友列表
|
|
|
|
|
var friends = await this.liveUserFriend.Where(x => x.CreatedUserId == UserManager.UserId).ToListAsync();
|
|
|
|
|
foreach (var item in friends)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//获取用户信息
|
|
|
|
|
var sysUser = await this._sysUserRep.SingleAsync(x => x.Id == item.FriendID);
|
|
|
|
|
if (sysUser == null)
|
|
|
|
|
continue;
|
|
|
|
|
var liveHis = new LiveHistoryLists()
|
|
|
|
|
{
|
|
|
|
|
Avatar = sysUser.Avatar,
|
|
|
|
|
DisplayName = sysUser.NickName,
|
|
|
|
|
Id = item.FriendID,
|
|
|
|
|
Index = sysUser.Name.Substring(0, 1),
|
|
|
|
|
LastSendTime = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//查询聊天记录
|
|
|
|
|
//rm -rf mk dir ls install cd home //ru-rf
|
|
|
|
|
var live = await this.liveMessageRep.Where(x => x.CreatedUserId == UserManager.UserId && x.OtherUserID == item.FriendID || (x.CreatedUserId == item.FriendID && x.OtherUserID == UserManager.UserId)).OrderByDescending(x => x.CreatedTime).FirstAsync();
|
|
|
|
|
|
|
|
|
|
if (live != null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var isNow = Utils.ShowHelp(live.SendTime);
|
|
|
|
|
if (isNow)
|
|
|
|
|
{
|
|
|
|
|
liveHis.LastSendTimeData = live.SendTime.ToString("HH:mm:ss");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
liveHis.LastSendTimeData = live.SendTime.ToString("yyyy/MM/dd");
|
|
|
|
|
}
|
|
|
|
|
liveHis.LastSendTime = (live.SendTime.ToUniversalTime().Ticks - 621355968000000000) / 10000;
|
|
|
|
|
liveHis.Unread = await this.cacheService.GetUnreadAsync(UserManager.UserId, live.Id);
|
|
|
|
|
liveHis.LastContent = live.Content;
|
|
|
|
|
liveHis.Type = live.Type;
|
|
|
|
|
}
|
|
|
|
|
historyLists.Add(liveHis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await this.cacheService.SetLiveHistoryService(UserManager.UserId, historyLists);
|
|
|
|
|
return historyLists;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 聊天详情
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取聊天详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("/Mini/LiveHistoryContacts/GetMessageLists")]
|
|
|
|
|
public async Task<List<LiveMessageList>> GetMessageLists(long OtherUserID)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.liveMessageRep.AsQueryable()
|
|
|
|
|
.Filter("TenantId", true)
|
|
|
|
|
.Where(x => x.CreatedUserId == UserManager.UserId && x.OtherUserID == OtherUserID
|
|
|
|
|
|| (x.CreatedUserId == OtherUserID && x.OtherUserID == UserManager.UserId)).ToListAsync();
|
|
|
|
|
return res.Adapt<List<LiveMessageList>>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 增加聊天详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/Mini/LiveHistoryContacts/addMessage")]
|
|
|
|
|
public async Task AddMessage(AddLiveMessageInput input)
|
|
|
|
|
{
|
|
|
|
|
var entity = input.Adapt<LiveMessage>();
|
|
|
|
|
entity.Content = Utils.stringToUnicode(entity.Content);
|
|
|
|
|
var live = this.liveMessageRep.InsertReturnEntity(entity);
|
|
|
|
|
var user = await _sysOnlineUerRep.Where(m => m.UserId == entity.OtherUserID).OrderByDescending(x=>x.LastTime).FirstAsync();
|
|
|
|
|
if (user != null)
|
|
|
|
|
{
|
|
|
|
|
var livemes = new LiveMessageInput()
|
|
|
|
|
{
|
|
|
|
|
id = live.Id.ToString(),
|
|
|
|
|
type = live.Type,
|
|
|
|
|
FileName = live.FileName,
|
|
|
|
|
content = live.Content,
|
|
|
|
|
sendTime = new DateTimeOffset((DateTime)live.CreatedTime).ToUnixTimeSeconds(),
|
|
|
|
|
status = "succeed",
|
|
|
|
|
toContactId = entity.OtherUserID,
|
|
|
|
|
fromUser = new Fromuser()
|
|
|
|
|
{
|
|
|
|
|
avatar = this._sysUserRep.FirstOrDefaultAsync(x => x.Id == UserManager.UserId).Result.Avatar,
|
|
|
|
|
displayName = UserManager.Name,
|
|
|
|
|
id = UserManager.UserId
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
var livejson = livemes.ToJsonString();
|
|
|
|
|
|
|
|
|
|
await _chatHubContext.Clients.Client(user.ConnectionId).SendMessage(livejson, "SendMessage");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//设置消息支付状态 --存入reids
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 上传文件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/Mini/LiveHistoryContacts/upload")]
|
|
|
|
|
public async Task<LiveFileOutput> UploadFileDefault(IFormFile file)
|
|
|
|
|
{
|
|
|
|
|
// 可以读取系统配置来决定将文件存储到什么地方
|
|
|
|
|
return await UploadFile(file, _options.Default.path, FileLocation.LOCAL);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 上传文件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file"></param>
|
|
|
|
|
/// <param name="pathType"></param>
|
|
|
|
|
/// <param name="fileLocation"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static async Task<LiveFileOutput> UploadFile(IFormFile file, string pathType, FileLocation fileLocation)
|
|
|
|
|
{
|
|
|
|
|
var fileSizeKb = (long)(file.Length / 1024.0); // 文件大小KB
|
|
|
|
|
var originalFilename = file.FileName; // 文件原始名称
|
|
|
|
|
var fileSuffix = Path.GetExtension(file.FileName).ToLower(); // 文件后缀
|
|
|
|
|
|
|
|
|
|
// 先存库获取Id
|
|
|
|
|
var id = YitIdHelper.NextId();
|
|
|
|
|
var newFile = new SysFile
|
|
|
|
|
{
|
|
|
|
|
Id = id,
|
|
|
|
|
FileLocation = (int)FileLocation.LOCAL,
|
|
|
|
|
FileBucket = FileLocation.LOCAL.ToString(),
|
|
|
|
|
FileObjectName = $"{YitIdHelper.NextId()}{fileSuffix}",
|
|
|
|
|
FileOriginName = originalFilename,
|
|
|
|
|
FileSuffix = fileSuffix.TrimStart('.'),
|
|
|
|
|
FileSizeKb = fileSizeKb.ToString(),
|
|
|
|
|
FilePath = pathType
|
|
|
|
|
};
|
|
|
|
|
newFile = await App.GetService<ISqlSugarClient>().Insertable(newFile).ExecuteReturnEntityAsync();
|
|
|
|
|
|
|
|
|
|
var finalName = newFile.FileObjectName; // 生成文件的最终名称
|
|
|
|
|
if (fileLocation == FileLocation.LOCAL) // 本地存储
|
|
|
|
|
{
|
|
|
|
|
var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, pathType);
|
|
|
|
|
if (!Directory.Exists(filePath))
|
|
|
|
|
Directory.CreateDirectory(filePath);
|
|
|
|
|
using (var stream = File.Create(Path.Combine(filePath, finalName)))
|
|
|
|
|
{
|
|
|
|
|
await file.CopyToAsync(stream);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (fileLocation == FileLocation.ALIYUN) // 阿里云OSS
|
|
|
|
|
{
|
|
|
|
|
var filePath = pathType + finalName;
|
|
|
|
|
OSSClientUtil.DeletefileCode(filePath);
|
|
|
|
|
|
|
|
|
|
var stream = file.OpenReadStream();
|
|
|
|
|
OSSClientUtil.PushMedia(stream, filePath);
|
|
|
|
|
}
|
|
|
|
|
newFile.FileObjectName = finalName;
|
|
|
|
|
return new LiveFileOutput() { Id = finalName, FileUrl= "/"+pathType + "/"+ finalName }; // 返回文件唯一标识
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|