using NCC.Common.Core.Manager;
using NCC.Common.Enum;
using NCC.Common.Extension;
using NCC.Common.Filter;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.FriendlyException;
using NCC.JsonSerialization;
using NCC.LinqBuilder;
using NCC.Message.Entitys;
using NCC.Message.Entitys.Dto.Message;
using NCC.Message.Extensions;
using NCC.Message.Interfaces.Message;
using NCC.System.Entitys.Permission;
using NCC.System.Interfaces.Permission;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using NCC.Message.Entitys.Dto.IM;
namespace NCC.Message.Service
{
///
/// 系统消息
/// 版 本:V1.20.15
/// 版 权:Wesley(https://www.NCCsoft.com)
/// 作 者:NCC开发平台组
/// 日 期:2022-03-16
///
[ApiDescriptionSettings(Tag = "Message", Name = "message", Order = 240)]
[Route("api/[controller]")]
public class MessageService : IMessageService, IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository _messageRepository;
private readonly ISqlSugarRepository _messageReceiveRepository;
private readonly SqlSugarScope db;
private readonly IUserManager _userManager;
private readonly IUsersService _usersService;
private readonly ISqlSugarRepository _IMContentRepository;
private readonly ISqlSugarRepository _roomMessageRepository;
///
///
///
///
///
///
///
public MessageService(ISqlSugarRepository messageRepository, ISqlSugarRepository messageReceiveRepository, IUsersService usersService, IUserManager userManager, ISqlSugarRepository iMContentRepository, ISqlSugarRepository roomMessageRepository)
{
_messageRepository = messageRepository;
_messageReceiveRepository = messageReceiveRepository;
db = messageRepository.Context;
_usersService = usersService;
_userManager = userManager;
_IMContentRepository = iMContentRepository;
_roomMessageRepository = roomMessageRepository;
}
#region Get
///
/// 列表(通知公告)
///
/// 请求参数
///
[HttpGet("Notice")]
public async Task GetNoticeList([FromQuery] PageInputBase input)
{
var list = await _messageRepository.Context.Queryable((a, b) =>
new JoinQueryInfos(JoinType.Left, b.Id == a.CreatorUserId)).Select((a, b) =>
new MessageNoticeOutput
{
id = a.Id,
lastModifyTime = a.LastModifyTime,
enabledMark = a.EnabledMark,
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
title = a.Title,
deleteMark = SqlFunc.ToString(a.DeleteMark),
type = a.Type
}).MergeTable().Where(m => m.type == 1 && m.deleteMark == null)
.WhereIF(!string.IsNullOrEmpty(input.keyword), m => m.title.Contains(input.keyword))
.OrderBy(t => t.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(list);
}
///
/// 列表(通知公告/系统消息/私信消息)
///
/// 请求参数
///
[HttpGet("")]
public async Task GetMessageList([FromQuery] MessageListInput input)
{
var list = await _messageRepository.Context.Queryable(
(a, b, c) => new JoinQueryInfos(JoinType.Left, a.Id == b.MessageId, JoinType.Left,
a.CreatorUserId == c.Id)).Select((a, b, c) =>
new MessageListOutput
{
id = a.Id,
lastModifyTime = a.LastModifyTime,
enabledMark = a.EnabledMark,
creatorUser = SqlFunc.MergeString(c.RealName, "/", c.Account),
title = a.Title,
deleteMark = a.DeleteMark,
type = a.Type,
isRead = b.IsRead,
userId = b.UserId
}).MergeTable()
.Where(m => m.userId == _userManager.UserId && m.deleteMark == null)
.WhereIF(input.type.IsNotEmptyOrNull(), x => x.type == input.type)
.WhereIF(!string.IsNullOrEmpty(input.keyword), m => m.title.Contains(input.keyword))
.OrderBy(t => t.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(list);
}
///
/// 信息
///
/// 主键值
///
[HttpGet("{id}")]
public async Task GetInfo_Api(string id)
{
var data = await _messageRepository.Context.Queryable(
(a, b) => new JoinQueryInfos(JoinType.Left, a.CreatorUserId == b.Id))
.Select((a, b) =>
new MessageInfoOutput
{
id = a.Id,
lastModifyTime = a.LastModifyTime,
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
title = a.Title,
deleteMark = a.DeleteMark,
bodyText = a.BodyText
}).MergeTable().
Where(m => m.id == id && m.deleteMark == null).FirstAsync();
return data;
}
///
/// 读取消息
///
/// 主键值
///
[HttpGet("ReadInfo/{id}")]
public async Task ReadInfo(string id)
{
var data = await _messageRepository.Context.Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.CreatorUserId == b.Id))
.Select((a, b) => new MessageReadInfoOutput
{
id = a.Id,
lastModifyTime = a.LastModifyTime,
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
title = a.Title,
deleteMark = a.DeleteMark,
bodyText = a.BodyText
}).MergeTable().Where(m => m.id == id && m.deleteMark == null)
.OrderBy(t => t.lastModifyTime).FirstAsync();
if (data != null)
await MessageRead(id);
return data;
}
#endregion
#region 群组/房间
#endregion
#region Post
///
/// 删除
///
/// 主键值
///
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await GetInfo(id);
var isOk = await Delete(entity);
if (isOk < 1)
throw NCCException.Oh(ErrorCode.COM1002);
}
///
/// 新建
///
/// 实体对象
///
[HttpPost("")]
public async Task Create([FromBody] MessageCrInput input)
{
var entity = input.Adapt();
entity.Type = 1;
entity.EnabledMark = 0;
var isOk = await Create(entity);
if (isOk < 1)
throw NCCException.Oh(ErrorCode.COM1000);
}
///
/// 更新
///
/// 主键值
/// 实体对象
///
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] MessageUpInput input)
{
var entity = input.Adapt();
var isOk = await Update(entity);
if (isOk < 1)
throw NCCException.Oh(ErrorCode.COM1001);
}
///
/// 发布公告
///
/// 主键值
///
[HttpPut("{id}/Actions/Release")]
public async Task Release(string id)
{
var entity = await GetInfo(id);
if (entity != null)
{
var userList = await _usersService.GetList();
entity.ToUserIds = string.Join(",", userList.Select(m => m.Id).ToList());
//发送
await SentNotice(entity.ToUserIds.Split(',').ToList(), entity);
}
}
///
/// 全部已读
///
///
[HttpPost("Actions/ReadAll")]
public async Task AllRead()
{
await MessageRead("");
}
///
/// 删除记录
///
/// 请求参数
///
[HttpDelete("Record")]
public async Task DeleteRecord_Api([FromBody] dynamic postParam)
{
string[] ids = postParam.ids.ToString().Split(',');
var isOk = await DeleteRecord(_userManager.UserId, ids.ToList());
if (isOk < 1)
throw NCCException.Oh(ErrorCode.COM1002);
}
#endregion
#region PublicMethod
///
/// 列表
///
/// 类型
///
[NonAction]
public async Task> GetList(int type)
{
return await _messageRepository.Entities.Where(m => m.Type == type && m.DeleteMark == null).ToListAsync();
}
///
/// 信息
///
/// 主键值
///
[NonAction]
public async Task GetInfo(string id)
{
return await _messageRepository.FirstOrDefaultAsync(x => x.Id == id && x.DeleteMark == null);
}
///
/// 默认公告(app)
///
///
[NonAction]
public string GetInfoDefaultNotice()
{
var entity = _messageRepository.Entities.Where(x => x.Type == 1 && x.DeleteMark == null).OrderBy(x => x.CreatorTime, OrderByType.Desc).First();
return entity == null ? "" : entity.Title;
}
///
/// 默认消息(app)
///
///
///
[NonAction]
public string GetInfoDefaultMessage(string userId)
{
var entity = db.Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.MessageId))
.Where((a, b) => a.Type == 2 && a.DeleteMark == null && b.UserId == userId).OrderBy(a => a.CreatorTime, OrderByType.Desc).Select(a => a).First();
return entity == null ? "" : entity.Title;
}
///
/// 删除
///
/// 实体对象
[NonAction]
public async Task Delete(MessageEntity entity)
{
try
{
db.BeginTran();
await _messageReceiveRepository.DeleteAsync(x => x.MessageId == entity.Id);
var total = await _messageRepository.Context.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.Delete()).ExecuteCommandAsync();
db.CommitTran();
return total;
}
catch (Exception)
{
db.RollbackTran();
return 0;
}
}
///
/// 创建
///
/// 实体对象
[NonAction]
public async Task Create(MessageEntity entity)
{
return await _messageRepository.Context.Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
}
///
/// 创建
///
/// 实体对象
/// 收件用户
[NonAction]
public async Task Create(MessageEntity entity, List receiveEntityList)
{
try
{
db.BeginTran();
await _messageReceiveRepository.InsertAsync(receiveEntityList);
var total = await _messageRepository.Context.Insertable(entity).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
db.CommitTran();
return total;
}
catch (Exception ex)
{
db.RollbackTran();
return 0;
}
}
///
/// 更新
///
/// 实体对象
[NonAction]
public async Task Update(MessageEntity entity)
{
return await _messageRepository.Context.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
}
///
/// 更新
///
/// 实体对象
/// 收件用户
[NonAction]
public async Task Update(MessageEntity entity, List receiveEntityList)
{
try
{
db.BeginTran();
await _messageReceiveRepository.InsertAsync(receiveEntityList);
var total = await _messageRepository.Context.Updateable(entity).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
db.CommitTran();
return total;
}
catch (Exception ex)
{
db.RollbackTran();
return 0;
}
}
///
/// 消息已读(单条)
///
/// 当前用户
/// 消息主键
[NonAction]
public async Task MessageRead(string userId, string messageId)
{
await db.Updateable().SetColumns(it => it.ReadCount == it.ReadCount + 1).SetColumns(x => new MessageReceiveEntity()
{
IsRead = 1,
ReadTime = DateTime.Now
}).Where(x => x.UserId == userId && x.MessageId == messageId).ExecuteCommandAsync();
}
///
/// 消息已读(全部)
///
/// id
[NonAction]
public async Task MessageRead(string id)
{
try
{
db.BeginTran();
var whereParams = LinqExpression.And();
whereParams = whereParams.And(x => x.UserId == _userManager.UserId && x.IsRead == 0);
if (id.IsNotEmptyOrNull())
whereParams = whereParams.And(x => x.MessageId == id);
await db.Updateable().SetColumns(it => it.ReadCount == it.ReadCount + 1).SetColumns(x => new MessageReceiveEntity()
{
IsRead = 1,
ReadTime = DateTime.Now
}).Where(whereParams).ExecuteCommandAsync();
db.CommitTran();
}
catch (Exception e)
{
db.RollbackTran();
}
}
///
/// 删除记录
///
/// 当前用户
/// 消息Id
[NonAction]
public async Task DeleteRecord(string userId, List messageIds)
{
return await _messageReceiveRepository.DeleteAsync(m => m.UserId == userId && messageIds.Contains(m.MessageId));
}
///
/// 获取未读数量(含 通知公告、系统消息)
///
/// 用户主键
///
[NonAction]
public async Task GetUnreadCount(string userId)
{
return await _messageReceiveRepository.CountAsync(m => m.UserId == userId && m.IsRead == 0);
}
///
/// 获取公告未读数量
///
/// 用户主键
///
[NonAction]
public int GetUnreadNoticeCount(string userId)
{
return db.Queryable((m, mr) => new JoinQueryInfos(JoinType.Left, m.Id == mr.MessageId)).Select((m, mr) => new { mr.Id, mr.UserId, mr.IsRead, m.Type, m.DeleteMark }).MergeTable().Where(x => x.Type == 1 && x.DeleteMark == null && x.UserId == userId && x.IsRead == 0).Count();
}
///
/// 获取消息未读数量
///
/// 用户主键
///
[NonAction]
public int GetUnreadMessageCount(string userId)
{
return db.Queryable((m, mr) => new JoinQueryInfos(JoinType.Left, m.Id == mr.MessageId)).Select((m, mr) => new { mr.Id, mr.UserId, mr.IsRead, m.Type, m.DeleteMark }).MergeTable().Where(x => x.Type == 2 && x.DeleteMark == null && x.UserId == userId && x.IsRead == 0).Count();
}
///
/// 发送公告
///
/// 发送用户
/// 消息信息
[NonAction]
public async Task SentNotice(List toUserIds, MessageEntity entity)
{
try
{
entity.EnabledMark = 1;
List receiveEntityList = new List();
foreach (var item in toUserIds)
{
MessageReceiveEntity messageReceiveEntity = new MessageReceiveEntity();
messageReceiveEntity.Id = YitIdHelper.NextId().ToString();
messageReceiveEntity.MessageId = entity.Id;
messageReceiveEntity.UserId = item;
messageReceiveEntity.IsRead = 0;
receiveEntityList.Add(messageReceiveEntity);
}
await Update(entity, receiveEntityList);
//消息推送 - PC端
foreach (var item in WebSocketClientCollection._clients.FindAll(it => it.TenantId == _userManager.TenantId))
{
if (toUserIds.Contains(item.UserId))
{
await item.SendMessageAsync(new { method = "messagePush", userId = _userManager.UserId, toUserId = toUserIds, title = entity.Title, unreadNoticeCount = 1 }.Serialize());
}
}
}
catch (Exception ex)
{
throw NCCException.Oh(ErrorCode.D7003);
}
}
///
/// 发送站内消息
///
/// 发送用户
/// 标题
/// 内容
[NonAction]
public async Task SentMessage(List toUserIds, string title, string bodyText = null)
{
try
{
MessageEntity entity = new MessageEntity();
entity.Id = YitIdHelper.NextId().ToString();
entity.Title = title;
entity.BodyText = bodyText;
entity.Type = 2;
entity.LastModifyTime = DateTime.Now;
entity.LastModifyUserId = _userManager.UserId;
List receiveEntityList = new List();
foreach (var item in toUserIds)
{
MessageReceiveEntity messageReceiveEntity = new MessageReceiveEntity();
messageReceiveEntity.Id = YitIdHelper.NextId().ToString();
messageReceiveEntity.MessageId = entity.Id;
messageReceiveEntity.UserId = item;
messageReceiveEntity.IsRead = 0;
receiveEntityList.Add(messageReceiveEntity);
}
await Create(entity, receiveEntityList);
//消息推送 - PC端
foreach (var item in WebSocketClientCollection._clients)
{
if (toUserIds.Contains(item.UserId))
{
await item.SendMessageAsync(new { method = "messagePush", userId = _userManager.UserId, toUserId = toUserIds, title = entity.Title, unreadNoticeCount = 1 }.Serialize());
}
}
//消息推送 - APP
// GetuiAppPushHelper.Instance.SendNotice(userInfo.TenantId, toUserIds, "系统消息", entity.F_Title, "2");
}
catch (Exception ex)
{
throw;
}
}
#endregion
///
/// 获取群组/房间消息列表
///
/// 分页参数
/// 房间号/群组
///
[HttpPost("GetRoomMessageList/{roomNo}")]
public dynamic GetRoomMessageList( string roomNo, PageInputBase input)
{
var orderByType = input.sort == "asc" ? OrderByType.Asc : OrderByType.Desc;
var list = _IMContentRepository.Entities.Select(it => new RoomIMContentListOutput { id = it.Id, sendUserId = it.SendUserId, sendTime = it.SendTime, content = it.Content, contentType = it.ContentType, state = it.State, roomNo = it.RoomNo }).MergeTable()
.OrderBy(it => it.sendTime, orderByType)
.WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.content.Contains(input.keyword))
.Where(i => (i.roomNo == roomNo))//i.sendUserId == sendUserId &&
.ToPagedList(input.currentPage, input.pageSize);
if (input.sort == "desc")
{
list.list = list.list.ToList().OrderBy(it => it.sendTime);
}
return PageResult.SqlSugarPageResult(list);
}
///
/// 发送消息
///
///
///
///
///
///
[HttpPost("SendRoomMessage")]
public int SendRoomMessage( string roomNo, string message, string messageType, string sendUserId="")
{
RoomIMContentEntity entity = new RoomIMContentEntity();
entity.Id = YitIdHelper.NextId().ToString();
entity.SendUserId = _userManager.UserId;
entity.SendTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
entity.RoomNo = roomNo;
entity.State = 0;
entity.Content = message;
entity.ContentType = messageType;
return _IMContentRepository.Insert(entity);
}
///
/// 添加房间
///
///
[HttpPost("AddRoom")]
public async Task