mahjong_group/server/CoreCms.Net.Services/SQ/SQMessageServices.cs
2026-01-01 14:35:52 +08:00

311 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***********************************************************************
* 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
{
/// <summary>
/// 站内信消息服务实现
/// </summary>
public class SQMessageServices : BaseServices<SQMessage>, 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方法
/// <summary>
/// 获取用户消息列表(包含指定用户消息和全员广播)
/// </summary>
public async Task<List<SQMessageDto>> GetUserMessageListAsync(int userId, int messageType = 0, int pageIndex = 1, int pageSize = 20)
{
// 获取用户已读的广播消息ID列表
var readBroadcastIds = await _messageReadRepository.GetUserReadMessageIdsAsync(userId);
// 查询消息:指定用户的消息 + 全员广播
var query = _unitOfWork.GetDbClient().Queryable<SQMessage>()
.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;
}
/// <summary>
/// 获取用户未读消息数量
/// </summary>
public async Task<int> GetUnreadCountAsync(int userId)
{
// 获取用户已读的广播消息ID列表
var readBroadcastIds = await _messageReadRepository.GetUserReadMessageIdsAsync(userId);
// 统计未读的指定用户消息
var userUnreadCount = await _unitOfWork.GetDbClient().Queryable<SQMessage>()
.Where(m => m.target_type == 0 && m.user_id == userId && m.is_read == false)
.CountAsync();
// 统计未读的广播消息
var broadcastQuery = _unitOfWork.GetDbClient().Queryable<SQMessage>()
.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;
}
/// <summary>
/// 标记用户所有消息为已读
/// </summary>
public async Task<bool> MarkAllAsReadAsync(int userId)
{
try
{
// 1. 标记指定用户的所有消息为已读
await _unitOfWork.GetDbClient().Updateable<SQMessage>()
.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<SQMessage>()
.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
/// <summary>
/// 发送消息给指定用户
/// </summary>
public async Task<bool> 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;
}
/// <summary>
/// 发送消息给多个用户
/// </summary>
public async Task<bool> SendToUsersAsync(List<int> 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;
}
/// <summary>
/// 发送全员广播消息
/// </summary>
public async Task<bool> 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;
}
/// <summary>
/// 发送系统通知(用于业务触发,如组局成功/失败)
/// </summary>
public async Task<bool> 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
/// <summary>
/// 重写异步插入方法
/// </summary>
public new async Task<AdminUiCallBack> InsertAsync(SQMessage entity)
{
return await _dal.InsertAsync(entity);
}
/// <summary>
/// 重写异步更新方法
/// </summary>
public new async Task<AdminUiCallBack> UpdateAsync(SQMessage entity)
{
return await _dal.UpdateAsync(entity);
}
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
public new async Task<AdminUiCallBack> DeleteByIdAsync(object id)
{
return await _dal.DeleteByIdAsync(id);
}
/// <summary>
/// 重写删除指定ID集合的数据(批量删除)
/// </summary>
public new async Task<AdminUiCallBack> DeleteByIdsAsync(int[] ids)
{
return await _dal.DeleteByIdsAsync(ids);
}
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
public new async Task<IPageList<SQMessage>> QueryPageAsync(
Expression<Func<SQMessage, bool>> predicate,
Expression<Func<SQMessage, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock);
}
#endregion
}
}