12 KiB
Design Document: API Migration Remaining
Overview
本设计文档描述将剩余54个PHP API接口迁移到C# ASP.NET Core后端的技术方案。迁移遵循现有的Clean Architecture架构模式,复用已有的基础设施组件。
迁移流程
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 1. PHP源码分析 │ -> │ 2. SQL Server │ -> │ 3. 数据表创建 │ -> │ 4. C#代码实现 │
│ 查看控制器逻辑 │ │ 表结构验证 │ │ (如需要) │ │ Controller/ │
│ 理解业务流程 │ │ MCP查询 │ │ Entity/ │ │ Service │
└─────────────────┘ └─────────────────┘ │ Migration │ └─────────────────┘
└─────────────────┘
技术栈
- 后端框架: ASP.NET Core (.NET 10)
- ORM: Entity Framework Core 8.0
- 数据库: SQL Server
- 架构: Clean Architecture (Api/Core/Infrastructure/Model)
- 依赖注入: Autofac
- 认证: JWT Bearer
Architecture
项目结构
server/C#/HoneyBox/src/
├── HoneyBox.Api/ # Web API层
│ ├── Controllers/ # API控制器 (新增: AddressController, SignController等)
│ └── Filters/ # 过滤器
├── HoneyBox.Core/ # 业务逻辑层
│ ├── Services/ # 业务服务 (新增: AddressService, SignService等)
│ ├── Interfaces/ # 接口定义
│ └── Mappings/ # 对象映射配置
├── HoneyBox.Infrastructure/ # 基础设施层
│ ├── Cache/ # 缓存实现
│ └── External/ # 外部服务集成
└── HoneyBox.Model/ # 数据模型层
├── Entities/ # 数据库实体 (复用现有)
├── Models/ # DTO/ViewModel
└── Data/ # DbContext
PHP源码位置映射
| 模块 | PHP控制器路径 | C#控制器 |
|---|---|---|
| 地址 | server/php/app/api/controller/User.php |
AddressController.cs (新建) |
| 支付 | server/php/app/api/controller/Pay.php |
PayController.cs (扩展) |
| 签到 | server/php/app/api/controller/Sign.php |
SignController.cs (新建) |
| 福利屋 | server/php/app/api/controller/FuLiWu.php |
WelfareController.cs (扩展) |
| 商品 | server/php/app/api/controller/Goods.php |
GoodsController.cs (扩展) |
| 订单 | server/php/app/api/controller/Order.php |
OrderController.cs (扩展) |
| 优惠券 | server/php/app/api/controller/Coupon.php |
CouponController.cs (扩展) |
| 权益 | server/php/app/api/controller/QuanYi.php |
UserController.cs (扩展) |
| 收藏 | server/php/app/api/controller/Goods.php |
CollectionController.cs (扩展) |
| 排行榜 | server/php/app/api/controller/Rank.php |
RankController.cs (扩展) |
| 兑换码 | server/php/app/api/controller/Other.php |
RedeemController.cs (扩展) |
| 仓库 | server/php/app/api/controller/Warehouse.php |
WarehouseController.cs (扩展) |
| 认证 | server/php/app/api/controller/Login.php |
AuthController.cs (扩展) |
| 配置 | server/php/app/api/controller/Config.php |
ConfigController.cs (扩展) |
| 商城 | server/php/app/api/controller/Mall.php |
MallController.cs (新建) |
Components and Interfaces
新增控制器
AddressController
[ApiController]
[Route("api")]
[Authorize]
public class AddressController : ControllerBase
{
// POST /addAddress - 添加收货地址
// POST /updateAddress - 更新收货地址
// GET /getDefaultAddress - 获取默认地址
// GET /getAddressList - 获取地址列表
// POST /deleteAddress - 删除地址
// POST /setDefaultAddress - 设置默认地址
// GET /getAddressDetail - 获取地址详情
}
SignController
[ApiController]
[Route("api")]
[Authorize]
public class SignController : ControllerBase
{
// GET /sign_info - 获取签到信息
// POST /sign - 执行签到
// POST /sign_add - 执行签到(旧版)
}
MallController
[ApiController]
[Route("api")]
[Authorize]
public class MallController : ControllerBase
{
// GET /get_diamond_list - 获取钻石商品列表
// GET /createOrderProducts - 创建钻石订单
// GET /get_diamond_order_log - 获取订单状态
}
新增服务
IAddressService
public interface IAddressService
{
Task<UserAddress> AddAddressAsync(int userId, AddAddressRequest request);
Task<bool> UpdateAddressAsync(int userId, int addressId, UpdateAddressRequest request);
Task<UserAddress?> GetDefaultAddressAsync(int userId);
Task<List<UserAddress>> GetAddressListAsync(int userId);
Task<bool> DeleteAddressAsync(int userId, int addressId);
Task<bool> SetDefaultAddressAsync(int userId, int addressId);
Task<UserAddress?> GetAddressDetailAsync(int userId, int addressId);
}
ISignService
public interface ISignService
{
Task<SignInfoResponse> GetSignInfoAsync(int userId);
Task<SignResult> DoSignAsync(int userId);
Task<SignResult> DoSignAddAsync(int userId);
}
IMallService
public interface IMallService
{
Task<List<DiamondProduct>> GetDiamondListAsync();
Task<DiamondOrder> CreateOrderProductsAsync(int userId, CreateDiamondOrderRequest request);
Task<DiamondOrderStatus> GetDiamondOrderLogAsync(int userId, string orderNo);
}
Data Models
现有实体 (已存在于SQL Server)
以下实体已在 HoneyBox.Model/Entities/ 中定义:
UserAddress- 用户收货地址UserSign- 用户签到记录SignConfig- 签到配置DiamondProduct- 钻石商品DiamondOrder- 钻石订单UserRecharge- 用户充值记录UserItemCard- 用户道具卡RedeemCode- 兑换码
需要验证的数据表
迁移前需通过MCP SQL Server工具验证以下表是否存在:
-- 地址模块
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'user_address';
-- 签到模块
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'user_sign';
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sign_config';
-- 钻石商城
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'diamond_product';
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'diamond_order';
-- 权益模块
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'user_vip_reward';
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'vip_level_reward';
DTO模型
AddAddressRequest
public class AddAddressRequest
{
public string Name { get; set; } // 收货人姓名
public string Phone { get; set; } // 手机号
public string Province { get; set; } // 省
public string City { get; set; } // 市
public string District { get; set; } // 区
public string Address { get; set; } // 详细地址
public bool IsDefault { get; set; } // 是否默认
}
SignInfoResponse
public class SignInfoResponse
{
public bool IsSignedToday { get; set; } // 今日是否已签到
public int ContinuousDays { get; set; } // 连续签到天数
public int TotalDays { get; set; } // 累计签到天数
public List<SignReward> Rewards { get; set; } // 签到奖励配置
}
Correctness Properties
A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.
Property 1: 地址操作一致性
For any 用户和地址操作序列,添加地址后通过getAddressList应能查询到该地址,删除后应查询不到 Validates: Requirements 1.1, 1.4, 1.5
Property 2: 默认地址唯一性
For any 用户,设置某地址为默认后,该用户只能有一个默认地址,其他地址的默认标记应为false Validates: Requirements 1.3, 1.6
Property 3: 余额支付扣减正确性
For any 余额支付操作,支付后用户余额应等于支付前余额减去支付金额 Validates: Requirements 2.2
Property 4: 签到幂等性
For any 用户在同一天内多次调用签到接口,只有第一次应成功,后续调用应返回已签到状态 Validates: Requirements 3.1, 3.2
Property 5: 签到连续天数计算
For any 用户签到序列,连续签到天数应正确反映实际连续签到情况 Validates: Requirements 3.1
Property 6: 福利屋积分扣减
For any 福利屋购买操作,购买后用户积分应等于购买前积分减去消耗积分 Validates: Requirements 4.2
Property 7: 收藏状态一致性
For any 商品收藏操作,添加收藏后collect_status应返回已收藏,取消后应返回未收藏 Validates: Requirements 9.1, 9.2, 9.3
Property 8: 兑换码使用唯一性
For any 兑换码,使用后不能再次使用,应返回已使用错误 Validates: Requirements 11.1
Property 9: 保险柜移入移出一致性
For any 奖品,移入保险柜后应在保险柜列表中可见,移出后应不在保险柜列表中 Validates: Requirements 12.1, 12.2
Error Handling
通用错误码
| 错误码 | 说明 |
|---|---|
| 400 | 请求参数错误 |
| 401 | 未授权/Token无效 |
| 403 | 权限不足 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
业务错误码
| 错误码 | 说明 |
|---|---|
| 1001 | 地址不存在 |
| 1002 | 地址数量超过限制 |
| 2001 | 余额不足 |
| 2002 | 支付订单不存在 |
| 3001 | 今日已签到 |
| 3002 | 签到配置不存在 |
| 4001 | 积分不足 |
| 4002 | 福利屋活动已结束 |
| 5001 | 兑换码无效 |
| 5002 | 兑换码已使用 |
响应格式
{
"code": 0,
"msg": "success",
"data": { ... }
}
错误响应:
{
"code": 1001,
"msg": "地址不存在",
"data": null
}
Testing Strategy
单元测试
- 使用 xUnit 作为测试框架
- 使用 Moq 进行依赖模拟
- 测试覆盖所有Service方法
- 测试边界条件和异常情况
属性测试
- 使用 FsCheck 进行属性测试
- 每个属性测试运行100次迭代
- 测试标签格式: Feature: api-migration-remaining, Property {number}: {property_text}
集成测试
- 使用 WebApplicationFactory 进行API集成测试
- 使用内存数据库进行测试隔离
- 测试完整的请求-响应流程
测试文件结构
server/C#/HoneyBox/tests/
├── HoneyBox.Api.Tests/
│ ├── Controllers/
│ │ ├── AddressControllerTests.cs
│ │ ├── SignControllerTests.cs
│ │ └── MallControllerTests.cs
│ └── Integration/
│ └── ApiIntegrationTests.cs
└── HoneyBox.Core.Tests/
└── Services/
├── AddressServiceTests.cs
├── SignServiceTests.cs
└── MallServiceTests.cs
Migration Checklist
每个接口迁移需完成以下步骤:
- 1. 在PHP源码中找到对应控制器方法
- 2. 分析业务逻辑和数据库操作
- 3. 使用MCP查询SQL Server表结构
- 4. 如缺少表,创建Entity和Migration
- 5. 实现Service层业务逻辑
- 6. 实现Controller层API端点
- 7. 添加DTO映射配置
- 8. 编写单元测试
- 9. 进行API测试验证
- 10. 更新API接口清单状态