201 lines
5.8 KiB
C#
201 lines
5.8 KiB
C#
using HoneyBox.Admin.Business.Models;
|
||
using HoneyBox.Admin.Business.Models.Danye;
|
||
using HoneyBox.Admin.Business.Services.Interfaces;
|
||
using HoneyBox.Model.Data;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace HoneyBox.Admin.Business.Services;
|
||
|
||
/// <summary>
|
||
/// 单页管理服务实现
|
||
/// </summary>
|
||
public class DanyeService : IDanyeService
|
||
{
|
||
private readonly HoneyBoxDbContext _dbContext;
|
||
private readonly ILogger<DanyeService> _logger;
|
||
|
||
/// <summary>
|
||
/// 标题不可编辑的ID范围(2-20)
|
||
/// </summary>
|
||
private const int TitleEditableMinId = 2;
|
||
private const int TitleEditableMaxId = 20;
|
||
|
||
public DanyeService(
|
||
HoneyBoxDbContext dbContext,
|
||
ILogger<DanyeService> logger)
|
||
{
|
||
_dbContext = dbContext;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<DanyeResponse>> GetDanyeListAsync()
|
||
{
|
||
var danyes = await _dbContext.Danyes
|
||
.AsNoTracking()
|
||
.OrderBy(d => d.Id)
|
||
.ToListAsync();
|
||
|
||
return danyes.Select(d => new DanyeResponse
|
||
{
|
||
Id = d.Id,
|
||
Title = d.Title,
|
||
IsImageOptimizer = d.IsImageOptimizer == 1,
|
||
UpdateTime = UnixTimeToDateTime(d.UpdateTime)
|
||
}).ToList();
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<DanyeDetailResponse?> GetDanyeByIdAsync(int id)
|
||
{
|
||
var danye = await _dbContext.Danyes
|
||
.AsNoTracking()
|
||
.FirstOrDefaultAsync(d => d.Id == id);
|
||
|
||
if (danye == null)
|
||
return null;
|
||
|
||
return new DanyeDetailResponse
|
||
{
|
||
Id = danye.Id,
|
||
Title = danye.Title,
|
||
Content = danye.Content,
|
||
IsImageOptimizer = danye.IsImageOptimizer == 1,
|
||
IsTitleEditable = !IsTitleProtected(danye.Id)
|
||
};
|
||
}
|
||
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> UpdateDanyeAsync(int id, DanyeUpdateRequest request)
|
||
{
|
||
var danye = await _dbContext.Danyes.FirstOrDefaultAsync(d => d.Id == id);
|
||
if (danye == null)
|
||
{
|
||
throw new BusinessException(BusinessErrorCodes.NotFound, "单页不存在");
|
||
}
|
||
|
||
// 验证内容不能为空
|
||
if (string.IsNullOrWhiteSpace(request.Content))
|
||
{
|
||
throw new BusinessException(BusinessErrorCodes.ValidationFailed, "内容不能为空");
|
||
}
|
||
|
||
// 更新标题(仅当ID不在2-20范围内且提供了标题时)
|
||
if (!string.IsNullOrWhiteSpace(request.Title))
|
||
{
|
||
if (IsTitleProtected(id))
|
||
{
|
||
_logger.LogWarning("尝试修改受保护的单页标题: Id={Id}", id);
|
||
// 不抛出异常,只是忽略标题更新
|
||
}
|
||
else
|
||
{
|
||
danye.Title = request.Title;
|
||
}
|
||
}
|
||
|
||
// 更新内容
|
||
danye.Content = request.Content;
|
||
danye.UpdateTime = GetUnixTimestamp();
|
||
|
||
var result = await _dbContext.SaveChangesAsync() > 0;
|
||
|
||
_logger.LogInformation("更新单页成功: Id={Id}", id);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> ToggleImageOptimizerAsync(int id, ImageOptimizerRequest request)
|
||
{
|
||
var danye = await _dbContext.Danyes.FirstOrDefaultAsync(d => d.Id == id);
|
||
if (danye == null)
|
||
{
|
||
throw new BusinessException(BusinessErrorCodes.NotFound, "单页不存在");
|
||
}
|
||
|
||
danye.IsImageOptimizer = (byte)(request.IsImageOptimizer ? 1 : 0);
|
||
danye.UpdateTime = GetUnixTimestamp();
|
||
|
||
var result = await _dbContext.SaveChangesAsync() > 0;
|
||
|
||
_logger.LogInformation("切换单页图片优化状态: Id={Id}, IsImageOptimizer={IsImageOptimizer}",
|
||
id, request.IsImageOptimizer);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> ClearContentAsync(int id)
|
||
{
|
||
var danye = await _dbContext.Danyes.FirstOrDefaultAsync(d => d.Id == id);
|
||
if (danye == null)
|
||
{
|
||
throw new BusinessException(BusinessErrorCodes.NotFound, "单页不存在");
|
||
}
|
||
|
||
// 清空内容,设置为空字符串
|
||
danye.Content = string.Empty;
|
||
danye.UpdateTime = GetUnixTimestamp();
|
||
|
||
var result = await _dbContext.SaveChangesAsync() > 0;
|
||
|
||
_logger.LogInformation("清空单页内容: Id={Id}, Title={Title}", id, danye.Title);
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<bool> DeleteDanyeAsync(int id)
|
||
{
|
||
var danye = await _dbContext.Danyes.FirstOrDefaultAsync(d => d.Id == id);
|
||
if (danye == null)
|
||
{
|
||
throw new BusinessException(BusinessErrorCodes.NotFound, "单页不存在");
|
||
}
|
||
|
||
// 系统预设单页(ID 2-20)不允许删除
|
||
if (IsTitleProtected(id))
|
||
{
|
||
throw new BusinessException(BusinessErrorCodes.ValidationFailed, "系统预设单页不允许删除");
|
||
}
|
||
|
||
_dbContext.Danyes.Remove(danye);
|
||
var result = await _dbContext.SaveChangesAsync() > 0;
|
||
|
||
_logger.LogInformation("删除单页: Id={Id}, Title={Title}", id, danye.Title);
|
||
|
||
return result;
|
||
}
|
||
|
||
#region Private Helper Methods
|
||
|
||
/// <summary>
|
||
/// 判断标题是否受保护(ID 2-20 的单页标题不可编辑)
|
||
/// </summary>
|
||
private static bool IsTitleProtected(int id)
|
||
{
|
||
return id >= TitleEditableMinId && id <= TitleEditableMaxId;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Unix时间戳转DateTime
|
||
/// </summary>
|
||
private static DateTime UnixTimeToDateTime(int unixTime)
|
||
{
|
||
return DateTimeOffset.FromUnixTimeSeconds(unixTime).LocalDateTime;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前Unix时间戳
|
||
/// </summary>
|
||
private static int GetUnixTimestamp()
|
||
{
|
||
return (int)DateTimeOffset.Now.ToUnixTimeSeconds();
|
||
}
|
||
|
||
#endregion
|
||
}
|