feat: 新增功能

- 概要
  - 重构并扩展公告相关模型、DTO、服务,新增公告类型、图片与时间字段,调整缓存与查询处理。
  - 新增枚举 AnnouncementTypeEnum。

- 主要改动(简要)
  - Yi.Framework.AiHub.Application.Contracts/Dtos/Announcement/AnnouncementLogDto.cs
    - 新增 ImageUrl、StartTime、EndTime、Type 字段,移除 Date 字段,Title 不再默认空串。
  - Yi.Framework.AiHub.Domain/Entities
    - 重命名 AnnouncementLogAggregateRoot -> AnnouncementAggregateRoot
    - 表名由 Ai_AnnouncementLog 改为 Ai_Announcement(SugarTable 标注)
    - 新增 ImageUrl、StartTime、EndTime、Type、Remark 字段(Remark 已存在,保持)
  - Yi.Framework.AiHub.Domain.Shared/Enums/AnnouncementTypeEnum.cs
    - 新增枚举文件(Activity=1, System=2)
  - Yi.Framework.AiHub.Application.Contracts/IServices/IAnnouncementService.cs
    - GetAsync 返回类型由 AnnouncementOutput 改为 List<AnnouncementLogDto>
  - Yi.Framework.AiHub.Application/Services/AnnouncementService.cs
    - 使用 Mapster 进行 DTO 映射
    - 查询按 StartTime 降序,返回 List<AnnouncementLogDto>,缓存结构简化
  - Yi.Abp.Web/YiAbpWebModule.cs
    - 改为初始化 AnnouncementAggregateRoot 的表(Ai_Announcement)
  - Yi.Ai.Vue3/types/import_meta.d.ts
    - 移除 VITE_BUILD_COMPRESS 环境变量声明

- 重要注意/兼容性提示
  - 接口变更:IAnnouncementService.GetAsync 返回类型已改变,调用方需同步更新(之前返回 AnnouncementOutput 的代码需调整)。
  - 数据库表变更:表名从 Ai_AnnouncementLog -> Ai_Announcement,若需保留历史数据,请在部署前做好数据迁移(重命名表或迁移数据到新表结构),或使用 CodeFirst 初始化新表(当前代码在启动时会 InitTables<AnnouncementAggregateRoot>())。
  - 新增 Mapster 适配(确保项目有 Mapster 依赖)。
  - 前端类型声明移除环境变量后,前端构建/运行脚本若依赖 VITE_BUILD_COMPRESS 需同步调整。
  - 若有缓存结构(AnnouncementCacheDto)或序列化相关约定变更,确认兼容性。

- 建议操作
  - 更新所有使用 IAnnouncementService 的代码(API 层/前端适配返回结构)。
  - 在非生产环境先执行数据迁移验证(保留旧表数据或写迁移脚本)。
  - 确认 Mapster 包已安装并编译通过。
  - 前端项目检查并同步 import_meta.d.ts 变更。
This commit is contained in:
chenchun
2025-11-10 15:03:02 +08:00
parent cb49059e84
commit b7756e2112
8 changed files with 94 additions and 74 deletions

View File

@@ -1,3 +1,5 @@
using Yi.Framework.AiHub.Domain.Shared.Enums;
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Announcement;
/// <summary>
@@ -5,18 +7,33 @@ namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Announcement;
/// </summary>
public class AnnouncementLogDto
{
/// <summary>
/// 日期
/// </summary>
public string Date { get; set; } = string.Empty;
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; } = string.Empty;
public string Title { get; set; }
/// <summary>
/// 内容列表
/// </summary>
public List<string> Content { get; set; } = new List<string>();
/// <summary>
/// 图片url
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 开始时间(系统公告时间、活动开始时间)
/// </summary>
public DateTime StartTime { get; set; }
/// <summary>
/// 活动结束时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 公告类型(系统、活动)
/// </summary>
public AnnouncementTypeEnum Type{ get; set; }
}

View File

@@ -11,5 +11,5 @@ public interface IAnnouncementService
/// 获取公告信息
/// </summary>
/// <returns>公告信息</returns>
Task<AnnouncementOutput> GetAsync();
Task<List<AnnouncementLogDto>> GetAsync();
}

View File

@@ -1,3 +1,4 @@
using Mapster;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Volo.Abp.Application.Services;
@@ -14,13 +15,13 @@ namespace Yi.Framework.AiHub.Application.Services;
/// </summary>
public class AnnouncementService : ApplicationService, IAnnouncementService
{
private readonly ISqlSugarRepository<AnnouncementLogAggregateRoot> _announcementRepository;
private readonly ISqlSugarRepository<AnnouncementAggregateRoot> _announcementRepository;
private readonly IConfiguration _configuration;
private readonly IDistributedCache<AnnouncementCacheDto> _announcementCache;
private const string AnnouncementCacheKey = "AiHub:Announcement";
public AnnouncementService(
ISqlSugarRepository<AnnouncementLogAggregateRoot> announcementRepository,
ISqlSugarRepository<AnnouncementAggregateRoot> announcementRepository,
IConfiguration configuration,
IDistributedCache<AnnouncementCacheDto> announcementCache)
{
@@ -32,7 +33,7 @@ public class AnnouncementService : ApplicationService, IAnnouncementService
/// <summary>
/// 获取公告信息
/// </summary>
public async Task<AnnouncementOutput> GetAsync()
public async Task<List<AnnouncementLogDto>> GetAsync()
{
// 使用 GetOrAddAsync 从缓存获取或添加数据缓存1小时
var cacheData = await _announcementCache.GetOrAddAsync(
@@ -44,11 +45,7 @@ public class AnnouncementService : ApplicationService, IAnnouncementService
}
);
return new AnnouncementOutput
{
Version = cacheData?.Version ?? "v1.0.0",
Logs = cacheData?.Logs ?? new List<AnnouncementLogDto>()
};
return cacheData?.Logs ?? new List<AnnouncementLogDto>();
}
/// <summary>
@@ -56,25 +53,15 @@ public class AnnouncementService : ApplicationService, IAnnouncementService
/// </summary>
private async Task<AnnouncementCacheDto> LoadAnnouncementDataAsync()
{
// 从配置文件读取版本号,如果没有配置则使用默认值
var version = _configuration["AiHubVersion"] ?? "v1.0.0";
// 查询所有公告日志,按日期降序排列
var logs = await _announcementRepository._DbQueryable
.OrderByDescending(x => x.Date)
.OrderByDescending(x => x.StartTime)
.ToListAsync();
// 转换为 DTO
var logDtos = logs.Select(log => new AnnouncementLogDto
{
Date = log.Date.ToString("yyyy-MM-dd"),
Title = log.Title,
Content = log.Content
}).ToList();
var logDtos = logs.Adapt<List<AnnouncementLogDto>>();
return new AnnouncementCacheDto
{
Version = version,
Logs = logDtos
};
}

View File

@@ -0,0 +1,7 @@
namespace Yi.Framework.AiHub.Domain.Shared.Enums;
public enum AnnouncementTypeEnum
{
Activity=1,
System=2
}

View File

@@ -0,0 +1,52 @@
using SqlSugar;
using Volo.Abp.Domain.Entities.Auditing;
using Yi.Framework.AiHub.Domain.Shared.Enums;
namespace Yi.Framework.AiHub.Domain.Entities;
/// <summary>
/// 公告日志
/// </summary>
[SugarTable("Ai_Announcement")]
public class AnnouncementAggregateRoot : FullAuditedAggregateRoot<Guid>
{
public AnnouncementAggregateRoot()
{
}
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 内容列表JSON格式存储
/// </summary>
[SugarColumn(IsJson = true, IsNullable = false)]
public List<string> Content { get; set; } = new List<string>();
/// <summary>
/// 备注
/// </summary>
public string? Remark { get; set; }
/// <summary>
/// 图片url
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 开始时间(系统公告时间、活动开始时间)
/// </summary>
public DateTime StartTime { get; set; }
/// <summary>
/// 活动结束时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 公告类型(系统、活动)
/// </summary>
public AnnouncementTypeEnum Type{ get; set; }
}

View File

@@ -1,44 +0,0 @@
using SqlSugar;
using Volo.Abp.Domain.Entities.Auditing;
namespace Yi.Framework.AiHub.Domain.Entities;
/// <summary>
/// 公告日志
/// </summary>
[SugarTable("Ai_AnnouncementLog")]
[SugarIndex($"index_{nameof(Date)}", nameof(Date), OrderByType.Desc)]
public class AnnouncementLogAggregateRoot : FullAuditedAggregateRoot<Guid>
{
public AnnouncementLogAggregateRoot()
{
}
public AnnouncementLogAggregateRoot(DateTime date, string title, List<string> content)
{
Date = date;
Title = title;
Content = content;
}
/// <summary>
/// 日期
/// </summary>
public DateTime Date { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 内容列表JSON格式存储
/// </summary>
[SugarColumn(IsJson = true, IsNullable = false)]
public List<string> Content { get; set; } = new List<string>();
/// <summary>
/// 备注
/// </summary>
public string? Remark { get; set; }
}

View File

@@ -29,6 +29,7 @@ using Volo.Abp.Swashbuckle;
using Yi.Abp.Application;
using Yi.Abp.SqlsugarCore;
using Yi.Framework.AiHub.Application;
using Yi.Framework.AiHub.Application.Services;
using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.AspNetCore;
using Yi.Framework.AspNetCore.Authentication.OAuth;
@@ -354,8 +355,9 @@ namespace Yi.Abp.Web
var app = context.GetApplicationBuilder();
app.UseRouting();
//app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<AnnouncementLogAggregateRoot>();
app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<AnnouncementAggregateRoot>();
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<CardFlipTaskAggregateRoot>();
//跨域
app.UseCors(DefaultCorsPolicyName);