2025-11-10 15:03:02 +08:00
|
|
|
|
using Mapster;
|
2025-11-06 16:59:29 +08:00
|
|
|
|
using Microsoft.Extensions.Caching.Distributed;
|
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
|
using Volo.Abp.Application.Services;
|
|
|
|
|
|
using Volo.Abp.Caching;
|
|
|
|
|
|
using Yi.Framework.AiHub.Application.Contracts.Dtos.Announcement;
|
|
|
|
|
|
using Yi.Framework.AiHub.Application.Contracts.IServices;
|
|
|
|
|
|
using Yi.Framework.AiHub.Domain.Entities;
|
|
|
|
|
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Yi.Framework.AiHub.Application.Services;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 公告服务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class AnnouncementService : ApplicationService, IAnnouncementService
|
|
|
|
|
|
{
|
2025-11-10 15:03:02 +08:00
|
|
|
|
private readonly ISqlSugarRepository<AnnouncementAggregateRoot> _announcementRepository;
|
2025-11-06 16:59:29 +08:00
|
|
|
|
private readonly IConfiguration _configuration;
|
|
|
|
|
|
private readonly IDistributedCache<AnnouncementCacheDto> _announcementCache;
|
|
|
|
|
|
private const string AnnouncementCacheKey = "AiHub:Announcement";
|
|
|
|
|
|
|
|
|
|
|
|
public AnnouncementService(
|
2025-11-10 15:03:02 +08:00
|
|
|
|
ISqlSugarRepository<AnnouncementAggregateRoot> announcementRepository,
|
2025-11-06 16:59:29 +08:00
|
|
|
|
IConfiguration configuration,
|
|
|
|
|
|
IDistributedCache<AnnouncementCacheDto> announcementCache)
|
|
|
|
|
|
{
|
|
|
|
|
|
_announcementRepository = announcementRepository;
|
|
|
|
|
|
_configuration = configuration;
|
|
|
|
|
|
_announcementCache = announcementCache;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取公告信息
|
|
|
|
|
|
/// </summary>
|
2025-11-10 15:03:02 +08:00
|
|
|
|
public async Task<List<AnnouncementLogDto>> GetAsync()
|
2025-11-06 16:59:29 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 使用 GetOrAddAsync 从缓存获取或添加数据,缓存1小时
|
|
|
|
|
|
var cacheData = await _announcementCache.GetOrAddAsync(
|
|
|
|
|
|
AnnouncementCacheKey,
|
|
|
|
|
|
async () => await LoadAnnouncementDataAsync(),
|
|
|
|
|
|
() => new DistributedCacheEntryOptions
|
|
|
|
|
|
{
|
|
|
|
|
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2025-11-10 15:03:02 +08:00
|
|
|
|
return cacheData?.Logs ?? new List<AnnouncementLogDto>();
|
2025-11-06 16:59:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 从数据库加载公告数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private async Task<AnnouncementCacheDto> LoadAnnouncementDataAsync()
|
|
|
|
|
|
{
|
2026-01-07 20:10:42 +08:00
|
|
|
|
// 1️⃣ 一次性查出全部公告(不排序)
|
2025-11-06 16:59:29 +08:00
|
|
|
|
var logs = await _announcementRepository._DbQueryable
|
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
2026-01-07 20:10:42 +08:00
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
// 2️⃣ 内存中处理排序
|
|
|
|
|
|
var orderedLogs = logs
|
|
|
|
|
|
.OrderByDescending(x =>
|
|
|
|
|
|
x.StartTime <= now &&
|
|
|
|
|
|
(x.EndTime == null || x.EndTime >= now)
|
|
|
|
|
|
)
|
|
|
|
|
|
.ThenByDescending(x => x.StartTime)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
2025-11-06 16:59:29 +08:00
|
|
|
|
// 转换为 DTO
|
2026-01-07 20:10:42 +08:00
|
|
|
|
var logDtos = orderedLogs.Adapt<List<AnnouncementLogDto>>();
|
2025-11-06 16:59:29 +08:00
|
|
|
|
return new AnnouncementCacheDto
|
|
|
|
|
|
{
|
|
|
|
|
|
Logs = logDtos
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|