Files
TakeoutSaaS.Docs/Document/06_开发规范.md
2026-01-29 01:58:15 +00:00

395 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 外卖SaaS系统 - 开发规范
## 1. 代码规范
### 1.1 命名规范
#### C#命名规范
```csharp
// 类名PascalCase
public class OrderService { }
// 接口I + PascalCase
public interface IOrderRepository { }
// 方法PascalCase
public async Task<Order> CreateOrderAsync() { }
// 私有字段_camelCase
private readonly IOrderRepository _orderRepository;
// 公共属性PascalCase
public string OrderNo { get; set; }
// 局部变量camelCase
var orderTotal = 100.00m;
// 常量PascalCase
public const int MaxOrderItems = 50;
// 枚举PascalCase
public enum OrderStatus
{
Pending = 1,
Confirmed = 2,
Completed = 3
}
```
#### 数据库命名规范
```sql
-- 表名:小写,下划线分隔,复数
orders
order_items
merchant_stores
-- 字段名:小写,下划线分隔
order_no
created_at
total_amount
-- 索引idx_表名_字段名
idx_orders_merchant_id
idx_orders_created_at
-- 外键fk_表名_引用表名
fk_orders_merchants
```
### 1.2 代码组织
#### 项目结构
```
TakeoutSaaS/
├── src/
│ ├── TakeoutSaaS.Api/ # Web API层
│ │ ├── Controllers/ # 控制器
│ │ ├── Filters/ # 过滤器
│ │ ├── Middleware/ # 中间件
│ │ ├── Models/ # DTO模型
│ │ └── Program.cs
│ ├── TakeoutSaaS.Application/ # 应用层
│ │ ├── Services/ # 应用服务
│ │ ├── DTOs/ # 数据传输对象
│ │ ├── Interfaces/ # 服务接口
│ │ ├── Validators/ # 验证器
│ │ ├── Mappings/ # 对象映射
│ │ └── Commands/ # CQRS命令
│ │ └── Queries/ # CQRS查询
│ ├── TakeoutSaaS.Domain/ # 领域层
│ │ ├── Entities/ # 实体
│ │ ├── ValueObjects/ # 值对象
│ │ ├── Enums/ # 枚举
│ │ ├── Events/ # 领域事件
│ │ └── Interfaces/ # 仓储接口
│ ├── TakeoutSaaS.Infrastructure/ # 基础设施层
│ │ ├── Data/ # 数据访问
│ │ │ ├── EFCore/ # EF Core实现
│ │ │ ├── Dapper/ # Dapper实现
│ │ │ └── Repositories/ # 仓储实现
│ │ ├── Cache/ # 缓存实现
│ │ ├── MessageQueue/ # 消息队列
│ │ └── ExternalServices/ # 外部服务
│ └── TakeoutSaaS.Shared/ # 共享层
│ ├── Constants/ # 常量
│ ├── Exceptions/ # 异常
│ ├── Extensions/ # 扩展方法
│ └── Results/ # 统一返回结果
├── tests/
│ ├── TakeoutSaaS.UnitTests/ # 单元测试
│ ├── TakeoutSaaS.IntegrationTests/ # 集成测试
│ └── TakeoutSaaS.PerformanceTests/ # 性能测试
└── docs/ # 文档
```
### 1.3 代码注释
```csharp
/// <summary>
/// 订单服务接口
/// </summary>
public interface IOrderService
{
/// <summary>
/// 创建订单
/// </summary>
/// <param name="request">订单创建请求</param>
/// <returns>订单信息</returns>
/// <exception cref="BusinessException">业务异常</exception>
Task<OrderDto> CreateOrderAsync(CreateOrderRequest request);
}
// 复杂业务逻辑添加注释
public async Task<decimal> CalculateOrderAmount(Order order)
{
// 1. 计算菜品总金额
var dishAmount = order.Items.Sum(x => x.Price * x.Quantity);
// 2. 计算配送费(距离 > 3km每公里加收2元
var deliveryFee = CalculateDeliveryFee(order.Distance);
// 3. 应用优惠券折扣
var discount = await ApplyCouponDiscountAsync(order.CouponId, dishAmount);
// 4. 计算最终金额
return dishAmount + deliveryFee - discount;
}
```
### 1.4 异常处理
```csharp
// 自定义业务异常
public class BusinessException : Exception
{
public int ErrorCode { get; }
public BusinessException(int errorCode, string message)
: base(message)
{
ErrorCode = errorCode;
}
}
// 全局异常处理中间件
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "业务异常:{Message}", ex.Message);
await HandleBusinessExceptionAsync(context, ex);
}
catch (Exception ex)
{
_logger.LogError(ex, "系统异常:{Message}", ex.Message);
await HandleSystemExceptionAsync(context, ex);
}
}
private static Task HandleBusinessExceptionAsync(HttpContext context, BusinessException ex)
{
context.Response.StatusCode = StatusCodes.Status422UnprocessableEntity;
return context.Response.WriteAsJsonAsync(new
{
success = false,
code = ex.ErrorCode,
message = ex.Message
});
}
}
// 使用示例
public async Task<Order> GetOrderAsync(Guid orderId)
{
var order = await _orderRepository.GetByIdAsync(orderId);
if (order == null)
{
throw new BusinessException(404, "订单不存在");
}
return order;
}
```
## 2. Git工作流
### 2.1 分支管理
```
main # 主分支,生产环境代码
├── develop # 开发分支
│ ├── feature/order-management # 功能分支
│ ├── feature/payment-integration # 功能分支
│ └── bugfix/order-calculation # 修复分支
└── hotfix/critical-bug # 紧急修复分支
```
### 2.2 分支命名规范
- **功能分支**`feature/功能名称`(如:`feature/order-management`
- **修复分支**`bugfix/问题描述`(如:`bugfix/order-calculation`
- **紧急修复**`hotfix/问题描述`(如:`hotfix/payment-error`
- **发布分支**`release/版本号`(如:`release/v1.0.0`
### 2.3 提交信息规范
```bash
# 格式:<type>(<scope>): <subject>
# type类型
# feat: 新功能
# fix: 修复bug
# docs: 文档更新
# style: 代码格式调整
# refactor: 重构
# perf: 性能优化
# test: 测试相关
# chore: 构建/工具相关
# 示例
git commit -m "feat(order): 添加订单创建功能"
git commit -m "fix(payment): 修复支付回调处理错误"
git commit -m "docs(api): 更新API文档"
git commit -m "refactor(service): 重构订单服务"
```
### 2.4 工作流程
```bash
# 1. 从develop创建功能分支
git checkout develop
git pull origin develop
git checkout -b feature/order-management
# 2. 开发并提交
git add .
git commit -m "feat(order): 添加订单创建功能"
# 3. 推送到远程
git push origin feature/order-management
# 4. 创建Pull Request到develop分支
# 5. 代码审查通过后合并
# 6. 删除功能分支
git branch -d feature/order-management
git push origin --delete feature/order-management
```
## 3. 代码审查
### 3.1 审查清单
- [ ] 代码符合命名规范
- [ ] 代码逻辑清晰,易于理解
- [ ] 适当的注释和文档
- [ ] 异常处理完善
- [ ] 单元测试覆盖
- [ ] 性能考虑N+1查询、大数据量处理
- [ ] 安全性考虑SQL注入、XSS、权限校验
- [ ] 日志记录完善
- [ ] 无硬编码配置
- [ ] 符合SOLID原则
### 3.2 审查重点
```csharp
// ❌ 不好的实践
public class OrderService
{
public Order CreateOrder(CreateOrderRequest request)
{
// 直接在服务层操作DbContext
var order = new Order();
_dbContext.Orders.Add(order);
_dbContext.SaveChanges();
// 硬编码配置
var deliveryFee = 5.0m;
// 没有异常处理
// 没有日志记录
return order;
}
}
// ✅ 好的实践
public class OrderService : IOrderService
{
private readonly IOrderRepository _orderRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly ILogger<OrderService> _logger;
private readonly IOptions<OrderSettings> _settings;
public async Task<OrderDto> CreateOrderAsync(CreateOrderRequest request)
{
try
{
// 参数验证
if (request == null)
throw new ArgumentNullException(nameof(request));
_logger.LogInformation("创建订单:{@Request}", request);
// 业务逻辑
var order = new Order
{
// ... 初始化订单
DeliveryFee = _settings.Value.DefaultDeliveryFee
};
// 使用仓储
await _orderRepository.AddAsync(order);
await _unitOfWork.SaveChangesAsync();
_logger.LogInformation("订单创建成功:{OrderId}", order.Id);
return _mapper.Map<OrderDto>(order);
}
catch (Exception ex)
{
_logger.LogError(ex, "创建订单失败:{@Request}", request);
throw;
}
}
}
```
## 4. 单元测试规范
### 4.1 测试命名
- 命名格式:`MethodName_Scenario_ExpectedResult`
- 测试覆盖率要求:核心业务逻辑 >= 80%
### 4.2 测试示例
```csharp
[Fact]
public async Task CreateOrder_ValidRequest_ReturnsOrderDto()
{
// Arrange
var request = new CreateOrderRequest { /* ... */ };
// Act
var result = await _orderService.CreateOrderAsync(request);
// Assert
result.Should().NotBeNull();
result.OrderNo.Should().NotBeNullOrEmpty();
}
```
## 5. 性能优化规范
### 5.1 数据库查询优化
- 避免N+1查询使用Include预加载
- 大数据量查询使用Dapper
- 合理使用索引
### 5.2 缓存策略
- 商家信息30分钟
- 菜品信息15分钟
- 配置信息1小时
- 用户会话2小时
## 6. 文档要求
### 6.1 代码文档
- 所有公共API必须有XML文档注释
- 复杂业务逻辑添加详细注释
- README.md说明项目结构和运行方式
### 6.2 变更日志
维护CHANGELOG.md记录版本变更