using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using MiAssessment.Admin.Business.Data;
using MiAssessment.Admin.Business.Entities;
using MiAssessment.Admin.Business.Models;
using MiAssessment.Admin.Business.Models.Common;
using MiAssessment.Admin.Business.Models.Content;
using MiAssessment.Admin.Business.Services.Interfaces;
namespace MiAssessment.Admin.Business.Services;
///
/// 内容管理服务实现
///
public class ContentService : IContentService
{
private readonly AdminBusinessDbContext _dbContext;
private readonly ILogger _logger;
///
/// 跳转类型名称映射
///
private static readonly Dictionary LinkTypeNames = new()
{
{ 0, "无" },
{ 1, "内部页面" },
{ 2, "外部链接" },
{ 3, "小程序" }
};
///
/// 状态名称映射
///
private static readonly Dictionary StatusNames = new()
{
{ 0, "禁用" },
{ 1, "启用" }
};
///
/// 宣传图位置名称映射
///
private static readonly Dictionary PositionNames = new()
{
{ 1, "首页底部" },
{ 2, "团队页" }
};
///
/// 构造函数
///
/// 数据库上下文
/// 日志记录器
public ContentService(
AdminBusinessDbContext dbContext,
ILogger logger)
{
_dbContext = dbContext;
_logger = logger;
}
#region Banner 轮播图操作
///
public async Task> GetBannerListAsync(BannerQueryRequest request)
{
// 构建查询,过滤软删除记录
var query = _dbContext.Banners
.AsNoTracking()
.Where(b => !b.IsDeleted);
// 状态筛选
if (request.Status.HasValue)
{
query = query.Where(b => b.Status == request.Status.Value);
}
// 获取总数
var total = await query.CountAsync();
// 分页查询,按 Sort 降序排列
var items = await query
.OrderByDescending(b => b.Sort)
.ThenByDescending(b => b.CreateTime)
.Skip(request.Skip)
.Take(request.PageSize)
.Select(b => new BannerDto
{
Id = b.Id,
Title = b.Title,
ImageUrl = b.ImageUrl,
LinkType = b.LinkType,
LinkTypeName = GetLinkTypeName(b.LinkType),
LinkUrl = b.LinkUrl,
AppId = b.AppId,
Sort = b.Sort,
Status = b.Status,
StatusName = GetStatusName(b.Status),
CreateTime = b.CreateTime
})
.ToListAsync();
return PagedResult.Create(items, total, request.Page, request.PageSize);
}
///
public async Task GetBannerByIdAsync(long id)
{
var banner = await _dbContext.Banners
.AsNoTracking()
.Where(b => b.Id == id && !b.IsDeleted)
.Select(b => new BannerDto
{
Id = b.Id,
Title = b.Title,
ImageUrl = b.ImageUrl,
LinkType = b.LinkType,
LinkTypeName = GetLinkTypeName(b.LinkType),
LinkUrl = b.LinkUrl,
AppId = b.AppId,
Sort = b.Sort,
Status = b.Status,
StatusName = GetStatusName(b.Status),
CreateTime = b.CreateTime
})
.FirstOrDefaultAsync();
if (banner == null)
{
throw new BusinessException(ErrorCodes.BannerNotFound, "轮播图不存在");
}
return banner;
}
///
public async Task CreateBannerAsync(CreateBannerRequest request)
{
// 验证图片URL必填
if (string.IsNullOrWhiteSpace(request.ImageUrl))
{
throw new BusinessException(ErrorCodes.BannerImageRequired, "图片URL不能为空");
}
// 验证 LinkType 和对应字段
ValidateLinkType(request.LinkType, request.LinkUrl, request.AppId);
// 创建实体
var banner = new Banner
{
Title = request.Title,
ImageUrl = request.ImageUrl,
LinkType = request.LinkType,
LinkUrl = request.LinkUrl,
AppId = request.AppId,
Sort = request.Sort,
Status = request.Status,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now,
IsDeleted = false
};
_dbContext.Banners.Add(banner);
await _dbContext.SaveChangesAsync();
_logger.LogInformation("创建轮播图成功,ID: {BannerId}, 标题: {Title}", banner.Id, banner.Title);
return banner.Id;
}
///
public async Task UpdateBannerAsync(UpdateBannerRequest request)
{
// 查找轮播图
var banner = await _dbContext.Banners
.Where(b => b.Id == request.Id && !b.IsDeleted)
.FirstOrDefaultAsync();
if (banner == null)
{
throw new BusinessException(ErrorCodes.BannerNotFound, "轮播图不存在");
}
// 验证图片URL必填
if (string.IsNullOrWhiteSpace(request.ImageUrl))
{
throw new BusinessException(ErrorCodes.BannerImageRequired, "图片URL不能为空");
}
// 验证 LinkType 和对应字段
ValidateLinkType(request.LinkType, request.LinkUrl, request.AppId);
// 更新字段
banner.Title = request.Title;
banner.ImageUrl = request.ImageUrl;
banner.LinkType = request.LinkType;
banner.LinkUrl = request.LinkUrl;
banner.AppId = request.AppId;
banner.Sort = request.Sort;
banner.Status = request.Status;
banner.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新轮播图成功,ID: {BannerId}", banner.Id);
return true;
}
///
public async Task DeleteBannerAsync(long id)
{
// 查找轮播图
var banner = await _dbContext.Banners
.Where(b => b.Id == id && !b.IsDeleted)
.FirstOrDefaultAsync();
if (banner == null)
{
throw new BusinessException(ErrorCodes.BannerNotFound, "轮播图不存在");
}
// 软删除
banner.IsDeleted = true;
banner.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("删除轮播图成功,ID: {BannerId}", id);
return true;
}
///
public async Task UpdateBannerStatusAsync(long id, int status)
{
// 查找轮播图
var banner = await _dbContext.Banners
.Where(b => b.Id == id && !b.IsDeleted)
.FirstOrDefaultAsync();
if (banner == null)
{
throw new BusinessException(ErrorCodes.BannerNotFound, "轮播图不存在");
}
// 更新状态
banner.Status = status;
banner.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新轮播图状态成功,ID: {BannerId}, 状态: {Status}", id, status);
return true;
}
///
public async Task UpdateBannerSortAsync(List items)
{
if (items == null || items.Count == 0)
{
return true;
}
// 获取所有需要更新的轮播图ID
var ids = items.Select(i => i.Id).ToList();
// 批量查询轮播图
var banners = await _dbContext.Banners
.Where(b => ids.Contains(b.Id) && !b.IsDeleted)
.ToListAsync();
// 更新排序
foreach (var item in items)
{
var banner = banners.FirstOrDefault(b => b.Id == item.Id);
if (banner != null)
{
banner.Sort = item.Sort;
banner.UpdateTime = DateTime.Now;
}
}
await _dbContext.SaveChangesAsync();
_logger.LogInformation("批量更新轮播图排序成功,更新数量: {Count}", items.Count);
return true;
}
#endregion
#region Promotion 宣传图操作
///
public async Task> GetPromotionListAsync(PromotionQueryRequest request)
{
// 构建查询,过滤软删除记录
var query = _dbContext.Promotions
.AsNoTracking()
.Where(p => !p.IsDeleted);
// 位置筛选
if (request.Position.HasValue)
{
query = query.Where(p => p.Position == request.Position.Value);
}
// 状态筛选
if (request.Status.HasValue)
{
query = query.Where(p => p.Status == request.Status.Value);
}
// 获取总数
var total = await query.CountAsync();
// 分页查询,按 Sort 降序排列
var items = await query
.OrderByDescending(p => p.Sort)
.ThenByDescending(p => p.CreateTime)
.Skip(request.Skip)
.Take(request.PageSize)
.Select(p => new PromotionDto
{
Id = p.Id,
Title = p.Title,
ImageUrl = p.ImageUrl,
Position = p.Position,
PositionName = GetPositionName(p.Position),
Sort = p.Sort,
Status = p.Status,
StatusName = GetStatusName(p.Status),
CreateTime = p.CreateTime
})
.ToListAsync();
return PagedResult.Create(items, total, request.Page, request.PageSize);
}
///
public async Task GetPromotionByIdAsync(long id)
{
var promotion = await _dbContext.Promotions
.AsNoTracking()
.Where(p => p.Id == id && !p.IsDeleted)
.Select(p => new PromotionDto
{
Id = p.Id,
Title = p.Title,
ImageUrl = p.ImageUrl,
Position = p.Position,
PositionName = GetPositionName(p.Position),
Sort = p.Sort,
Status = p.Status,
StatusName = GetStatusName(p.Status),
CreateTime = p.CreateTime
})
.FirstOrDefaultAsync();
if (promotion == null)
{
throw new BusinessException(ErrorCodes.PromotionNotFound, "宣传图不存在");
}
return promotion;
}
///
public async Task CreatePromotionAsync(CreatePromotionRequest request)
{
// 验证图片URL必填
if (string.IsNullOrWhiteSpace(request.ImageUrl))
{
throw new BusinessException(ErrorCodes.PromotionImageRequired, "图片URL不能为空");
}
// 验证 Position 值
ValidatePosition(request.Position);
// 创建实体
var promotion = new Promotion
{
Title = request.Title,
ImageUrl = request.ImageUrl,
Position = request.Position,
Sort = request.Sort,
Status = request.Status,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now,
IsDeleted = false
};
_dbContext.Promotions.Add(promotion);
await _dbContext.SaveChangesAsync();
_logger.LogInformation("创建宣传图成功,ID: {PromotionId}, 标题: {Title}, 位置: {Position}",
promotion.Id, promotion.Title, promotion.Position);
return promotion.Id;
}
///
public async Task UpdatePromotionAsync(UpdatePromotionRequest request)
{
// 查找宣传图
var promotion = await _dbContext.Promotions
.Where(p => p.Id == request.Id && !p.IsDeleted)
.FirstOrDefaultAsync();
if (promotion == null)
{
throw new BusinessException(ErrorCodes.PromotionNotFound, "宣传图不存在");
}
// 验证图片URL必填
if (string.IsNullOrWhiteSpace(request.ImageUrl))
{
throw new BusinessException(ErrorCodes.PromotionImageRequired, "图片URL不能为空");
}
// 验证 Position 值
ValidatePosition(request.Position);
// 更新字段
promotion.Title = request.Title;
promotion.ImageUrl = request.ImageUrl;
promotion.Position = request.Position;
promotion.Sort = request.Sort;
promotion.Status = request.Status;
promotion.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新宣传图成功,ID: {PromotionId}", promotion.Id);
return true;
}
///
public async Task DeletePromotionAsync(long id)
{
// 查找宣传图
var promotion = await _dbContext.Promotions
.Where(p => p.Id == id && !p.IsDeleted)
.FirstOrDefaultAsync();
if (promotion == null)
{
throw new BusinessException(ErrorCodes.PromotionNotFound, "宣传图不存在");
}
// 软删除
promotion.IsDeleted = true;
promotion.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("删除宣传图成功,ID: {PromotionId}", id);
return true;
}
///
public async Task UpdatePromotionStatusAsync(long id, int status)
{
// 查找宣传图
var promotion = await _dbContext.Promotions
.Where(p => p.Id == id && !p.IsDeleted)
.FirstOrDefaultAsync();
if (promotion == null)
{
throw new BusinessException(ErrorCodes.PromotionNotFound, "宣传图不存在");
}
// 更新状态
promotion.Status = status;
promotion.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新宣传图状态成功,ID: {PromotionId}, 状态: {Status}", id, status);
return true;
}
#endregion
#region 私有方法
///
/// 验证 LinkType 和对应字段
///
/// 跳转类型
/// 跳转地址
/// 小程序AppId
private void ValidateLinkType(int linkType, string? linkUrl, string? appId)
{
switch (linkType)
{
case 0:
// 无跳转,不需要验证
break;
case 1:
case 2:
// 内部页面或外部链接,LinkUrl 必填
if (string.IsNullOrWhiteSpace(linkUrl))
{
throw new BusinessException(ErrorCodes.BannerLinkUrlRequired, "跳转地址不能为空");
}
break;
case 3:
// 小程序,LinkUrl 和 AppId 都必填
if (string.IsNullOrWhiteSpace(linkUrl))
{
throw new BusinessException(ErrorCodes.BannerLinkUrlRequired, "跳转地址不能为空");
}
if (string.IsNullOrWhiteSpace(appId))
{
throw new BusinessException(ErrorCodes.BannerLinkUrlRequired, "小程序AppId不能为空");
}
break;
}
}
///
/// 获取跳转类型名称
///
/// 跳转类型
/// 类型名称
private static string GetLinkTypeName(int linkType)
{
return LinkTypeNames.TryGetValue(linkType, out var name) ? name : "未知";
}
///
/// 获取状态名称
///
/// 状态值
/// 状态名称
private static string GetStatusName(int status)
{
return StatusNames.TryGetValue(status, out var name) ? name : "未知";
}
///
/// 获取位置名称
///
/// 位置值
/// 位置名称
private static string GetPositionName(int position)
{
return PositionNames.TryGetValue(position, out var name) ? name : "未知";
}
///
/// 验证 Position 值
///
/// 位置值
private void ValidatePosition(int position)
{
if (position != 1 && position != 2)
{
throw new BusinessException(ErrorCodes.ParamError, "位置值必须为1(首页底部)或2(团队页)");
}
}
#endregion
}