From 4aa7e82429bc9b7f24bb31c0bdd69a69d10db647 Mon Sep 17 00:00:00 2001 From: SunCheng Date: Tue, 27 Jan 2026 15:29:25 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=AF=B9=E8=B4=A6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20=E5=90=8E=E6=9C=9F=E4=BB=8E=E9=95=BF=E8=AE=A1?= =?UTF-8?q?=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 202 ++++++++++++++++++ Entity/TransactionRecord.cs | 9 +- Repository/TransactionRecordRepository.cs | 44 +--- Service/SmartHandleService.cs | 2 +- Web/src/api/budget.js | 18 +- Web/src/api/notification.js | 6 +- Web/src/api/request.js | 6 +- Web/src/api/statistics.js | 2 - Web/src/api/transactionRecord.js | 28 +-- Web/src/components/Bill/BillForm.vue | 60 +++++- Web/src/components/Bill/ManualBillAdd.vue | 6 +- Web/src/components/Bill/OneLineBillAdd.vue | 19 +- Web/src/components/Budget/BudgetSummary.vue | 34 ++- .../components/Budget/SavingsConfigPopup.vue | 23 +- Web/src/components/Global/GlobalAddBill.vue | 36 +++- Web/src/components/PopupContainer.vue | 30 ++- Web/src/components/TransactionDetail.vue | 157 ++++++-------- Web/src/components/TransactionList.vue | 56 +++-- Web/src/registerServiceWorker.js | 10 +- Web/src/stores/counter.js | 2 +- Web/src/views/BalanceView.vue | 42 +++- Web/src/views/ClassificationBatch.vue | 5 +- Web/src/views/ClassificationEdit.vue | 52 ++++- Web/src/views/ClassificationNLP.vue | 59 ++++- Web/src/views/ClassificationSmart.vue | 12 +- Web/src/views/LoginView.vue | 4 +- Web/src/views/TransactionsRecord.vue | 5 +- WebApi.Test/Basic/DatabaseTest.cs | 58 +++++ .../TransactionRecordController.cs | 57 +---- 29 files changed, 716 insertions(+), 328 deletions(-) create mode 100644 AGENTS.md create mode 100644 WebApi.Test/Basic/DatabaseTest.cs diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..956a5f6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,202 @@ +# AGENTS.md - EmailBill Project Guidelines + +Full-stack budget tracking app with .NET 10 backend and Vue 3 frontend. + +## Project Structure + +``` +EmailBill/ +├── Common/ # Shared utilities and abstractions +├── Entity/ # Database entities (FreeSql ORM) +├── Repository/ # Data access layer +├── Service/ # Business logic layer +├── WebApi/ # ASP.NET Core Web API +├── WebApi.Test/ # Backend tests (xUnit) +└── Web/ # Vue 3 frontend (Vite + Vant UI) +``` + +## Build & Test Commands + +### Backend (.NET 10) +```bash +# Build and run +dotnet build EmailBill.sln +dotnet run --project WebApi/WebApi.csproj + +# Run all tests +dotnet test WebApi.Test/WebApi.Test.csproj + +# Run single test class +dotnet test --filter "FullyQualifiedName~BudgetStatsTest" + +# Run single test method +dotnet test --filter "FullyQualifiedName~BudgetStatsTest.GetCategoryStats_月度_Test" + +# Clean +dotnet clean EmailBill.sln +``` + +### Frontend (Vue 3) +```bash +cd Web + +# Setup and dev +pnpm install +pnpm dev + +# Build and preview +pnpm build +pnpm preview + +# Lint and format +pnpm lint # ESLint with auto-fix +pnpm format # Prettier formatting +``` + +## C# Code Style + +**Namespaces & Imports:** +- File-scoped namespaces: `namespace Entity;` +- Global usings in `Common/GlobalUsings.cs` +- Sort using statements alphabetically + +**Naming:** +- Classes/Methods: `PascalCase` +- Interfaces: `IPascalCase` +- Private fields: `_camelCase` +- Parameters/locals: `camelCase` + +**Entities:** +- Inherit from `BaseEntity` +- Use `[Column]` attributes for FreeSql ORM +- IDs via Snowflake: `YitIdHelper.NextId()` +- Use XML docs (`///`) for public APIs +- **Chinese comments for business logic** (per `.github/csharpe.prompt.md`) + +**Best Practices:** +- Use modern C# syntax (records, pattern matching, nullable types) +- Use `IDateTimeProvider` instead of `DateTime.Now` for testability +- Avoid deep nesting, keep code flat and readable +- Reuse utilities from `Common` project + +**Example:** +```csharp +namespace Entity; + +/// +/// 实体基类 +/// +public abstract class BaseEntity +{ + [Column(IsPrimary = true)] + public long Id { get; set; } = YitIdHelper.NextId(); + + public DateTime CreateTime { get; set; } = DateTime.Now; +} +``` + +## Vue/TypeScript Style + +**Component Structure:** +```vue + + + + + +``` + +**Rules:** +- Composition API with `