feat: 新增轮播图和资料管理模块

此提交完整实现了小程序端和管理后台的轮播图、资料管理功能:
1. 新增3个枚举类型:轮播图展示位置、跳转类型、资料文件类型
2. 新增数据库表结构SQL脚本,包含Banner、Material、MaterialFile表
3. 新增实体类定义,适配SqlSugar ORM
4. 新增服务接口与实现,包含CRUD、状态切换、列表查询等完整业务逻辑
5. 新增管理后台API控制器和小程序端API控制器
6. 新增数据传输对象,包含输入、输出、查询参数等类型
7. 实现了OSS临时文件迁移、参数校验、分页查询、软删除等基础功能
This commit is contained in:
glz
2026-07-07 15:53:25 +08:00
parent 0b829b72cb
commit 24059dfebb
16 changed files with 1534 additions and 0 deletions

View File

@ -0,0 +1,163 @@
using QYZH.InteractiveMagazine.Common.Helpers;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Banner;
/// <summary>
/// 轮播图创建/更新输入
/// </summary>
public class BannerInput
{
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 轮播图OSS路径
/// </summary>
public string ImageUrl { get; set; } = string.Empty;
/// <summary>
/// 展示位置
/// </summary>
public BannerPositionEnum Position { get; set; } = BannerPositionEnum.Home;
/// <summary>
/// 跳转类型
/// </summary>
public BannerTargetTypeEnum TargetType { get; set; } = BannerTargetTypeEnum.None;
/// <summary>
/// 跳转值
/// </summary>
public string? TargetValue { get; set; }
/// <summary>
/// 排序值,越小越靠前
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 生效开始时间
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// 生效结束时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 备注
/// </summary>
public string? Remark { get; set; }
}
/// <summary>
/// 轮播图输出
/// </summary>
public class BannerOutput
{
private string _imageUrl = string.Empty;
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 轮播图完整地址
/// </summary>
public string ImageUrl
{
get => DomainHelper.OssFullUrl(_imageUrl);
set => _imageUrl = value ?? string.Empty;
}
/// <summary>
/// 展示位置
/// </summary>
public BannerPositionEnum Position { get; set; }
/// <summary>
/// 跳转类型
/// </summary>
public BannerTargetTypeEnum TargetType { get; set; }
/// <summary>
/// 跳转值
/// </summary>
public string? TargetValue { get; set; }
/// <summary>
/// 排序值,越小越靠前
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 生效开始时间
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// 生效结束时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 备注
/// </summary>
public string? Remark { get; set; }
/// <summary>
/// 状态
/// </summary>
public int Status { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string? CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 修改人
/// </summary>
public string? UpdatedBy { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// 轮播图分页查询输入
/// </summary>
public class BannerQueryInput : PageQueryModel
{
/// <summary>
/// 标题
/// </summary>
public string? Title { get; set; }
/// <summary>
/// 展示位置
/// </summary>
public BannerPositionEnum? Position { get; set; }
/// <summary>
/// 状态
/// </summary>
public int? Status { get; set; }
}

View File

@ -0,0 +1,200 @@
using QYZH.InteractiveMagazine.Common.Helpers;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Material;
/// <summary>
/// 资料创建/更新输入
/// </summary>
public class MaterialInput
{
/// <summary>
/// 资料标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 资料名称
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 资料描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 排序值,越小越靠前
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 生效开始时间
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// 生效结束时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 资料文件列表
/// </summary>
public List<MaterialFileInput> Files { get; set; } = new();
}
/// <summary>
/// 资料文件输入
/// </summary>
public class MaterialFileInput
{
/// <summary>
/// 文件类型
/// </summary>
public MaterialFileTypeEnum FileType { get; set; }
/// <summary>
/// 文件OSS路径
/// </summary>
public string FileUrl { get; set; } = string.Empty;
/// <summary>
/// 文件名称
/// </summary>
public string? FileName { get; set; }
/// <summary>
/// 排序值,越小越靠前
/// </summary>
public int Sort { get; set; }
}
/// <summary>
/// 资料输出
/// </summary>
public class MaterialOutput
{
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 资料标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 资料名称
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 资料描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 排序值,越小越靠前
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 生效开始时间
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// 生效结束时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 状态
/// </summary>
public int Status { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string? CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 修改人
/// </summary>
public string? UpdatedBy { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime? UpdatedAt { get; set; }
/// <summary>
/// 资料文件列表
/// </summary>
public List<MaterialFileOutput> Files { get; set; } = new();
}
/// <summary>
/// 资料文件输出
/// </summary>
public class MaterialFileOutput
{
private string _fileUrl = string.Empty;
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 文件类型
/// </summary>
public MaterialFileTypeEnum FileType { get; set; }
/// <summary>
/// 文件完整地址
/// </summary>
public string FileUrl
{
get => DomainHelper.OssFullUrl(_fileUrl);
set => _fileUrl = value ?? string.Empty;
}
/// <summary>
/// 文件名称
/// </summary>
public string? FileName { get; set; }
/// <summary>
/// 排序值,越小越靠前
/// </summary>
public int Sort { get; set; }
}
/// <summary>
/// 资料分页查询输入
/// </summary>
public class MaterialQueryInput : PageQueryModel
{
/// <summary>
/// 标题
/// </summary>
public string? Title { get; set; }
/// <summary>
/// 名称
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 状态
/// </summary>
public int? Status { get; set; }
}

View File

@ -0,0 +1,74 @@
using QYZH.InteractiveMagazine.Models.Enum;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity;
/// <summary>
/// 轮播图表
/// </summary>
[SugarTable("Banner")]
public partial class Banner : SqlSugarBaseEntity
{
/// <summary>
/// Desc:标题
/// Default:
/// Nullable:False
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// Desc:轮播图OSS路径
/// Default:
/// Nullable:False
/// </summary>
public string ImageUrl { get; set; } = string.Empty;
/// <summary>
/// Desc:展示位置
/// Default:1
/// Nullable:False
/// </summary>
public BannerPositionEnum Position { get; set; } = BannerPositionEnum.Home;
/// <summary>
/// Desc:跳转类型
/// Default:0
/// Nullable:False
/// </summary>
public BannerTargetTypeEnum TargetType { get; set; } = BannerTargetTypeEnum.None;
/// <summary>
/// Desc:跳转值
/// Default:
/// Nullable:True
/// </summary>
public string? TargetValue { get; set; }
/// <summary>
/// Desc:排序值,越小越靠前
/// Default:0
/// Nullable:False
/// </summary>
public int Sort { get; set; }
/// <summary>
/// Desc:生效开始时间
/// Default:
/// Nullable:True
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// Desc:生效结束时间
/// Default:
/// Nullable:True
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// Desc:备注
/// Default:
/// Nullable:True
/// </summary>
public string? Remark { get; set; }
}

View File

@ -0,0 +1,52 @@
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity;
/// <summary>
/// 资料表
/// </summary>
[SugarTable("Material")]
public partial class Material : SqlSugarBaseEntity
{
/// <summary>
/// Desc:资料标题
/// Default:
/// Nullable:False
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// Desc:资料名称
/// Default:
/// Nullable:True
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Desc:资料描述
/// Default:
/// Nullable:True
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Desc:排序值,越小越靠前
/// Default:0
/// Nullable:False
/// </summary>
public int Sort { get; set; }
/// <summary>
/// Desc:生效开始时间
/// Default:
/// Nullable:True
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// Desc:生效结束时间
/// Default:
/// Nullable:True
/// </summary>
public DateTime? EndTime { get; set; }
}

View File

@ -0,0 +1,46 @@
using QYZH.InteractiveMagazine.Models.Enum;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity;
/// <summary>
/// 资料文件表
/// </summary>
[SugarTable("MaterialFile")]
public partial class MaterialFile : SqlSugarBaseEntity
{
/// <summary>
/// Desc:资料ID
/// Default:
/// Nullable:False
/// </summary>
public long MaterialId { get; set; }
/// <summary>
/// Desc:文件类型
/// Default:
/// Nullable:False
/// </summary>
public MaterialFileTypeEnum FileType { get; set; }
/// <summary>
/// Desc:文件OSS路径
/// Default:
/// Nullable:False
/// </summary>
public string FileUrl { get; set; } = string.Empty;
/// <summary>
/// Desc:文件名称
/// Default:
/// Nullable:True
/// </summary>
public string? FileName { get; set; }
/// <summary>
/// Desc:排序值,越小越靠前
/// Default:0
/// Nullable:False
/// </summary>
public int Sort { get; set; }
}

View File

@ -0,0 +1,15 @@
using System.ComponentModel;
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 轮播图展示位置枚举
/// </summary>
public enum BannerPositionEnum
{
/// <summary>
/// 首页
/// </summary>
[Description("首页")]
Home = 1
}

View File

@ -0,0 +1,33 @@
using System.ComponentModel;
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 轮播图跳转类型枚举
/// </summary>
public enum BannerTargetTypeEnum
{
/// <summary>
/// 无跳转
/// </summary>
[Description("无跳转")]
None = 0,
/// <summary>
/// 链接
/// </summary>
[Description("链接")]
Url = 1,
/// <summary>
/// 期刊
/// </summary>
[Description("期刊")]
Journal = 2,
/// <summary>
/// 商品
/// </summary>
[Description("商品")]
Product = 3
}

View File

@ -0,0 +1,27 @@
using System.ComponentModel;
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 资料文件类型枚举
/// </summary>
public enum MaterialFileTypeEnum
{
/// <summary>
/// 视频
/// </summary>
[Description("视频")]
Video = 1,
/// <summary>
/// 图片
/// </summary>
[Description("图片")]
Image = 2,
/// <summary>
/// 音频
/// </summary>
[Description("音频")]
Audio = 3
}