302 lines
9.2 KiB
C#
302 lines
9.2 KiB
C#
|
|
namespace WebApi.Controllers;
|
|||
|
|
|
|||
|
|
[ApiController]
|
|||
|
|
[Route("api/[controller]/[action]")]
|
|||
|
|
public class TransactionRecordController(
|
|||
|
|
ITransactionRecordRepository transactionRepository,
|
|||
|
|
ILogger<TransactionRecordController> logger
|
|||
|
|
) : ControllerBase
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取交易记录列表(分页)
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpGet]
|
|||
|
|
public async Task<PagedResponse<Entity.TransactionRecord>> GetListAsync(
|
|||
|
|
[FromQuery] DateTime? lastOccurredAt = null,
|
|||
|
|
[FromQuery] long? lastId = null,
|
|||
|
|
[FromQuery] string? searchKeyword = null
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var (list, lastTime, lastIdResult) = await transactionRepository.GetPagedListAsync(lastOccurredAt, lastId, 20, searchKeyword);
|
|||
|
|
var total = await transactionRepository.GetTotalCountAsync();
|
|||
|
|
|
|||
|
|
return new PagedResponse<Entity.TransactionRecord>
|
|||
|
|
{
|
|||
|
|
Success = true,
|
|||
|
|
Data = list.ToArray(),
|
|||
|
|
Total = (int)total,
|
|||
|
|
LastId = lastIdResult,
|
|||
|
|
LastTime = lastTime
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "获取交易记录列表失败,时间: {LastTime}, ID: {LastId}", lastOccurredAt, lastId);
|
|||
|
|
return PagedResponse<Entity.TransactionRecord>.Fail($"获取交易记录列表失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据ID获取交易记录详情
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpGet("{id}")]
|
|||
|
|
public async Task<BaseResponse<Entity.TransactionRecord>> GetByIdAsync(long id)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var transaction = await transactionRepository.GetByIdAsync(id);
|
|||
|
|
if (transaction == null)
|
|||
|
|
{
|
|||
|
|
return BaseResponse<Entity.TransactionRecord>.Fail("交易记录不存在");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new BaseResponse<Entity.TransactionRecord>
|
|||
|
|
{
|
|||
|
|
Success = true,
|
|||
|
|
Data = transaction
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "获取交易记录详情失败,交易ID: {TransactionId}", id);
|
|||
|
|
return BaseResponse<Entity.TransactionRecord>.Fail($"获取交易记录详情失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据邮件ID获取交易记录列表
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpGet("{emailId}")]
|
|||
|
|
public async Task<BaseResponse<List<Entity.TransactionRecord>>> GetByEmailIdAsync(long emailId)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var transactions = await transactionRepository.GetByEmailIdAsync(emailId);
|
|||
|
|
return new BaseResponse<List<Entity.TransactionRecord>>
|
|||
|
|
{
|
|||
|
|
Success = true,
|
|||
|
|
Data = transactions
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "获取邮件交易记录失败,邮件ID: {EmailId}", emailId);
|
|||
|
|
return BaseResponse<List<Entity.TransactionRecord>>.Fail($"获取邮件交易记录失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 创建交易记录
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpPost]
|
|||
|
|
public async Task<BaseResponse> CreateAsync([FromBody] CreateTransactionDto dto)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 解析日期字符串
|
|||
|
|
if (!DateTime.TryParse(dto.OccurredAt, out var occurredAt))
|
|||
|
|
{
|
|||
|
|
return BaseResponse.Fail("交易时间格式不正确");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var transaction = new Entity.TransactionRecord
|
|||
|
|
{
|
|||
|
|
OccurredAt = occurredAt,
|
|||
|
|
Reason = dto.Reason ?? string.Empty,
|
|||
|
|
Amount = dto.Amount,
|
|||
|
|
Type = dto.Type,
|
|||
|
|
Classify = dto.Classify ?? string.Empty,
|
|||
|
|
SubClassify = dto.SubClassify ?? string.Empty,
|
|||
|
|
ImportFrom = "手动录入",
|
|||
|
|
EmailMessageId = 0 // 手动录入的记录,EmailMessageId 设为 0
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var result = await transactionRepository.AddAsync(transaction);
|
|||
|
|
if (result)
|
|||
|
|
{
|
|||
|
|
return new BaseResponse
|
|||
|
|
{
|
|||
|
|
Success = true
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return BaseResponse.Fail("创建交易记录失败");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "创建交易记录失败,交易信息: {@TransactionDto}", dto);
|
|||
|
|
return BaseResponse.Fail($"创建交易记录失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新交易记录
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpPost]
|
|||
|
|
public async Task<BaseResponse> UpdateAsync([FromBody] UpdateTransactionDto dto)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var transaction = await transactionRepository.GetByIdAsync(dto.Id);
|
|||
|
|
if (transaction == null)
|
|||
|
|
{
|
|||
|
|
return BaseResponse.Fail("交易记录不存在");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新可编辑字段
|
|||
|
|
transaction.Reason = dto.Reason ?? string.Empty;
|
|||
|
|
transaction.Amount = dto.Amount;
|
|||
|
|
transaction.Balance = dto.Balance;
|
|||
|
|
transaction.Type = dto.Type;
|
|||
|
|
transaction.Classify = dto.Classify ?? string.Empty;
|
|||
|
|
transaction.SubClassify = dto.SubClassify ?? string.Empty;
|
|||
|
|
|
|||
|
|
var success = await transactionRepository.UpdateAsync(transaction);
|
|||
|
|
if (success)
|
|||
|
|
{
|
|||
|
|
return new BaseResponse
|
|||
|
|
{
|
|||
|
|
Success = true
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return BaseResponse.Fail("更新交易记录失败");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "更新交易记录失败,交易ID: {TransactionId}, 交易信息: {@TransactionDto}", dto.Id, dto);
|
|||
|
|
return BaseResponse.Fail($"更新交易记录失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 删除交易记录
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpPost]
|
|||
|
|
public async Task<BaseResponse> DeleteByIdAsync([FromQuery] long id)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var success = await transactionRepository.DeleteAsync(id);
|
|||
|
|
if (success)
|
|||
|
|
{
|
|||
|
|
return new BaseResponse
|
|||
|
|
{
|
|||
|
|
Success = true
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return BaseResponse.Fail("删除交易记录失败,记录不存在");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "删除交易记录失败,交易ID: {TransactionId}", id);
|
|||
|
|
return BaseResponse.Fail($"删除交易记录失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取指定月份每天的消费统计
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpGet]
|
|||
|
|
public async Task<BaseResponse<List<DailyStatisticsDto>>> GetDailyStatisticsAsync(
|
|||
|
|
[FromQuery] int year,
|
|||
|
|
[FromQuery] int month
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var statistics = await transactionRepository.GetDailyStatisticsAsync(year, month);
|
|||
|
|
var result = statistics.Select(s => new DailyStatisticsDto(s.Key, s.Value.count, s.Value.amount)).ToList();
|
|||
|
|
|
|||
|
|
return new BaseResponse<List<DailyStatisticsDto>>
|
|||
|
|
{
|
|||
|
|
Success = true,
|
|||
|
|
Data = result
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "获取日历统计数据失败,年份: {Year}, 月份: {Month}", year, month);
|
|||
|
|
return BaseResponse<List<DailyStatisticsDto>>.Fail($"获取日历统计数据失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取指定日期的交易记录
|
|||
|
|
/// </summary>
|
|||
|
|
[HttpGet]
|
|||
|
|
public async Task<BaseResponse<List<Entity.TransactionRecord>>> GetByDateAsync(
|
|||
|
|
[FromQuery] string date
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (!DateTime.TryParse(date, out var targetDate))
|
|||
|
|
{
|
|||
|
|
return BaseResponse<List<Entity.TransactionRecord>>.Fail("日期格式不正确");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取当天的开始和结束时间
|
|||
|
|
var startDate = targetDate.Date;
|
|||
|
|
var endDate = startDate.AddDays(1);
|
|||
|
|
|
|||
|
|
var records = await transactionRepository.GetByDateRangeAsync(startDate, endDate);
|
|||
|
|
|
|||
|
|
return new BaseResponse<List<Entity.TransactionRecord>>
|
|||
|
|
{
|
|||
|
|
Success = true,
|
|||
|
|
Data = records
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "获取指定日期的交易记录失败,日期: {Date}", date);
|
|||
|
|
return BaseResponse<List<Entity.TransactionRecord>>.Fail($"获取指定日期的交易记录失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 创建交易记录DTO
|
|||
|
|
/// </summary>
|
|||
|
|
public record CreateTransactionDto(
|
|||
|
|
string OccurredAt,
|
|||
|
|
string? Reason,
|
|||
|
|
decimal Amount,
|
|||
|
|
TransactionType Type,
|
|||
|
|
string? Classify,
|
|||
|
|
string? SubClassify
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新交易记录DTO
|
|||
|
|
/// </summary>
|
|||
|
|
public record UpdateTransactionDto(
|
|||
|
|
long Id,
|
|||
|
|
string? Reason,
|
|||
|
|
decimal Amount,
|
|||
|
|
decimal Balance,
|
|||
|
|
TransactionType Type,
|
|||
|
|
string? Classify,
|
|||
|
|
string? SubClassify
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 日历统计响应DTO
|
|||
|
|
/// </summary>
|
|||
|
|
public record DailyStatisticsDto(
|
|||
|
|
string Date,
|
|||
|
|
int Count,
|
|||
|
|
decimal Amount
|
|||
|
|
);
|