Files
EmailBill/WebApi/Controllers/TransactionPeriodicController.cs
SunCheng 3ed9cf5ebd
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 22s
Docker Build & Deploy / Deploy to Production (push) Successful in 7s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
重构: 将 LogCleanupService 转为 Quartz Job 服务
- 创建 LogCleanupJob 替代 LogCleanupService (BackgroundService)
- 在 Expand.cs 中注册 LogCleanupJob (每天凌晨2点执行, 保留30天日志)
- 从 Program.cs 移除 LogCleanupService 的 HostedService 注册
- 删除 Service/LogCleanupService.cs
- 删除 Service/PeriodicBillBackgroundService.cs (已无用的重复服务)

所有后台任务现在统一通过 Quartz.NET 管理, 支持运行时控制
2026-01-28 11:19:23 +08:00

229 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Service.Transaction;
namespace WebApi.Controllers;
/// <summary>
/// 周期性账单控制器
/// </summary>
[ApiController]
[Route("api/[controller]/[action]")]
public class TransactionPeriodicController(
ITransactionPeriodicRepository periodicRepository,
ITransactionPeriodicService periodicService,
ILogger<TransactionPeriodicController> logger
) : ControllerBase
{
/// <summary>
/// 获取周期性账单列表(分页)
/// </summary>
[HttpGet]
public async Task<PagedResponse<TransactionPeriodic>> GetListAsync(
[FromQuery] int pageIndex = 1,
[FromQuery] int pageSize = 20,
[FromQuery] string? searchKeyword = null
)
{
try
{
var list = await periodicRepository.GetPagedListAsync(pageIndex, pageSize, searchKeyword);
var total = await periodicRepository.GetTotalCountAsync(searchKeyword);
return new PagedResponse<TransactionPeriodic>
{
Success = true,
Data = list.ToArray(),
Total = (int)total
};
}
catch (Exception ex)
{
logger.LogError(ex, "获取周期性账单列表失败");
return PagedResponse<TransactionPeriodic>.Fail($"获取列表失败: {ex.Message}");
}
}
/// <summary>
/// 根据ID获取周期性账单详情
/// </summary>
[HttpGet("{id}")]
public async Task<BaseResponse<TransactionPeriodic>> GetByIdAsync(long id)
{
try
{
var periodic = await periodicRepository.GetByIdAsync(id);
if (periodic == null)
{
return "周期性账单不存在".Fail<TransactionPeriodic>();
}
return periodic.Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "获取周期性账单详情失败ID: {Id}", id);
return $"获取详情失败: {ex.Message}".Fail<TransactionPeriodic>();
}
}
/// <summary>
/// 创建周期性账单
/// </summary>
[HttpPost]
public async Task<BaseResponse<TransactionPeriodic>> CreateAsync([FromBody] CreatePeriodicRequest request)
{
try
{
var periodic = new TransactionPeriodic
{
PeriodicType = request.PeriodicType,
PeriodicConfig = request.PeriodicConfig ?? string.Empty,
Amount = request.Amount,
Type = request.Type,
Classify = request.Classify ?? string.Empty,
Reason = request.Reason ?? string.Empty,
IsEnabled = true
};
// 计算下次执行时间
periodic.NextExecuteTime = periodicService.CalculateNextExecuteTime(periodic, DateTime.Now);
var success = await periodicRepository.AddAsync(periodic);
if (!success)
{
return "创建周期性账单失败".Fail<TransactionPeriodic>();
}
return periodic.Ok("创建成功");
}
catch (Exception ex)
{
logger.LogError(ex, "创建周期性账单失败");
return $"创建失败: {ex.Message}".Fail<TransactionPeriodic>();
}
}
/// <summary>
/// 更新周期性账单
/// </summary>
[HttpPost]
public async Task<BaseResponse> UpdateAsync([FromBody] UpdatePeriodicRequest request)
{
try
{
var periodic = await periodicRepository.GetByIdAsync(request.Id);
if (periodic == null)
{
return "周期性账单不存在".Fail();
}
periodic.PeriodicType = request.PeriodicType;
periodic.PeriodicConfig = request.PeriodicConfig ?? string.Empty;
periodic.Amount = request.Amount;
periodic.Type = request.Type;
periodic.Classify = request.Classify ?? string.Empty;
periodic.Reason = request.Reason ?? string.Empty;
periodic.IsEnabled = request.IsEnabled;
periodic.UpdateTime = DateTime.Now;
// 重新计算下次执行时间
periodic.NextExecuteTime = periodicService.CalculateNextExecuteTime(periodic, DateTime.Now);
var success = await periodicRepository.UpdateAsync(periodic);
if (!success)
{
return "更新周期性账单失败".Fail();
}
return "更新成功".Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "更新周期性账单失败ID: {Id}", request.Id);
return $"更新失败: {ex.Message}".Fail();
}
}
/// <summary>
/// 删除周期性账单
/// </summary>
[HttpPost]
public async Task<BaseResponse> DeleteByIdAsync([FromQuery] long id)
{
try
{
var success = await periodicRepository.DeleteAsync(id);
if (!success)
{
return "删除周期性账单失败".Fail();
}
return "删除成功".Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "删除周期性账单失败ID: {Id}", id);
return $"删除失败: {ex.Message}".Fail();
}
}
/// <summary>
/// 启用/禁用周期性账单
/// </summary>
[HttpPost]
public async Task<BaseResponse> ToggleEnabledAsync([FromQuery] long id, [FromQuery] bool enabled)
{
try
{
var periodic = await periodicRepository.GetByIdAsync(id);
if (periodic == null)
{
return "周期性账单不存在".Fail();
}
periodic.IsEnabled = enabled;
periodic.UpdateTime = DateTime.Now;
var success = await periodicRepository.UpdateAsync(periodic);
if (!success)
{
return "操作失败".Fail();
}
return (enabled ? "已启用" : "已禁用").Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "启用/禁用周期性账单失败ID: {Id}", id);
return $"操作失败: {ex.Message}".Fail();
}
}
}
/// <summary>
/// 创建周期性账单请求
/// </summary>
public class CreatePeriodicRequest
{
public PeriodicType PeriodicType { get; set; }
public string? PeriodicConfig { get; set; }
public decimal Amount { get; set; }
public TransactionType Type { get; set; }
public string? Classify { get; set; }
public string? Reason { get; set; }
}
/// <summary>
/// 更新周期性账单请求
/// </summary>
public class UpdatePeriodicRequest
{
public long Id { get; set; }
public PeriodicType PeriodicType { get; set; }
public string? PeriodicConfig { get; set; }
public decimal Amount { get; set; }
public TransactionType Type { get; set; }
public string? Classify { get; set; }
public string? Reason { get; set; }
public bool IsEnabled { get; set; }
}