/*********************************************************************** * Project: CoreCms * ProjectName: 核心内容管理系统 * Web: https://www.corecms.net * Author: 大灰灰 * Email: jianweie@163.com * CreateTime: 2025/12/7 * Description: 站内信消息服务实现 ***********************************************************************/ using CoreCms.Net.Configuration; using CoreCms.Net.IRepository; using CoreCms.Net.IRepository.UnitOfWork; using CoreCms.Net.IServices; using CoreCms.Net.Model.Entities; using CoreCms.Net.Model.ViewModels.Basics; using CoreCms.Net.Model.ViewModels.UI; using NPOI.SS.Formula.Functions; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; namespace CoreCms.Net.Services { /// /// 站内信消息服务实现 /// public class SQMessageServices : BaseServices, ISQMessageServices { private readonly ISQMessageRepository _dal; private readonly ISQMessageReadRepository _messageReadRepository; private readonly IUnitOfWork _unitOfWork; public SQMessageServices( IUnitOfWork unitOfWork, ISQMessageRepository dal, ISQMessageReadRepository messageReadRepository) { _dal = dal; base.BaseDal = dal; _unitOfWork = unitOfWork; _messageReadRepository = messageReadRepository; } #region 前端API方法 /// /// 获取用户消息列表(包含指定用户消息和全员广播) /// public async Task> GetUserMessageListAsync(int userId, int messageType = 0, int pageIndex = 1, int pageSize = 20) { // 获取用户已读的广播消息ID列表 var readBroadcastIds = await _messageReadRepository.GetUserReadMessageIdsAsync(userId); // 查询消息:指定用户的消息 + 全员广播 var query = _unitOfWork.GetDbClient().Queryable() .Where(m => (m.target_type == 0 && m.user_id == userId) || m.target_type == 1); // 按消息类型筛选 if (messageType == 1) { // 私信:只查询指定用户且message_type=1的消息 query = query.Where(m => m.target_type == 0 && m.message_type == 1); } // 分页查询 var messages = await query .OrderBy(m => m.created_at, OrderByType.Desc) .Skip((pageIndex - 1) * pageSize) .Take(pageSize) .ToListAsync(); // 转换为DTO var result = messages.Select(m => new SQMessageDto { id = m.id, title = m.title, content = m.content, createTime = m.created_at.ToString("yyyy-MM-dd HH:mm"), messageType = m.message_type, isRead = m.target_type == 0 ? m.is_read : readBroadcastIds.Contains(m.id) }).ToList(); return result; } /// /// 获取用户未读消息数量 /// public async Task GetUnreadCountAsync(int userId) { // 获取用户已读的广播消息ID列表 var readBroadcastIds = await _messageReadRepository.GetUserReadMessageIdsAsync(userId); // 统计未读的指定用户消息 var userUnreadCount = await _unitOfWork.GetDbClient().Queryable() .Where(m => m.target_type == 0 && m.user_id == userId && m.is_read == false) .CountAsync(); // 统计未读的广播消息 var broadcastQuery = _unitOfWork.GetDbClient().Queryable() .Where(m => m.target_type == 1); if (readBroadcastIds.Count > 0) { broadcastQuery = broadcastQuery.Where(m => !readBroadcastIds.Contains(m.id)); } var broadcastUnreadCount = await broadcastQuery.CountAsync(); return userUnreadCount + broadcastUnreadCount; } /// /// 标记用户所有消息为已读 /// public async Task MarkAllAsReadAsync(int userId) { try { // 1. 标记指定用户的所有消息为已读 await _unitOfWork.GetDbClient().Updateable() .SetColumns(m => m.is_read == true) .SetColumns(m => m.updated_at == DateTime.Now) .Where(m => m.target_type == 0 && m.user_id == userId && m.is_read == false) .ExecuteCommandAsync(); // 2. 获取所有未读的广播消息 var readBroadcastIds = await _messageReadRepository.GetUserReadMessageIdsAsync(userId); var unreadBroadcasts = await _unitOfWork.GetDbClient().Queryable() .Where(m => m.target_type == 1) .WhereIF(readBroadcastIds.Count > 0, m => !readBroadcastIds.Contains(m.id)) .Select(m => m.id) .ToListAsync(); // 3. 插入已读记录 if (unreadBroadcasts.Count > 0) { var readRecords = unreadBroadcasts.Select(msgId => new SQMessageRead { message_id = msgId, user_id = userId, read_at = DateTime.Now }).ToList(); await _messageReadRepository.InsertAsync(readRecords); } return true; } catch { return false; } } #endregion #region 后台管理方法 /// /// 发送消息给指定用户 /// public async Task SendToUserAsync(int userId, string title, string content, int messageType = 1, int? senderId = null) { var message = new SQMessage { user_id = userId, target_type = 0, title = title, content = content, message_type = messageType, is_read = false, sender_id = senderId, created_at = DateTime.Now }; var result = await _unitOfWork.GetDbClient().Insertable(message).ExecuteCommandAsync(); return result > 0; } /// /// 发送消息给多个用户 /// public async Task SendToUsersAsync(List userIds, string title, string content, int messageType = 1, int? senderId = null) { if (userIds == null || userIds.Count == 0) return false; var messages = userIds.Select(userId => new SQMessage { user_id = userId, target_type = 0, title = title, content = content, message_type = messageType, is_read = false, sender_id = senderId, created_at = DateTime.Now }).ToList(); var result = await _unitOfWork.GetDbClient().Insertable(messages).ExecuteCommandAsync(); return result > 0; } /// /// 发送全员广播消息 /// public async Task SendBroadcastAsync(string title, string content, int? senderId = null) { var message = new SQMessage { user_id = null, target_type = 1, title = title, content = content, message_type = 0, // 系统通知 is_read = false, sender_id = senderId, created_at = DateTime.Now }; var result = await _unitOfWork.GetDbClient().Insertable(message).ExecuteCommandAsync(); return result > 0; } /// /// 发送系统通知(用于业务触发,如组局成功/失败) /// public async Task SendSystemNoticeAsync(int userId, string title, string content, int? relatedType = null, int? relatedId = null) { var message = new SQMessage { user_id = userId, target_type = 0, title = title, content = content, message_type = 0, // 系统通知 is_read = false, related_type = relatedType, related_id = relatedId, created_at = DateTime.Now }; var result = await _unitOfWork.GetDbClient().Insertable(message).ExecuteCommandAsync(); return result > 0; } #endregion #region 实现重写增删改查操作 /// /// 重写异步插入方法 /// public new async Task InsertAsync(SQMessage entity) { return await _dal.InsertAsync(entity); } /// /// 重写异步更新方法 /// public new async Task UpdateAsync(SQMessage entity) { return await _dal.UpdateAsync(entity); } /// /// 重写删除指定ID的数据 /// public new async Task DeleteByIdAsync(object id) { return await _dal.DeleteByIdAsync(id); } /// /// 重写删除指定ID集合的数据(批量删除) /// public new async Task DeleteByIdsAsync(int[] ids) { return await _dal.DeleteByIdsAsync(ids); } #endregion #region 重写根据条件查询分页数据 /// /// 重写根据条件查询分页数据 /// public new async Task> QueryPageAsync( Expression> predicate, Expression> orderByExpression, OrderByType orderByType, int pageIndex = 1, int pageSize = 20, bool blUseNoLock = false) { return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock); } #endregion } }