重构预算管理模块,添加预算记录和服务,更新相关API,优化预算统计逻辑
This commit is contained in:
151
WebApi/Controllers/BudgetController.cs
Normal file
151
WebApi/Controllers/BudgetController.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
namespace WebApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class BudgetController(
|
||||
IBudgetService budgetService,
|
||||
ILogger<BudgetController> logger) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取预算列表
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<BaseResponse<List<BudgetDto>>> GetListAsync([FromQuery] DateTime? referenceDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var budgets = await budgetService.GetAllAsync();
|
||||
var dtos = new List<BudgetDto>();
|
||||
|
||||
foreach (var budget in budgets)
|
||||
{
|
||||
var currentAmount = await budgetService.CalculateCurrentAmountAsync(budget, referenceDate);
|
||||
dtos.Add(BudgetDto.FromEntity(budget, currentAmount, referenceDate));
|
||||
}
|
||||
|
||||
return dtos.Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "获取预算列表失败");
|
||||
return $"获取预算列表失败: {ex.Message}".Fail<List<BudgetDto>>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取单个预算统计信息
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<BaseResponse<BudgetDto>> GetStatisticsAsync([FromQuery] long id, [FromQuery] DateTime? referenceDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var budget = await budgetService.GetByIdAsync(id);
|
||||
if (budget == null) return "预算不存在".Fail<BudgetDto>();
|
||||
|
||||
var currentAmount = await budgetService.CalculateCurrentAmountAsync(budget, referenceDate);
|
||||
return BudgetDto.FromEntity(budget, currentAmount, referenceDate).Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "获取预算统计失败, Id: {Id}", id);
|
||||
return $"获取预算统计失败: {ex.Message}".Fail<BudgetDto>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建预算
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<BaseResponse<long>> CreateAsync([FromBody] CreateBudgetDto dto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var budget = new BudgetRecord
|
||||
{
|
||||
Name = dto.Name,
|
||||
Type = dto.Type,
|
||||
Limit = dto.Limit,
|
||||
Category = dto.Category,
|
||||
SelectedCategories = dto.SelectedCategories != null ? string.Join(",", dto.SelectedCategories) : string.Empty,
|
||||
StartDate = dto.StartDate ?? DateTime.Now,
|
||||
LastSync = DateTime.Now
|
||||
};
|
||||
|
||||
var success = await budgetService.AddAsync(budget);
|
||||
if (success)
|
||||
{
|
||||
return budget.Id.Ok();
|
||||
}
|
||||
return "创建预算失败".Fail<long>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "创建预算失败");
|
||||
return $"创建预算失败: {ex.Message}".Fail<long>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除预算
|
||||
/// </summary>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<BaseResponse> DeleteByIdAsync(long id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var success = await budgetService.DeleteAsync(id);
|
||||
return success ? BaseResponse.Done() : "删除预算失败".Fail();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "删除预算失败, Id: {Id}", id);
|
||||
return $"删除预算失败: {ex.Message}".Fail();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换预算暂停状态
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<BaseResponse> ToggleStopAsync([FromQuery] long id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var success = await budgetService.ToggleStopAsync(id);
|
||||
return success ? BaseResponse.Done() : "操作失败".Fail();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "切换预算状态失败, Id: {Id}", id);
|
||||
return $"操作失败: {ex.Message}".Fail();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步预算数据
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<BaseResponse<BudgetDto>> SyncAsync([FromQuery] long id, [FromQuery] DateTime? referenceDate = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var budget = await budgetService.GetByIdAsync(id);
|
||||
if (budget == null)
|
||||
{
|
||||
return "预算不存在".Fail<BudgetDto>();
|
||||
}
|
||||
|
||||
budget.LastSync = DateTime.Now;
|
||||
await budgetService.UpdateAsync(budget);
|
||||
|
||||
var currentAmount = await budgetService.CalculateCurrentAmountAsync(budget, referenceDate);
|
||||
return BudgetDto.FromEntity(budget, currentAmount, referenceDate).Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "同步预算失败, Id: {Id}", id);
|
||||
return $"同步失败: {ex.Message}".Fail<BudgetDto>();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
WebApi/Controllers/Dto/BudgetDto.cs
Normal file
49
WebApi/Controllers/Dto/BudgetDto.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
namespace WebApi.Controllers.Dto;
|
||||
|
||||
public class BudgetDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public BudgetPeriodType Type { get; set; }
|
||||
public decimal Limit { get; set; }
|
||||
public decimal Current { get; set; }
|
||||
public BudgetCategory Category { get; set; }
|
||||
public string[] SelectedCategories { get; set; } = Array.Empty<string>();
|
||||
public bool IsStopped { get; set; }
|
||||
public string StartDate { get; set; } = string.Empty;
|
||||
public string Period { get; set; } = string.Empty;
|
||||
public string LastSync { get; set; } = string.Empty;
|
||||
|
||||
public static BudgetDto FromEntity(BudgetRecord entity, decimal currentAmount = 0, DateTime? referenceDate = null)
|
||||
{
|
||||
var date = referenceDate ?? DateTime.Now;
|
||||
var (start, end) = BudgetService.GetPeriodRange(entity.StartDate, entity.Type, date);
|
||||
|
||||
return new BudgetDto
|
||||
{
|
||||
Id = entity.Id,
|
||||
Name = entity.Name,
|
||||
Type = entity.Type,
|
||||
Limit = entity.Limit,
|
||||
Current = currentAmount,
|
||||
Category = entity.Category,
|
||||
SelectedCategories = string.IsNullOrEmpty(entity.SelectedCategories)
|
||||
? Array.Empty<string>()
|
||||
: entity.SelectedCategories.Split(','),
|
||||
IsStopped = entity.IsStopped,
|
||||
StartDate = entity.StartDate.ToString("yyyy-MM-dd"),
|
||||
Period = entity.Type == BudgetPeriodType.Longterm ? "长期" : $"{start:yyyy-MM-dd} ~ {end:yyyy-MM-dd}",
|
||||
LastSync = entity.LastSync?.ToString("yyyy-MM-dd HH:mm") ?? "未同步"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class CreateBudgetDto
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public BudgetPeriodType Type { get; set; } = BudgetPeriodType.Month;
|
||||
public decimal Limit { get; set; }
|
||||
public BudgetCategory Category { get; set; }
|
||||
public string[] SelectedCategories { get; set; } = Array.Empty<string>();
|
||||
public DateTime? StartDate { get; set; }
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using FreeSql;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
Reference in New Issue
Block a user