- ErrorCodes 新增 NavigationNotFound = 3121 - ContentService 中 3 处 ContentNotFound 替换为 NavigationNotFound
743 lines
22 KiB
C#
743 lines
22 KiB
C#
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;
|
||
|
||
/// <summary>
|
||
/// 内容管ç<C2A1>†æœ<C3A6>务实现
|
||
/// </summary>
|
||
public class ContentService : IContentService
|
||
{
|
||
private readonly AdminBusinessDbContext _dbContext;
|
||
private readonly ILogger<ContentService> _logger;
|
||
|
||
/// <summary>
|
||
/// 跳转类型å<E280B9><C3A5>ç§°æ˜ å°„
|
||
/// </summary>
|
||
private static readonly Dictionary<int, string> LinkTypeNames = new()
|
||
{
|
||
{ 0, "æ—? },
|
||
{ 1, "内部页é<C2B5>¢" },
|
||
{ 2, "外部链接" },
|
||
{ 3, "å°<C3A5>程åº? }
|
||
};
|
||
|
||
/// <summary>
|
||
/// 状æ€<C3A6>å<EFBFBD><C3A5>ç§°æ˜ å°?
|
||
/// </summary>
|
||
private static readonly Dictionary<int, string> StatusNames = new()
|
||
{
|
||
{ 0, "ç¦<C3A7>用" },
|
||
{ 1, "å<>¯ç”¨" }
|
||
};
|
||
|
||
/// <summary>
|
||
/// å®£ä¼ å›¾ä½<C3A4>ç½®å<C2AE><C3A5>ç§°æ˜ å°?
|
||
/// </summary>
|
||
private static readonly Dictionary<int, string> PositionNames = new()
|
||
{
|
||
{ 1, "首页底部" },
|
||
{ 2, "团队� }
|
||
};
|
||
|
||
/// <summary>
|
||
/// æž„é€ å‡½æ•?
|
||
/// </summary>
|
||
/// <param name="dbContext">æ•°æ<C2B0>®åº“上下文</param>
|
||
/// <param name="logger">日志记录�/param>
|
||
public ContentService(
|
||
AdminBusinessDbContext dbContext,
|
||
ILogger<ContentService> logger)
|
||
{
|
||
_dbContext = dbContext;
|
||
_logger = logger;
|
||
}
|
||
|
||
#region Banner è½®æ’图æ“<EFBFBD>ä½?
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PagedResult<BannerDto>> GetBannerListAsync(BannerQueryRequest request)
|
||
{
|
||
// æž„å»ºæŸ¥è¯¢ï¼Œè¿‡æ»¤è½¯åˆ é™¤è®°å½•
|
||
var query = _dbContext.Banners
|
||
.AsNoTracking()
|
||
.Where(b => !b.IsDeleted);
|
||
|
||
// 状æ€<C3A6>ç›é€?
|
||
if (request.Status.HasValue)
|
||
{
|
||
query = query.Where(b => b.Status == request.Status.Value);
|
||
}
|
||
|
||
// 获å<C2B7>–总数
|
||
var total = await query.CountAsync();
|
||
|
||
// 分页查询,按 Sort é™<C3A9>åº<C3A5>排列
|
||
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<BannerDto>.Create(items, total, request.Page, request.PageSize);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<BannerDto> 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, "è½®æ’图ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
return banner;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<long> CreateBannerAsync(CreateBannerRequest request)
|
||
{
|
||
// 验è¯<C3A8>图片URLå¿…å¡«
|
||
if (string.IsNullOrWhiteSpace(request.ImageUrl))
|
||
{
|
||
throw new BusinessException(ErrorCodes.BannerImageRequired, "图片URLä¸<C3A4>能为空");
|
||
}
|
||
|
||
// 验è¯<C3A8> 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("创建轮æ’图æˆ<C3A6>功,ID: {BannerId}, æ ‡é¢˜: {Title}", banner.Id, banner.Title);
|
||
|
||
return banner.Id;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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, "è½®æ’图ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
// 验è¯<C3A8>图片URLå¿…å¡«
|
||
if (string.IsNullOrWhiteSpace(request.ImageUrl))
|
||
{
|
||
throw new BusinessException(ErrorCodes.BannerImageRequired, "图片URLä¸<C3A4>能为空");
|
||
}
|
||
|
||
// 验è¯<C3A8> 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("æ›´æ–°è½®æ’图æˆ<C3A6>功,ID: {BannerId}", banner.Id);
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> DeleteBannerAsync(long id)
|
||
{
|
||
// 查找轮æ’å›?
|
||
var banner = await _dbContext.Banners
|
||
.Where(b => b.Id == id && !b.IsDeleted)
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (banner == null)
|
||
{
|
||
throw new BusinessException(ErrorCodes.BannerNotFound, "è½®æ’图ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
// è½¯åˆ é™?
|
||
banner.IsDeleted = true;
|
||
banner.UpdateTime = DateTime.Now;
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("åˆ é™¤è½®æ’图æˆ<C3A6>功,ID: {BannerId}", id);
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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, "è½®æ’图ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
// 更新状�
|
||
banner.Status = status;
|
||
banner.UpdateTime = DateTime.Now;
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("æ›´æ–°è½®æ’图状æ€<C3A6>æˆ<C3A6>功,ID: {BannerId}, 状æ€? {Status}", id, status);
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> UpdateBannerSortAsync(List<SortItem> items)
|
||
{
|
||
if (items == null || items.Count == 0)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
// 获å<C2B7>–所有需è¦<C3A8>更新的轮æ’图ID
|
||
var ids = items.Select(i => i.Id).ToList();
|
||
|
||
// 批é‡<C3A9>查询轮æ’å›?
|
||
var banners = await _dbContext.Banners
|
||
.Where(b => ids.Contains(b.Id) && !b.IsDeleted)
|
||
.ToListAsync();
|
||
|
||
// 更新排åº<C3A5>
|
||
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("批é‡<C3A9>æ›´æ–°è½®æ’图排åº<C3A5>æˆ<C3A6>功,更新数é‡<C3A9>: {Count}", items.Count);
|
||
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Promotion å®£ä¼ å›¾æ“<EFBFBD>ä½?
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PagedResult<PromotionDto>> GetPromotionListAsync(PromotionQueryRequest request)
|
||
{
|
||
// æž„å»ºæŸ¥è¯¢ï¼Œè¿‡æ»¤è½¯åˆ é™¤è®°å½•
|
||
var query = _dbContext.Promotions
|
||
.AsNoTracking()
|
||
.Where(p => !p.IsDeleted);
|
||
|
||
// ä½<C3A4>ç½®ç›é€?
|
||
if (request.Position.HasValue)
|
||
{
|
||
query = query.Where(p => p.Position == request.Position.Value);
|
||
}
|
||
|
||
// 状æ€<C3A6>ç›é€?
|
||
if (request.Status.HasValue)
|
||
{
|
||
query = query.Where(p => p.Status == request.Status.Value);
|
||
}
|
||
|
||
// 获å<C2B7>–总数
|
||
var total = await query.CountAsync();
|
||
|
||
// 分页查询,按 Sort é™<C3A9>åº<C3A5>排列
|
||
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<PromotionDto>.Create(items, total, request.Page, request.PageSize);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PromotionDto> 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, "å®£ä¼ å›¾ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
return promotion;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<long> CreatePromotionAsync(CreatePromotionRequest request)
|
||
{
|
||
// 验è¯<C3A8>图片URLå¿…å¡«
|
||
if (string.IsNullOrWhiteSpace(request.ImageUrl))
|
||
{
|
||
throw new BusinessException(ErrorCodes.PromotionImageRequired, "图片URLä¸<C3A4>能为空");
|
||
}
|
||
|
||
// 验è¯<C3A8> 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("åˆ›å»ºå®£ä¼ å›¾æˆ<C3A6>功,ID: {PromotionId}, æ ‡é¢˜: {Title}, ä½<C3A4>ç½®: {Position}",
|
||
promotion.Id, promotion.Title, promotion.Position);
|
||
|
||
return promotion.Id;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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, "å®£ä¼ å›¾ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
// 验è¯<C3A8>图片URLå¿…å¡«
|
||
if (string.IsNullOrWhiteSpace(request.ImageUrl))
|
||
{
|
||
throw new BusinessException(ErrorCodes.PromotionImageRequired, "图片URLä¸<C3A4>能为空");
|
||
}
|
||
|
||
// 验è¯<C3A8> 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("æ›´æ–°å®£ä¼ å›¾æˆ<C3A6>功,ID: {PromotionId}", promotion.Id);
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> DeletePromotionAsync(long id)
|
||
{
|
||
// æŸ¥æ‰¾å®£ä¼ å›?
|
||
var promotion = await _dbContext.Promotions
|
||
.Where(p => p.Id == id && !p.IsDeleted)
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (promotion == null)
|
||
{
|
||
throw new BusinessException(ErrorCodes.PromotionNotFound, "å®£ä¼ å›¾ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
// è½¯åˆ é™?
|
||
promotion.IsDeleted = true;
|
||
promotion.UpdateTime = DateTime.Now;
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("åˆ é™¤å®£ä¼ å›¾æˆ<C3A6>功,ID: {PromotionId}", id);
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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, "å®£ä¼ å›¾ä¸<C3A4>å˜åœ¨");
|
||
}
|
||
|
||
// 更新状�
|
||
promotion.Status = status;
|
||
promotion.UpdateTime = DateTime.Now;
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("æ›´æ–°å®£ä¼ å›¾çŠ¶æ€<C3A6>æˆ<C3A6>功,ID: {PromotionId}, 状æ€? {Status}", id, status);
|
||
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region ç§<EFBFBD>有方法
|
||
|
||
/// <summary>
|
||
/// 验è¯<C3A8> LinkType å’Œå¯¹åº”å—æ®?
|
||
/// </summary>
|
||
/// <param name="linkType">跳转类型</param>
|
||
/// <param name="linkUrl">跳转地å<C2B0>€</param>
|
||
/// <param name="appId">å°<C3A5>程åº<C3A5>AppId</param>
|
||
private void ValidateLinkType(int linkType, string? linkUrl, string? appId)
|
||
{
|
||
switch (linkType)
|
||
{
|
||
case 0:
|
||
// æ— è·³è½¬ï¼Œä¸<C3A4>需è¦<C3A8>验è¯?
|
||
break;
|
||
case 1:
|
||
case 2:
|
||
// 内部页é<C2B5>¢æˆ–外部链接,LinkUrl å¿…å¡«
|
||
if (string.IsNullOrWhiteSpace(linkUrl))
|
||
{
|
||
throw new BusinessException(ErrorCodes.BannerLinkUrlRequired, "跳转地å<C2B0>€ä¸<C3A4>能为空");
|
||
}
|
||
break;
|
||
case 3:
|
||
// å°<C3A5>程åº<C3A5>,LinkUrl å’?AppId 都必å¡?
|
||
if (string.IsNullOrWhiteSpace(linkUrl))
|
||
{
|
||
throw new BusinessException(ErrorCodes.BannerLinkUrlRequired, "跳转地å<C2B0>€ä¸<C3A4>能为空");
|
||
}
|
||
if (string.IsNullOrWhiteSpace(appId))
|
||
{
|
||
throw new BusinessException(ErrorCodes.BannerLinkUrlRequired, "å°<C3A5>程åº<C3A5>AppIdä¸<C3A4>能为空");
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获å<C2B7>–跳转类型å<E280B9><C3A5>ç§°
|
||
/// </summary>
|
||
/// <param name="linkType">跳转类型</param>
|
||
/// <returns>类型å<E280B9><C3A5>ç§°</returns>
|
||
private static string GetLinkTypeName(int linkType)
|
||
{
|
||
return LinkTypeNames.TryGetValue(linkType, out var name) ? name : "未知";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获å<C2B7>–状æ€<C3A6>å<EFBFBD><C3A5>ç§?
|
||
/// </summary>
|
||
/// <param name="status">状æ€<C3A6>å€?/param>
|
||
/// <returns>状æ€<C3A6>å<EFBFBD><C3A5>ç§?/returns>
|
||
private static string GetStatusName(int status)
|
||
{
|
||
return StatusNames.TryGetValue(status, out var name) ? name : "未知";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获å<C2B7>–ä½<C3A4>ç½®å<C2AE><C3A5>ç§°
|
||
/// </summary>
|
||
/// <param name="position">ä½<C3A4>ç½®å€?/param>
|
||
/// <returns>ä½<C3A4>ç½®å<C2AE><C3A5>ç§°</returns>
|
||
private static string GetPositionName(int position)
|
||
{
|
||
return PositionNames.TryGetValue(position, out var name) ? name : "未知";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导航状æ€<C3A6>å<EFBFBD><C3A5>ç§°æ˜ å°?
|
||
/// </summary>
|
||
private static readonly Dictionary<int, string> NavigationStatusNames = new()
|
||
{
|
||
{ 0, "å<>³å°†ä¸Šçº¿" },
|
||
{ 1, "已上� }
|
||
};
|
||
|
||
/// <summary>
|
||
/// 验è¯<C3A8> Position å€?
|
||
/// </summary>
|
||
/// <param name="position">ä½<C3A4>ç½®å€?/param>
|
||
private void ValidatePosition(int position)
|
||
{
|
||
if (position != 1 && position != 2)
|
||
{
|
||
throw new BusinessException(ErrorCodes.ParamError, "ä½<C3A4>置值必须为1(首页底部)æˆ?(团队页ï¼?);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region HomeNavigation 首页导航æ“<EFBFBD>作
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PagedResult<HomeNavigationDto>> 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<HomeNavigationDto>.Create(items, total, request.Page, request.PageSize);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<HomeNavigationDto> 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, "首页导航ä¸<C3A4>å˜åœ?);
|
||
}
|
||
|
||
return nav;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<long> CreateNavigationAsync(CreateHomeNavigationRequest request)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(request.Name))
|
||
{
|
||
throw new BusinessException(ErrorCodes.ParamError, "导航å<C2AA><C3A5>ç§°ä¸<C3A4>能为空");
|
||
}
|
||
|
||
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("创建首页导航æˆ<C3A6>功,ID: {Id}, å<><C3A5>ç§°: {Name}", entity.Id, entity.Name);
|
||
return entity.Id;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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, "首页导航ä¸<C3A4>å˜åœ?);
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(request.Name))
|
||
{
|
||
throw new BusinessException(ErrorCodes.ParamError, "导航å<C2AA><C3A5>ç§°ä¸<C3A4>能为空");
|
||
}
|
||
|
||
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("更新首页导航æˆ<C3A6>功,ID: {Id}", entity.Id);
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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("åˆ é™¤é¦–é¡µå¯¼èˆªæˆ<C3A6>功,ID: {Id}", id);
|
||
return true;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> 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, "首页导航ä¸<C3A4>å˜åœ?);
|
||
}
|
||
|
||
entity.Status = status;
|
||
entity.UpdateTime = DateTime.Now;
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("更新首页导航状æ€<C3A6>æˆ<C3A6>功,ID: {Id}, 状æ€? {Status}", id, status);
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
}
|