- 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
506 lines
32 KiB
Markdown
506 lines
32 KiB
Markdown
# Invoice Master - 系统架构文档
|
||
|
||
**版本**: v3.0
|
||
**日期**: 2026-02-03
|
||
**状态**: 设计中
|
||
|
||
---
|
||
|
||
## 1. 项目概述
|
||
|
||
### 1.1 目标
|
||
|
||
构建一个**多会计系统集成的发票处理平台**,允许企业通过 Invoice Master OCR 技术自动识别发票并导入到各种会计软件。首个支持 Fortnox,架构设计支持未来无缝集成其他会计系统(如 Visma, Hogia 等)。
|
||
|
||
### 1.2 核心功能
|
||
|
||
1. **多会计系统支持** - 统一的抽象层,支持连接不同的会计软件
|
||
2. **OAuth2 认证** - 安全连接用户会计系统账户
|
||
3. **发票 OCR 识别** - 调用现有 invoice-master API 进行发票字段提取
|
||
4. **供应商自动匹配** - 智能匹配或创建会计系统供应商
|
||
5. **会计凭证生成** - 自动生成会计凭证
|
||
6. **文件存档** - 上传发票 PDF 到会计系统
|
||
7. **审计追踪** - 完整的操作日志和事件溯源
|
||
|
||
### 1.3 集成模式
|
||
|
||
采用 **外部独立应用 (External App)** 模式,支持多提供商:
|
||
|
||
```
|
||
┌─────────────────┐ ┌─────────────────────────┐ ┌─────────────────┐
|
||
│ Fortnox │────▶│ │────▶│ Fortnox │
|
||
│ (点击集成) │ │ │ │ (数据已导入) │
|
||
└─────────────────┘ │ Invoice Master │ └─────────────────┘
|
||
│ (多会计系统集成平台) │
|
||
┌─────────────────┐ │ │ ┌─────────────────┐
|
||
│ Visma │────▶│ - Fortnox Provider │────▶│ Visma │
|
||
│ (点击集成) │ │ - Visma Provider │ │ (数据已导入) │
|
||
└─────────────────┘ │ - Hogia Provider │ └─────────────────┘
|
||
│ - ... │
|
||
┌─────────────────┐ │ │ ┌─────────────────┐
|
||
│ Hogia │────▶│ │────▶│ Hogia │
|
||
│ (点击集成) │ │ │ │ (数据已导入) │
|
||
└─────────────────┘ └─────────────────────────┘ └─────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 系统架构
|
||
|
||
### 2.1 整体架构(.NET + 轻量级 DDD)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ 用户层 (User Layer) │
|
||
│ ┌──────────────────────────────────────────────────────────────────────┐ │
|
||
│ │ React Frontend │ │
|
||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||
│ │ │ 登录/授权 │ │ 发票上传 │ │ 结果确认 │ │ 历史记录 │ │ │
|
||
│ │ │ 页面 │ │ 页面 │ │ 页面 │ │ 页面 │ │ │
|
||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │
|
||
│ └──────────────────────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
│ HTTPS / REST API
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ 应用层 (Application Layer) │
|
||
│ ┌──────────────────────────────────────────────────────────────────────┐ │
|
||
│ │ ASP.NET Core Web API │ │
|
||
│ │ │ │
|
||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||
│ │ │ Controllers│ │ Minimal │ │ Filters │ │ Middleware│ │ │
|
||
│ │ │ │ │ APIs │ │ │ │ │ │ │
|
||
│ │ └──────┬──────┘ └──────┬──────┘ └─────────────┘ └─────────────┘ │ │
|
||
│ │ │ │ │ │
|
||
│ │ └────────────────┼──────────────────────────────────────────┘ │
|
||
│ │ │ │
|
||
│ │ ┌───────────────────────┴──────────────────────────────────────────┐ │ │
|
||
│ │ │ Application Layer (CQRS Lite) │ │ │
|
||
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
|
||
│ │ │ │ Commands │ │ Queries │ │ DTOs │ │ │ │
|
||
│ │ │ │ Handlers │ │ Handlers │ │ Mappers │ │ │ │
|
||
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │
|
||
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
|
||
│ │ │ │
|
||
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
|
||
│ │ │ Domain Layer (DDD Lite) │ │ │
|
||
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
|
||
│ │ │ │ Aggregates │ │ Domain │ │ Domain │ │ │ │
|
||
│ │ │ │ (Invoice) │ │ Events │ │ Services │ │ │ │
|
||
│ │ │ │ (Connection)│ │ │ │ │ │ │ │
|
||
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │
|
||
│ │ │ │ │ │
|
||
│ │ │ ┌─────────────────────────────────────────────────────────────┐│ │ │
|
||
│ │ │ │ Accounting System Integration Layer ││ │ │
|
||
│ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │ │
|
||
│ │ │ │ │ Abstract │ │ Fortnox │ │ Visma │ ... ││ │ │
|
||
│ │ │ │ │ Interface │──│ Provider │ │ Provider │ ││ │ │
|
||
│ │ │ │ │ │ │ │ │ │ ││ │ │
|
||
│ │ │ │ │ - Supplier │ │ - OAuth2 │ │ - OAuth2 │ ││ │ │
|
||
│ │ │ │ │ - Voucher │ │ - REST API │ │ - REST API │ ││ │ │
|
||
│ │ │ │ │ - Account │ │ - Webhooks │ │ - Webhooks │ ││ │ │
|
||
│ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ ││ │ │
|
||
│ │ │ │ ││ │ │
|
||
│ │ │ │ Factory: IAccountingSystemFactory.Create("fortnox") ││ │ │
|
||
│ │ │ └─────────────────────────────────────────────────────────────┘│ │ │
|
||
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
|
||
│ │ │ │
|
||
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
|
||
│ │ │ Infrastructure Layer │ │ │
|
||
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
|
||
│ │ │ │ EF Core │ │ Redis │ │ Blob │ │ │ │
|
||
│ │ │ │ Repository │ │ Cache │ │ Storage │ │ │ │
|
||
│ │ │ │ EventStore│ │ │ │ │ │ │ │
|
||
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │
|
||
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
|
||
│ └──────────────────────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
│ HTTP API
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ 外部服务层 (External Services) │
|
||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||
│ │ Invoice Master │ │ Fortnox │ │ Visma │ │
|
||
│ │ OCR API │ │ Platform │ │ Platform │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ │ - /api/v1/infer │ │ - OAuth2 Server │ │ - OAuth2 Server │ │
|
||
│ │ - YOLO + PaddleOCR │ │ - REST API │ │ - REST API │ │
|
||
│ │ - 94.8% accuracy │ │ - Supplier/Voucher │ │ - Supplier/Voucher │ │
|
||
│ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
│ SQL / Redis
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ 数据层 (Data Layer) │
|
||
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||
│ │ PostgreSQL │ │ Redis │ │ Azure Blob Storage │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ │ - Users │ │ - Token Cache │ │ - Invoice PDFs │ │
|
||
│ │ - Connections │ │ - Rate Limiting │ │ - Temporary Files │ │
|
||
│ │ - Invoices │ │ - Session Store │ │ │ │
|
||
│ │ - DomainEvents │ │ │ │ │ │
|
||
│ └──────────────────┘ └──────────────────┘ └──────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.2 分层架构详解
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Presentation Layer │
|
||
│ (Controllers / Minimal APIs) │
|
||
│ │
|
||
│ - Input validation (FluentValidation) │
|
||
│ - Authentication / Authorization │
|
||
│ - Response mapping │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Application Layer (CQRS Lite) │
|
||
│ │
|
||
│ Commands (Write): Queries (Read): │
|
||
│ - ImportInvoiceCommand - GetInvoiceQuery │
|
||
│ - CreateConnectionCommand - ListInvoicesQuery │
|
||
│ - UpdateSupplierCommand - GetConnectionQuery │
|
||
│ │
|
||
│ - MediatR for dispatching │
|
||
│ - AutoMapper for DTO mapping │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Domain Layer (DDD Lite) │
|
||
│ │
|
||
│ Aggregates: │
|
||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||
│ │ Invoice │ │ AccountingConnection│ SupplierCache │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ │ - Submit() │ │ - Connect() │ │ - Update() │ │
|
||
│ │ - Import() │ │ - Disconnect() │ │ - Expire() │ │
|
||
│ │ - Reject() │ │ - RefreshToken()│ │ │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ │ Domain Events: │ │ Domain Events: │ │ │ │
|
||
│ │ - InvoiceSubmitted│ - Connected │ │ │ │
|
||
│ │ - InvoiceImported │ - TokenRefreshed│ │ │ │
|
||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||
│ │
|
||
│ Domain Services: │
|
||
│ - InvoiceProcessingService │
|
||
│ - SupplierMatchingService │
|
||
│ - VoucherGenerationService │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Infrastructure Layer │
|
||
│ │
|
||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||
│ │ EF Core │ │ Event Store │ │ External APIs │ │
|
||
│ │ Repositories │ │ (Audit Table) │ │ │ │
|
||
│ │ │ │ │ │ - FortnoxClient │ │
|
||
│ │ - IRepository │ │ - Append events │ │ - VismaClient │ │
|
||
│ │ - Unit of Work │ │ - Replay events │ │ - OCRClient │ │
|
||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.3 会计系统集成层详解
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Accounting System Integration │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||
│ │ Abstract Interface │ │
|
||
│ │ (InvoiceMaster.Integrations/Accounting/IAccountingSystem.cs)│ │
|
||
│ │ │ │
|
||
│ │ public interface IAccountingSystem │ │
|
||
│ │ { │ │
|
||
│ │ string ProviderName { get; } │ │
|
||
│ │ Task<AuthResult> AuthenticateAsync(string code); │ │
|
||
│ │ Task<List<Supplier>> GetSuppliersAsync(); │ │
|
||
│ │ Task<Voucher> CreateVoucherAsync(Voucher voucher); │ │
|
||
│ │ // ... │ │
|
||
│ │ } │ │
|
||
│ └─────────────────────────────────────────────────────────────┘ │
|
||
│ ▲ │
|
||
│ │ implements │
|
||
│ ┌───────────────────┼───────────────────┐ │
|
||
│ │ │ │ │
|
||
│ ┌───────▼──────┐ ┌────────▼────────┐ ┌──────▼───────┐ │
|
||
│ │ Fortnox │ │ Visma │ │ Hogia │ ... │
|
||
│ │ Provider │ │ Provider │ │ Provider │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ │ - OAuth2 │ │ - OAuth2 │ │ - OAuth2 │ │
|
||
│ │ - Swedish │ │ - Nordic APIs │ │ - Swedish │ │
|
||
│ │ - BAS 2024 │ │ - Localized │ │ - Custom │ │
|
||
│ └──────────────┘ └─────────────────┘ └──────────────┘ │
|
||
│ │
|
||
│ Factory: IAccountingSystemFactory.Create(providerName: string) │
|
||
│ Registry: services.AddAccountingSystem<FortnoxProvider>("fortnox") │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.4 领域事件与审计
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Domain Event Flow │
|
||
│ │
|
||
│ 1. Domain Action │
|
||
│ Invoice.Import() called │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ 2. Event Raised │
|
||
│ _domainEvents.Add(new InvoiceImportedEvent { ... }) │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ 3. Transaction Commit │
|
||
│ EF Core SaveChangesAsync() │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ 4. Event Dispatcher │
|
||
│ DispatchDomainEventsInterceptor │
|
||
│ │ │
|
||
│ ├──────────────────┬──────────────────┐ │
|
||
│ ▼ ▼ ▼ │
|
||
│ 5. Handlers: Save to DB Send Notification │
|
||
│ - AuditLogHandler DomainEvents table - SignalR │
|
||
│ - NotificationHandler - Webhook │
|
||
│ - IntegrationHandler │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 技术栈选型
|
||
|
||
### 3.1 后端技术栈 (.NET 8)
|
||
|
||
| 技术 | 版本 | 用途 |
|
||
|------|------|------|
|
||
| .NET | 8.0 | 运行时和框架 |
|
||
| ASP.NET Core | 8.0 | Web API |
|
||
| Entity Framework Core | 8.0 | ORM |
|
||
| MediatR | 12.x | CQRS / 中介者模式 |
|
||
| AutoMapper | 12.x | 对象映射 |
|
||
| FluentValidation | 11.x | 输入验证 |
|
||
| FluentAssertions | 6.x | 测试断言 |
|
||
| xUnit | 2.x | 测试框架 |
|
||
| Moq | 4.x | Mocking |
|
||
| Serilog | 3.x | 结构化日志 |
|
||
| Polly | 8.x | 重试和熔断 |
|
||
| JWT Bearer | 8.x | 认证 |
|
||
| Swagger/OpenAPI | 6.x | API 文档 |
|
||
|
||
### 3.2 审计与事件存储
|
||
|
||
```csharp
|
||
// 领域事件基类
|
||
public abstract class DomainEvent
|
||
{
|
||
public Guid EventId { get; } = Guid.NewGuid();
|
||
public DateTime OccurredAt { get; } = DateTime.UtcNow;
|
||
public string EventType { get; protected set; }
|
||
public string AggregateType { get; set; }
|
||
public Guid AggregateId { get; set; }
|
||
public string UserId { get; set; }
|
||
public string CorrelationId { get; set; }
|
||
}
|
||
|
||
// 具体事件
|
||
public class InvoiceImportedEvent : DomainEvent
|
||
{
|
||
public string Provider { get; set; }
|
||
public string VoucherNumber { get; set; }
|
||
public decimal Amount { get; set; }
|
||
|
||
public InvoiceImportedEvent()
|
||
{
|
||
EventType = nameof(InvoiceImportedEvent);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.3 会计系统集成使用示例
|
||
|
||
```csharp
|
||
// 使用示例
|
||
public class ImportInvoiceCommandHandler : IRequestHandler<ImportInvoiceCommand, Result<InvoiceDto>>
|
||
{
|
||
private readonly IAccountingSystemFactory _factory;
|
||
private readonly IInvoiceRepository _invoiceRepository;
|
||
|
||
public async Task<Result<InvoiceDto>> Handle(
|
||
ImportInvoiceCommand request,
|
||
CancellationToken cancellationToken)
|
||
{
|
||
// 创建 Fortnox 连接
|
||
var accounting = _factory.Create("fortnox", connection.AccessToken);
|
||
|
||
// 创建 Visma 连接(未来)
|
||
// var accounting = _factory.Create("visma", connection.AccessToken);
|
||
|
||
// 统一接口,无需关心底层实现
|
||
var invoice = await _invoiceRepository.GetByIdAsync(request.InvoiceId);
|
||
|
||
// 执行业务逻辑
|
||
invoice.Import(request.Provider, request.UserId);
|
||
|
||
await _invoiceRepository.SaveChangesAsync();
|
||
|
||
// 领域事件自动保存到审计表
|
||
return Result.Success(_mapper.Map<InvoiceDto>(invoice));
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 数据模型变更
|
||
|
||
### 4.1 数据库表结构
|
||
|
||
**核心表:**
|
||
- `Users` - 用户表
|
||
- `AccountingConnections` - 通用会计系统连接表
|
||
- `Invoices` - 通用发票表
|
||
- `SupplierCaches` - 通用供应商缓存表
|
||
- `DomainEvents` - 领域事件表(审计)
|
||
|
||
```sql
|
||
-- 领域事件表(审计)
|
||
CREATE TABLE DomainEvents (
|
||
Id UUID PRIMARY KEY,
|
||
EventType VARCHAR(255) NOT NULL,
|
||
AggregateType VARCHAR(255) NOT NULL,
|
||
AggregateId UUID NOT NULL,
|
||
OccurredAt TIMESTAMP WITH TIME ZONE NOT NULL,
|
||
UserId VARCHAR(255),
|
||
CorrelationId VARCHAR(255),
|
||
Payload JSONB NOT NULL,
|
||
Processed BOOLEAN DEFAULT FALSE
|
||
);
|
||
|
||
CREATE INDEX IX_DomainEvents_Aggregate ON DomainEvents(AggregateType, AggregateId);
|
||
CREATE INDEX IX_DomainEvents_OccurredAt ON DomainEvents(OccurredAt DESC);
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 扩展性设计
|
||
|
||
### 5.1 添加新会计系统的步骤
|
||
|
||
1. **创建 Provider 类**
|
||
```csharp
|
||
// InvoiceMaster.Integrations/Accounting/Providers/VismaProvider.cs
|
||
public class VismaProvider : IAccountingSystem
|
||
{
|
||
public string ProviderName => "visma";
|
||
|
||
public async Task<AuthResult> AuthenticateAsync(string code)
|
||
{
|
||
// Visma OAuth2 实现
|
||
}
|
||
|
||
public async Task<List<Supplier>> GetSuppliersAsync()
|
||
{
|
||
// Visma API 实现
|
||
}
|
||
|
||
// ... 其他方法实现
|
||
}
|
||
```
|
||
|
||
2. **注册到 DI 容器**
|
||
```csharp
|
||
// Program.cs
|
||
builder.Services.AddAccountingSystem<VismaProvider>("visma");
|
||
```
|
||
|
||
3. **添加配置**
|
||
```json
|
||
{
|
||
"Visma": {
|
||
"ClientId": "xxx",
|
||
"ClientSecret": "xxx",
|
||
"RedirectUri": "..."
|
||
}
|
||
}
|
||
```
|
||
|
||
4. **完成** - 无需修改业务逻辑代码
|
||
|
||
### 5.2 未来支持的会计系统
|
||
|
||
| 会计系统 | 市场 | 优先级 | 预计工作量 |
|
||
|----------|------|--------|-----------|
|
||
| **Fortnox** | 瑞典 | P0 | 已完成 |
|
||
| **Visma eAccounting** | 北欧 | P1 | 2-3 周 |
|
||
| **Hogia Smart** | 瑞典 | P2 | 2-3 周 |
|
||
| **BjornLunden** | 瑞典 | P2 | 2-3 周 |
|
||
| **Sage** | 欧洲 | P3 | 3-4 周 |
|
||
| **QuickBooks** | 全球 | P3 | 3-4 周 |
|
||
|
||
---
|
||
|
||
## 6. API 设计变更
|
||
|
||
### 6.1 会计系统连接 API
|
||
|
||
```http
|
||
# 获取支持的会计系统列表
|
||
GET /api/v1/accounting/providers
|
||
|
||
# 获取特定会计系统的授权 URL
|
||
GET /api/v1/accounting/{provider}/auth/url
|
||
|
||
# OAuth 回调(通用)
|
||
GET /api/v1/accounting/{provider}/auth/callback?code=xxx&state=xxx
|
||
|
||
# 获取用户的所有连接
|
||
GET /api/v1/accounting/connections
|
||
|
||
# 断开特定会计系统连接
|
||
DELETE /api/v1/accounting/connections/{provider}
|
||
```
|
||
|
||
### 6.2 审计 API
|
||
|
||
```http
|
||
# 获取发票的审计日志
|
||
GET /api/v1/invoices/{id}/audit-log
|
||
|
||
# 获取用户的操作历史
|
||
GET /api/v1/users/me/audit-log
|
||
|
||
# 导出审计报告(管理员)
|
||
GET /api/v1/admin/audit-export?from=2026-01-01&to=2026-02-01
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 相关文档
|
||
|
||
- [API 设计文档](./API_DESIGN.md)
|
||
- [数据库 Schema](./DATABASE_SCHEMA.md)
|
||
- [开发计划](./DEVELOPMENT_PLAN.md)
|
||
- [部署指南](./DEPLOYMENT_GUIDE.md)
|
||
- [目录结构](./DIRECTORY_STRUCTURE.md)
|
||
|
||
---
|
||
|
||
**文档历史:**
|
||
|
||
| 版本 | 日期 | 作者 | 变更 |
|
||
|------|------|------|------|
|
||
| 3.0 | 2026-02-03 | Claude Code | 重构为 .NET + 轻量级 DDD |
|
||
| 2.0 | 2026-02-03 | Claude Code | 重构为多会计系统架构 |
|
||
| 1.0 | 2026-02-03 | Claude Code | 初始版本(仅 Fortnox) |
|