- Add .NET 8 backend with Clean Architecture - Add React + Vite + TypeScript frontend - Implement authentication with JWT - Implement Azure Blob Storage client - Implement OCR integration - Implement supplier matching service - Implement voucher generation - Implement Fortnox provider - Add unit and integration tests - Add Docker Compose configuration
19 KiB
19 KiB
Invoice Master - 项目目录结构
版本: v3.0
技术栈: .NET 8 + React 18
invoice-master/
│
├── README.md # 项目说明
├── ARCHITECTURE.md # 架构文档
├── API_DESIGN.md # API 设计文档
├── DATABASE_SCHEMA.md # 数据库设计
├── DEVELOPMENT_PLAN.md # 开发计划
├── DEPLOYMENT_GUIDE.md # 部署指南
├── .gitignore # Git 忽略配置
├── docker-compose.yml # 本地开发环境
├── docker-compose.prod.yml # 生产环境配置
│
├── backend/ # .NET 后端
│ ├── InvoiceMaster.sln # Solution 文件
│ ├── Directory.Build.props # 全局 MSBuild 属性
│ ├── global.json # .NET SDK 版本
│ ├── Dockerfile # 容器镜像
│ ├── docker-compose.yml # 本地开发编排
│ │
│ ├── src/ # 源代码
│ │ ├── InvoiceMaster.API/ # Web API 入口
│ │ │ ├── InvoiceMaster.API.csproj
│ │ │ ├── Program.cs
│ │ │ ├── appsettings.json
│ │ │ ├── appsettings.Development.json
│ │ │ ├── Controllers/ # API 控制器
│ │ │ │ ├── AuthController.cs
│ │ │ │ ├── InvoicesController.cs
│ │ │ │ └── AccountingController.cs
│ │ │ ├── Middleware/ # 中间件
│ │ │ │ ├── ExceptionHandlingMiddleware.cs
│ │ │ │ └── RequestLoggingMiddleware.cs
│ │ │ └── Properties/
│ │ │ └── launchSettings.json
│ │ │
│ │ ├── InvoiceMaster.Core/ # 领域层
│ │ │ ├── InvoiceMaster.Core.csproj
│ │ │ ├── Entities/ # 领域实体
│ │ │ │ ├── Invoice.cs
│ │ │ │ ├── AccountingConnection.cs
│ │ │ │ ├── User.cs
│ │ │ │ └── SupplierCache.cs
│ │ │ ├── Events/ # 领域事件
│ │ │ │ ├── DomainEvent.cs
│ │ │ │ ├── InvoiceImportedEvent.cs
│ │ │ │ └── ConnectionCreatedEvent.cs
│ │ │ ├── Interfaces/ # 领域接口
│ │ │ │ ├── IRepository.cs
│ │ │ │ ├── IUnitOfWork.cs
│ │ │ │ └── IDomainEventDispatcher.cs
│ │ │ └── ValueObjects/ # 值对象
│ │ │ ├── Money.cs
│ │ │ └── OrganizationNumber.cs
│ │ │
│ │ ├── InvoiceMaster.Application/ # 应用层
│ │ │ ├── InvoiceMaster.Application.csproj
│ │ │ ├── Commands/ # CQRS 命令
│ │ │ │ ├── ImportInvoice/
│ │ │ │ │ ├── ImportInvoiceCommand.cs
│ │ │ │ │ └── ImportInvoiceCommandHandler.cs
│ │ │ │ └── CreateConnection/
│ │ │ │ ├── CreateConnectionCommand.cs
│ │ │ │ └── CreateConnectionCommandHandler.cs
│ │ │ ├── Queries/ # CQRS 查询
│ │ │ │ ├── GetInvoice/
│ │ │ │ │ ├── GetInvoiceQuery.cs
│ │ │ │ │ └── GetInvoiceQueryHandler.cs
│ │ │ │ └── ListInvoices/
│ │ │ │ ├── ListInvoicesQuery.cs
│ │ │ │ └── ListInvoicesQueryHandler.cs
│ │ │ ├── DTOs/ # 数据传输对象
│ │ │ │ ├── InvoiceDto.cs
│ │ │ │ └── ConnectionDto.cs
│ │ │ ├── Mappings/ # AutoMapper 配置
│ │ │ │ └── MappingProfile.cs
│ │ │ └── Behaviors/ # MediatR 行为
│ │ │ ├── ValidationBehavior.cs
│ │ │ └── LoggingBehavior.cs
│ │ │
│ │ ├── InvoiceMaster.Infrastructure/# 基础设施层
│ │ │ ├── InvoiceMaster.Infrastructure.csproj
│ │ │ ├── Data/ # EF Core
│ │ │ │ ├── ApplicationDbContext.cs
│ │ │ │ ├── Configurations/ # 实体配置
│ │ │ │ │ ├── InvoiceConfiguration.cs
│ │ │ │ │ └── ConnectionConfiguration.cs
│ │ │ │ ├── Migrations/ # 迁移文件
│ │ │ │ └── Interceptors/ # EF 拦截器
│ │ │ │ └── DispatchDomainEventsInterceptor.cs
│ │ │ ├── Repositories/ # 仓储实现
│ │ │ │ ├── InvoiceRepository.cs
│ │ │ │ └── ConnectionRepository.cs
│ │ │ ├── Services/ # 外部服务
│ │ │ │ ├── BlobStorageService.cs
│ │ │ │ └── OCRService.cs
│ │ │ └── Identity/ # Identity 配置
│ │ │ └── ApplicationUser.cs
│ │ │
│ │ └── InvoiceMaster.Integrations/# 集成层
│ │ ├── InvoiceMaster.Integrations.csproj
│ │ ├── Accounting/ # 会计系统集成
│ │ │ ├── IAccountingSystem.cs
│ │ │ ├── IAccountingSystemFactory.cs
│ │ │ ├── AccountingSystemFactory.cs
│ │ │ ├── Models/ # 通用模型
│ │ │ │ ├── Supplier.cs
│ │ │ │ ├── Voucher.cs
│ │ │ │ └── Account.cs
│ │ │ └── Providers/ # Provider 实现
│ │ │ ├── Fortnox/
│ │ │ │ ├── FortnoxProvider.cs
│ │ │ │ ├── FortnoxAuthClient.cs
│ │ │ │ └── FortnoxApiClient.cs
│ │ │ └── Visma/ # Future
│ │ │ └── VismaProvider.cs
│ │ └── Extensions/ # DI 扩展
│ │ └── AccountingServiceExtensions.cs
│ │
│ └── tests/ # 测试项目
│ ├── InvoiceMaster.UnitTests/
│ │ ├── InvoiceMaster.UnitTests.csproj
│ │ ├── Commands/
│ │ ├── Queries/
│ │ └── Domain/
│ ├── InvoiceMaster.IntegrationTests/
│ │ ├── InvoiceMaster.IntegrationTests.csproj
│ │ ├── Factories/
│ │ │ └── CustomWebApplicationFactory.cs
│ │ └── Controllers/
│ └── InvoiceMaster.ArchitectureTests/
│ └── InvoiceMaster.ArchitectureTests.csproj
│
├── frontend/ # React 前端
│ ├── package.json # 依赖管理
│ ├── tsconfig.json # TypeScript 配置
│ ├── vite.config.ts # Vite 配置
│ ├── tailwind.config.js # TailwindCSS 配置
│ ├── index.html # 入口 HTML
│ ├── .env.example # 环境变量示例
│ │
│ ├── src/
│ │ ├── main.tsx # 应用入口
│ │ ├── App.tsx # 根组件
│ │ ├── index.css # 全局样式
│ │ │
│ │ ├── api/ # API 客户端
│ │ │ ├── client.ts # Axios 实例
│ │ │ ├── auth.ts # 认证相关 API
│ │ │ ├── invoices.ts # 发票相关 API
│ │ │ ├── suppliers.ts # 供应商相关 API
│ │ │ ├── accounting.ts # 会计系统集成 API (多系统)
│ │ │ └── providers/ # Provider 特定 API
│ │ │ ├── fortnox.ts # Fortnox API
│ │ │ ├── visma.ts # Visma API (future)
│ │ │ └── index.ts # Provider 导出
│ │ │
│ │ ├── components/ # 组件
│ │ │ ├── common/ # 通用组件
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── Input.tsx
│ │ │ │ ├── Card.tsx
│ │ │ │ ├── Modal.tsx
│ │ │ │ ├── LoadingSpinner.tsx
│ │ │ │ └── ErrorBoundary.tsx
│ │ │ │
│ │ │ ├── layout/ # 布局组件
│ │ │ │ ├── Layout.tsx # 主布局
│ │ │ │ ├── Header.tsx # 顶部导航
│ │ │ │ ├── Sidebar.tsx # 侧边栏
│ │ │ │ └── Footer.tsx # 底部
│ │ │ │
│ │ │ ├── auth/ # 认证组件
│ │ │ │ ├── AccountingProviderSelect.tsx # 会计系统选择
│ │ │ │ ├── ProviderConnect.tsx # 通用连接组件
│ │ │ │ ├── LoginForm.tsx
│ │ │ │ └── ProtectedRoute.tsx
│ │ │ │
│ │ │ ├── upload/ # 上传组件
│ │ │ │ ├── FileUpload.tsx # 文件上传区域
│ │ │ │ ├── UploadProgress.tsx # 上传进度
│ │ │ │ ├── DragDropZone.tsx # 拖放区域
│ │ │ │ └── ProviderSelector.tsx # 目标会计系统选择
│ │ │ │
│ │ │ ├── invoice/ # 发票组件
│ │ │ │ ├── InvoiceCard.tsx # 发票卡片
│ │ │ │ ├── InvoiceList.tsx # 发票列表
│ │ │ │ ├── InvoicePreview.tsx # 发票预览
│ │ │ │ ├── InvoiceForm.tsx # 发票编辑表单
│ │ │ │ └── InvoiceStatus.tsx # 状态显示
│ │ │ │
│ │ │ ├── supplier/ # 供应商组件
│ │ │ │ ├── SupplierMatch.tsx # 供应商匹配
│ │ │ │ ├── SupplierSelect.tsx # 供应商选择
│ │ │ │ └── SupplierCreate.tsx # 创建供应商
│ │ │ │
│ │ │ └── voucher/ # 凭证组件
│ │ │ ├── VoucherPreview.tsx # 凭证预览
│ │ │ ├── AccountSelect.tsx # 科目选择
│ │ │ └── VoucherRows.tsx # 凭证行
│ │ │
│ │ ├── hooks/ # 自定义 Hooks
│ │ │ ├── useAuth.ts # 认证 Hook
│ │ │ ├── useInvoices.ts # 发票数据 Hook
│ │ │ ├── useSuppliers.ts # 供应商数据 Hook
│ │ │ ├── useUpload.ts # 上传 Hook
│ │ │ ├── useAccounting.ts # 会计系统连接 Hook (通用)
│ │ │ ├── useProviders.ts # Provider 列表 Hook
│ │ │ └── useToast.ts # 通知 Hook
│ │ │
│ │ ├── stores/ # 状态管理 (Zustand)
│ │ │ ├── authStore.ts # 认证状态
│ │ │ ├── invoiceStore.ts # 发票状态
│ │ │ ├── accountingStore.ts # 会计系统连接状态
│ │ │ └── uiStore.ts # UI 状态
│ │ │
│ │ ├── types/ # TypeScript 类型
│ │ │ ├── auth.ts
│ │ │ ├── invoice.ts
│ │ │ ├── supplier.ts
│ │ │ ├── voucher.ts
│ │ │ ├── accounting.ts # 会计系统类型
│ │ │ └── api.ts
│ │ │
│ │ ├── utils/ # 工具函数
│ │ │ ├── formatters.ts # 格式化
│ │ │ ├── validators.ts # 验证
│ │ │ └── constants.ts # 常量
│ │ │
│ │ └── pages/ # 页面组件
│ │ ├── Home.tsx # 首页/仪表盘
│ │ ├── Login.tsx # 登录页
│ │ ├── Connect.tsx # 会计系统连接页
│ │ ├── Upload.tsx # 上传页
│ │ ├── Review.tsx # 审核页
│ │ ├── History.tsx # 历史记录
│ │ ├── Settings.tsx # 设置页
│ │ └── NotFound.tsx # 404
│ │
│ └── public/ # 静态资源
│ ├── logo.svg
│ └── favicon.ico
│
├── infrastructure/ # 基础设施
│ ├── terraform/ # Terraform 配置
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ ├── backend.tf
│ │ └── modules/ # 模块
│ │ ├── database/
│ │ ├── cache/
│ │ ├── storage/
│ │ └── container_apps/
│ │
│ ├── azure/ # Azure 特定配置
│ │ ├── bicep/ # Bicep 模板
│ │ └── arm/ # ARM 模板
│ │
│ └── scripts/ # 部署脚本
│ ├── deploy.sh
│ ├── setup-local.sh
│ └── migrate.sh
│
├── docs/ # 文档
│ ├── development/ # 开发文档
│ ├── api/ # API 文档
│ ├── deployment/ # 部署文档
│ └── providers/ # Provider 开发文档 (新增)
│ ├── README.md # Provider 开发指南
│ ├── interface.md # 接口规范
│ └── examples/ # 示例代码
│
└── scripts/ # 实用脚本
├── setup.sh # 项目初始化
├── dev-start.sh # 启动开发环境
├── test.sh # 运行测试
├── lint.sh # 代码检查
└── add-provider.sh # 添加新 Provider 脚手架 (新增)
目录说明
Frontend
-
api/: API 客户端封装
accounting.ts: 通用会计系统 APIproviders/: Provider 特定 API 实现
-
components/: 按功能分组的 React 组件
auth/AccountingProviderSelect.tsx: 会计系统选择组件auth/ProviderConnect.tsx: 通用连接组件upload/ProviderSelector.tsx: 上传时选择目标会计系统
-
hooks/: 自定义 React Hooks
useAccounting.ts: 通用会计系统连接 HookuseProviders.ts: 获取支持的 Provider 列表
-
stores/: Zustand 状态管理
accountingStore.ts: 会计系统连接状态
Backend (.NET)
-
InvoiceMaster.API/: Web API 入口
Controllers/: API 控制器Middleware/: 中间件appsettings.json: 配置
-
InvoiceMaster.Core/: 领域层
Entities/: 领域实体 (Invoice, AccountingConnection)Events/: 领域事件 (用于审计)Interfaces/: 领域接口ValueObjects/: 值对象
-
InvoiceMaster.Application/: 应用层 (CQRS)
Commands/: 命令处理器 (MediatR)Queries/: 查询处理器DTOs/: 数据传输对象Mappings/: AutoMapper 配置
-
InvoiceMaster.Infrastructure/: 基础设施层
Data/: EF Core DbContext, 配置, 迁移Repositories/: 仓储实现Services/: 外部服务实现Identity/: ASP.NET Core Identity
-
InvoiceMaster.Integrations/: 集成层
Accounting/: 会计系统集成IAccountingSystem.cs: 接口AccountingSystemFactory.cs: 工厂Providers/: Provider 实现Fortnox/: Fortnox ProviderVisma/: Visma Provider (future)
Infrastructure
- terraform/: 基础设施即代码
- scripts/: 部署和运维脚本
Docs
- providers/: Provider 开发文档 (新增)
- 如何添加新的会计系统 Provider
- 接口规范
- 示例代码
命名规范
文件命名
- React 组件: PascalCase (e.g.,
InvoiceCard.tsx) - Hooks: camelCase with
useprefix (e.g.,useAccounting.ts) - 工具函数: camelCase (e.g.,
formatters.ts) - C# 类: PascalCase (e.g.,
InvoiceService.cs) - C# 接口: PascalCase with
Iprefix (e.g.,IAccountingSystem.cs) - 测试文件:
{ClassName}Tests.cs(e.g.,InvoiceServiceTests.cs) - Provider 实现:
{ProviderName}Provider.cs(e.g.,FortnoxProvider.cs)
代码规范
- TypeScript: 严格模式,显式返回类型
- C#: C# 12 特性, 使用
record和required, StyleCop 规则 - CSS: TailwindCSS 工具类优先
- Git: Conventional commits
添加新 Provider 的目录变更
当添加新的会计系统 Provider 时,需要创建/修改以下文件:
Backend
backend/src/InvoiceMaster.Integrations/Accounting/Providers/
├── {ProviderName}/
│ ├── {ProviderName}Provider.cs # 新 Provider 实现
│ ├── {ProviderName}AuthClient.cs # OAuth 客户端
│ └── {ProviderName}ApiClient.cs # API 客户端
backend/src/InvoiceMaster.API/
├── appsettings.json # 添加 Provider 配置
└── Extensions/
└── AccountingServiceExtensions.cs # 注册 Provider
Frontend
frontend/src/api/providers/
├── index.ts # 导出 Provider API
├── {provider}.ts # 新 Provider API 客户端 (可选)
frontend/src/types/accounting.ts # 添加 Provider 类型
Docs
docs/providers/
├── {provider}.md # 新 Provider 文档
└── examples/
└── {provider}_example.py
文档历史:
| 版本 | 日期 | 作者 | 变更 |
|---|---|---|---|
| 3.0 | 2026-02-03 | Claude Code | 重构为 .NET 8 + 轻量级 DDD |
| 2.0 | 2026-02-03 | Claude Code | 添加多会计系统集成层 |
| 1.0 | 2026-02-03 | Claude Code | 初始版本 |