重构账单查询sql
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 26s
Docker Build & Deploy / Deploy to Production (push) Successful in 7s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 2s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 26s
Docker Build & Deploy / Deploy to Production (push) Successful in 7s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 2s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
This commit is contained in:
56
WebApi/Controllers/AGENTS.md
Normal file
56
WebApi/Controllers/AGENTS.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# API CONTROLLERS KNOWLEDGE BASE
|
||||
|
||||
**Generated:** 2026-01-28
|
||||
**Parent:** EmailBill/AGENTS.md
|
||||
|
||||
## OVERVIEW
|
||||
REST API controllers using ASP.NET Core with DTO patterns and standardized responses.
|
||||
|
||||
## STRUCTURE
|
||||
```
|
||||
WebApi/Controllers/
|
||||
├── Dto/ # Data transfer objects
|
||||
│ ├── BaseResponse.cs # Standard response wrapper
|
||||
│ ├── LoginRequest/Response.cs # Authentication DTOs
|
||||
│ ├── BudgetDto.cs # Budget data transfer
|
||||
│ ├── EmailMessageDto.cs # Email data transfer
|
||||
│ └── PagedResponse.cs # Pagination wrapper
|
||||
├── AuthController.cs # Authentication endpoints
|
||||
├── BudgetController.cs # Budget management
|
||||
├── TransactionRecordController.cs # Transaction CRUD
|
||||
├── EmailMessageController.cs # Email processing
|
||||
├── MessageRecordController.cs # Message handling
|
||||
└── [Other controllers] # Feature-specific endpoints
|
||||
```
|
||||
|
||||
## WHERE TO LOOK
|
||||
| Task | Location | Notes |
|
||||
|------|----------|-------|
|
||||
| Authentication | AuthController.cs | JWT login, token refresh |
|
||||
| Budget APIs | BudgetController.cs | Budget CRUD, statistics |
|
||||
| Transaction APIs | TransactionRecordController.cs | Financial transactions |
|
||||
| Email APIs | EmailMessageController.cs | Email processing |
|
||||
| DTO patterns | Dto/ | Request/response models |
|
||||
| Standard responses | BaseResponse.cs, PagedResponse.cs | Consistent API format |
|
||||
|
||||
## CONVENTIONS
|
||||
- Controllers inherit from ControllerBase
|
||||
- Route attributes: [ApiController], [Route("api/[controller]")]
|
||||
- All actions return Task<IActionResult> or Task<BaseResponse<T>>
|
||||
- Use DTOs for all request/response data
|
||||
- HTTP verb attributes: [HttpGet], [HttpPost], [HttpPut], [HttpDelete]
|
||||
- Validation via model state and attributes
|
||||
|
||||
## ANTI-PATTERNS (THIS LAYER)
|
||||
- Never return domain entities directly
|
||||
- Don't access repositories from controllers (use services)
|
||||
- Avoid business logic in controllers
|
||||
- No synchronous I/O operations
|
||||
- Don't skip authentication/authorization where needed
|
||||
|
||||
## UNIQUE STYLES
|
||||
- BaseResponse<T> wrapper for consistent API format
|
||||
- PagedResponse<T> for list endpoints
|
||||
- Chinese error messages for user-facing errors
|
||||
- JWT-based authentication patterns
|
||||
- Swagger/OpenAPI documentation via attributes
|
||||
@@ -4,6 +4,7 @@ namespace WebApi.Controllers;
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class TransactionRecordController(
|
||||
ITransactionRecordRepository transactionRepository,
|
||||
ITransactionStatisticsService transactionStatisticsService,
|
||||
ISmartHandleService smartHandleService,
|
||||
ILogger<TransactionRecordController> logger,
|
||||
IConfigService configService
|
||||
@@ -34,27 +35,27 @@ public class TransactionRecordController(
|
||||
: classify.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
TransactionType? transactionType = type.HasValue ? (TransactionType)type.Value : null;
|
||||
var list = await transactionRepository.GetPagedListAsync(
|
||||
pageIndex,
|
||||
pageSize,
|
||||
searchKeyword,
|
||||
classifies,
|
||||
transactionType,
|
||||
year,
|
||||
month,
|
||||
startDate,
|
||||
endDate,
|
||||
reason,
|
||||
sortByAmount);
|
||||
var total = await transactionRepository.GetTotalCountAsync(
|
||||
searchKeyword,
|
||||
classifies,
|
||||
transactionType,
|
||||
year,
|
||||
month,
|
||||
startDate,
|
||||
endDate,
|
||||
reason);
|
||||
var list = await transactionRepository.QueryAsync(
|
||||
year: year,
|
||||
month: month,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
type: transactionType,
|
||||
classifies: classifies,
|
||||
searchKeyword: searchKeyword,
|
||||
reason: reason,
|
||||
pageIndex: pageIndex,
|
||||
pageSize: pageSize,
|
||||
sortByAmount: sortByAmount);
|
||||
var total = await transactionRepository.CountAsync(
|
||||
year: year,
|
||||
month: month,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
type: transactionType,
|
||||
classifies: classifies,
|
||||
searchKeyword: searchKeyword,
|
||||
reason: reason);
|
||||
|
||||
return new PagedResponse<TransactionRecord>
|
||||
{
|
||||
@@ -267,7 +268,7 @@ public class TransactionRecordController(
|
||||
var savingClassify = await configService.GetConfigByKeyAsync<string>("SavingsCategories");
|
||||
|
||||
// 获取每日统计数据
|
||||
var statistics = await transactionRepository.GetDailyStatisticsAsync(year, month, savingClassify);
|
||||
var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify);
|
||||
|
||||
// 按日期排序并计算累积余额
|
||||
var sortedStats = statistics.OrderBy(s => s.Key).ToList();
|
||||
@@ -308,7 +309,7 @@ public class TransactionRecordController(
|
||||
// 获取存款分类
|
||||
var savingClassify = await configService.GetConfigByKeyAsync<string>("SavingsCategories");
|
||||
|
||||
var statistics = await transactionRepository.GetDailyStatisticsAsync(year, month, savingClassify);
|
||||
var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify);
|
||||
var result = statistics.Select(s => new DailyStatisticsDto(
|
||||
s.Key,
|
||||
s.Value.count,
|
||||
@@ -339,7 +340,7 @@ public class TransactionRecordController(
|
||||
{
|
||||
try
|
||||
{
|
||||
var statistics = await transactionRepository.GetMonthlyStatisticsAsync(year, month);
|
||||
var statistics = await transactionStatisticsService.GetMonthlyStatisticsAsync(year, month);
|
||||
return statistics.Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -361,7 +362,7 @@ public class TransactionRecordController(
|
||||
{
|
||||
try
|
||||
{
|
||||
var statistics = await transactionRepository.GetCategoryStatisticsAsync(year, month, type);
|
||||
var statistics = await transactionStatisticsService.GetCategoryStatisticsAsync(year, month, type);
|
||||
return statistics.Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -383,7 +384,7 @@ public class TransactionRecordController(
|
||||
{
|
||||
try
|
||||
{
|
||||
var statistics = await transactionRepository.GetTrendStatisticsAsync(startYear, startMonth, monthCount);
|
||||
var statistics = await transactionStatisticsService.GetTrendStatisticsAsync(startYear, startMonth, monthCount);
|
||||
return statistics.Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -439,7 +440,7 @@ public class TransactionRecordController(
|
||||
var startDate = targetDate.Date;
|
||||
var endDate = startDate.AddDays(1);
|
||||
|
||||
var records = await transactionRepository.GetByDateRangeAsync(startDate, endDate);
|
||||
var records = await transactionRepository.QueryAsync(startDate: startDate, endDate: endDate);
|
||||
|
||||
return records.Ok();
|
||||
}
|
||||
@@ -458,7 +459,7 @@ public class TransactionRecordController(
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await transactionRepository.GetUnclassifiedCountAsync();
|
||||
var count = (int)await transactionRepository.CountAsync();
|
||||
return count.Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -627,7 +628,7 @@ public class TransactionRecordController(
|
||||
{
|
||||
try
|
||||
{
|
||||
var (list, total) = await transactionRepository.GetReasonGroupsAsync(pageIndex, pageSize);
|
||||
var (list, total) = await transactionStatisticsService.GetReasonGroupsAsync(pageIndex, pageSize);
|
||||
return new PagedResponse<ReasonGroupDto>
|
||||
{
|
||||
Success = true,
|
||||
|
||||
Reference in New Issue
Block a user