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, "团队? }
};
///
/// 构造函?
///
/// 数据库上下文
/// 日志记录?/param>
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 : "未知";
}
///
/// 获取状态名?
///
/// 状态?/param>
/// 状态名?/returns>
private static string GetStatusName(int status)
{
return StatusNames.TryGetValue(status, out var name) ? name : "未知";
}
///
/// 获取位置名称
///
/// 位置?/param>
/// 位置名称
private static string GetPositionName(int position)
{
return PositionNames.TryGetValue(position, out var name) ? name : "未知";
}
///
/// 导航状态名称映?
///
private static readonly Dictionary NavigationStatusNames = new()
{
{ 0, "即将上线" },
{ 1, "已上? }
};
///
/// 验证 Position ?
///
/// 位置?/param>
private void ValidatePosition(int position)
{
if (position != 1 && position != 2)
{
throw new BusinessException(ErrorCodes.ParamError, "位置值必须为1(首页底部)?(团队页?);
}
}
#endregion
#region HomeNavigation 首页导航操作
///
public async Task> GetNavigationListAsync(HomeNavigationQueryRequest request)
{
var query = _dbContext.HomeNavigations
.AsNoTracking()
.Where(n => !n.IsDeleted);
if (!string.IsNullOrWhiteSpace(request.Name))
{
query = query.Where(n => n.Name.Contains(request.Name));
}
if (request.Status.HasValue)
{
query = query.Where(n => n.Status == request.Status.Value);
}
var total = await query.CountAsync();
var items = await query
.OrderByDescending(n => n.Sort)
.ThenByDescending(n => n.CreateTime)
.Skip(request.Skip)
.Take(request.PageSize)
.Select(n => new HomeNavigationDto
{
Id = n.Id,
Name = n.Name,
ImageUrl = n.ImageUrl,
LinkUrl = n.LinkUrl,
Sort = n.Sort,
Status = n.Status,
StatusName = NavigationStatusNames.ContainsKey(n.Status) ? NavigationStatusNames[n.Status] : "未知",
CreateTime = n.CreateTime
})
.ToListAsync();
return PagedResult.Create(items, total, request.Page, request.PageSize);
}
///
public async Task GetNavigationByIdAsync(long id)
{
var nav = await _dbContext.HomeNavigations
.AsNoTracking()
.Where(n => n.Id == id && !n.IsDeleted)
.Select(n => new HomeNavigationDto
{
Id = n.Id,
Name = n.Name,
ImageUrl = n.ImageUrl,
LinkUrl = n.LinkUrl,
Sort = n.Sort,
Status = n.Status,
StatusName = NavigationStatusNames.ContainsKey(n.Status) ? NavigationStatusNames[n.Status] : "未知",
CreateTime = n.CreateTime
})
.FirstOrDefaultAsync();
if (nav == null)
{
throw new BusinessException(ErrorCodes.NavigationNotFound, "首页导航不存?);
}
return nav;
}
///
public async Task CreateNavigationAsync(CreateHomeNavigationRequest request)
{
if (string.IsNullOrWhiteSpace(request.Name))
{
throw new BusinessException(ErrorCodes.ParamError, "导航名称不能为空");
}
var entity = new HomeNavigation
{
Name = request.Name,
ImageUrl = request.ImageUrl,
LinkUrl = request.LinkUrl,
Sort = request.Sort,
Status = request.Status,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now,
IsDeleted = false
};
_dbContext.HomeNavigations.Add(entity);
await _dbContext.SaveChangesAsync();
_logger.LogInformation("创建首页导航成功,ID: {Id}, 名称: {Name}", entity.Id, entity.Name);
return entity.Id;
}
///
public async Task UpdateNavigationAsync(UpdateHomeNavigationRequest request)
{
var entity = await _dbContext.HomeNavigations
.Where(n => n.Id == request.Id && !n.IsDeleted)
.FirstOrDefaultAsync();
if (entity == null)
{
throw new BusinessException(ErrorCodes.NavigationNotFound, "首页导航不存?);
}
if (string.IsNullOrWhiteSpace(request.Name))
{
throw new BusinessException(ErrorCodes.ParamError, "导航名称不能为空");
}
entity.Name = request.Name;
entity.ImageUrl = request.ImageUrl;
entity.LinkUrl = request.LinkUrl;
entity.Sort = request.Sort;
entity.Status = request.Status;
entity.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新首页导航成功,ID: {Id}", entity.Id);
return true;
}
///
public async Task DeleteNavigationAsync(long id)
{
var entity = await _dbContext.HomeNavigations.FindAsync(id);
if (entity == null || entity.IsDeleted) return false;
entity.IsDeleted = true;
entity.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("删除首页导航成功,ID: {Id}", id);
return true;
}
///
public async Task UpdateNavigationStatusAsync(long id, int status)
{
var entity = await _dbContext.HomeNavigations
.Where(n => n.Id == id && !n.IsDeleted)
.FirstOrDefaultAsync();
if (entity == null)
{
throw new BusinessException(ErrorCodes.NavigationNotFound, "首页导航不存?);
}
entity.Status = status;
entity.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新首页导航状态成功,ID: {Id}, 状? {Status}", id, status);
return true;
}
#endregion
}