# 外卖SaaS系统 - 开发规范 ## 1. 代码规范 ### 1.1 命名规范 #### C#命名规范 ```csharp // 类名:PascalCase public class OrderService { } // 接口:I + PascalCase public interface IOrderRepository { } // 方法:PascalCase public async Task 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 /// /// 订单服务接口 /// public interface IOrderService { /// /// 创建订单 /// /// 订单创建请求 /// 订单信息 /// 业务异常 Task CreateOrderAsync(CreateOrderRequest request); } // 复杂业务逻辑添加注释 public async Task 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 _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 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类型: # 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 _logger; private readonly IOptions _settings; public async Task 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(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记录版本变更