376 lines
12 KiB
Markdown
376 lines
12 KiB
Markdown
# Design Document: 用户管理系统迁移
|
||
|
||
## Overview
|
||
|
||
本设计文档描述了用户管理系统从PHP迁移到.NET 8的技术方案。系统包括用户资产管理、VIP等级、优惠券、任务、推荐关系、排行榜、兑换码和福利屋等模块。
|
||
|
||
## Architecture
|
||
|
||
### 系统架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ API Layer │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐│
|
||
│ │UserController│ │CouponController│ │WelfareController ││
|
||
│ └─────────────┘ └─────────────┘ └─────────────────────────┘│
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Service Layer │
|
||
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────────┐ │
|
||
│ │IAssetService │ │ICouponService │ │IWelfareService │ │
|
||
│ │IVipService │ │ITaskService │ │IRankService │ │
|
||
│ │IInvitationSvc │ │IRedeemService │ │
|
||
│ └───────────────┘ └───────────────┘ └───────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Data Layer │
|
||
│ ┌───────────────────────────────────────────────────────┐ │
|
||
│ │ HoneyBoxDbContext │ │
|
||
│ │ ProfitMoney | ProfitIntegral | ProfitMoney2 │ │
|
||
│ │ UserCoupon | TaskList | UserTaskList │ │
|
||
│ │ UserVip | Order | OrderList | Goods | GoodsList │ │
|
||
│ └───────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Components and Interfaces
|
||
|
||
### 1. 资产服务接口 (IAssetService)
|
||
|
||
```csharp
|
||
public interface IAssetService
|
||
{
|
||
// 余额明细查询
|
||
Task<PagedResult<AssetRecordDto>> GetMoneyRecordsAsync(int userId, int type, int page, int limit = 15);
|
||
|
||
// 吧唧币明细查询
|
||
Task<PagedResult<AssetRecordDto>> GetIntegralRecordsAsync(int userId, int type, int page, int limit = 15);
|
||
|
||
// 积分明细查询
|
||
Task<PagedResult<AssetRecordDto>> GetScoreRecordsAsync(int userId, int type, int page, int limit = 15);
|
||
|
||
// 支付记录查询
|
||
Task<PagedResult<AssetRecordDto>> GetPayRecordsAsync(int userId, int page, int limit = 15);
|
||
}
|
||
```
|
||
|
||
### 2. VIP服务接口 (IVipService)
|
||
|
||
```csharp
|
||
public interface IVipService
|
||
{
|
||
// 获取VIP信息
|
||
Task<VipInfoResponse> GetVipInfoAsync(int userId);
|
||
|
||
// 计算VIP等级
|
||
Task<int> CalculateVipLevelAsync(int userId, int currentVip);
|
||
|
||
// 获取VIP等级列表
|
||
Task<List<VipLevelDto>> GetVipLevelsAsync();
|
||
}
|
||
```
|
||
|
||
### 3. 优惠券服务接口 (ICouponService)
|
||
|
||
```csharp
|
||
public interface ICouponService
|
||
{
|
||
// 获取优惠券列表
|
||
Task<CouponListResponse> GetCouponListAsync(int userId, int status, int page, int limit = 15);
|
||
|
||
// 获取优惠券详情
|
||
Task<CouponDetailDto> GetCouponDetailAsync(int userId, int couponId);
|
||
|
||
// 分享优惠券
|
||
Task<bool> ShareCouponAsync(int userId, int couponId);
|
||
|
||
// 领取优惠券
|
||
Task<bool> ClaimCouponAsync(int userId, int couponId);
|
||
|
||
// 计算合成
|
||
Task<SynthesisCalculateResult> CalculateSynthesisAsync(int userId, string couponIds);
|
||
|
||
// 执行合成
|
||
Task<bool> SynthesisCouponsAsync(int userId, string couponIds);
|
||
}
|
||
```
|
||
|
||
### 4. 任务服务接口 (ITaskService)
|
||
|
||
```csharp
|
||
public interface ITaskService
|
||
{
|
||
// 获取任务列表
|
||
Task<TaskListResponse> GetTaskListAsync(int userId, int type);
|
||
|
||
// 领取任务奖励
|
||
Task<bool> ClaimTaskRewardAsync(int userId, int taskListId);
|
||
}
|
||
```
|
||
|
||
### 5. 推荐服务接口 (IInvitationService)
|
||
|
||
```csharp
|
||
public interface IInvitationService
|
||
{
|
||
// 获取推荐信息
|
||
Task<InvitationInfoResponse> GetInvitationInfoAsync(int userId, int page);
|
||
|
||
// 绑定邀请码
|
||
Task<bool> BindInviteCodeAsync(int userId, string inviteCode);
|
||
}
|
||
```
|
||
|
||
### 6. 排行榜服务接口 (IRankService)
|
||
|
||
```csharp
|
||
public interface IRankService
|
||
{
|
||
// 获取周榜
|
||
Task<RankResponse> GetWeekRankAsync(int userId);
|
||
|
||
// 获取月榜
|
||
Task<RankResponse> GetMonthRankAsync(int userId);
|
||
}
|
||
```
|
||
|
||
### 7. 兑换码服务接口 (IRedeemService)
|
||
|
||
```csharp
|
||
public interface IRedeemService
|
||
{
|
||
// 使用兑换码
|
||
Task<RedeemResult> UseRedeemCodeAsync(int userId, string code);
|
||
}
|
||
```
|
||
|
||
### 8. 福利屋服务接口 (IWelfareService)
|
||
|
||
```csharp
|
||
public interface IWelfareService
|
||
{
|
||
// 获取福利屋列表
|
||
Task<PagedResult<WelfareItemDto>> GetWelfareListAsync(int userId, int type, int page, int limit = 15);
|
||
|
||
// 获取福利屋详情
|
||
Task<WelfareDetailResponse> GetWelfareDetailAsync(int userId, int goodsId);
|
||
|
||
// 获取参与者列表
|
||
Task<List<ParticipantDto>> GetParticipantsAsync(int goodsId);
|
||
|
||
// 获取开奖记录
|
||
Task<List<WinningRecordDto>> GetWinningRecordsAsync(int goodsId);
|
||
|
||
// 获取用户参与记录
|
||
Task<List<UserParticipationDto>> GetUserParticipationRecordsAsync(int userId);
|
||
|
||
// 获取用户中奖记录
|
||
Task<List<UserWinningDto>> GetUserWinningRecordsAsync(int userId);
|
||
}
|
||
```
|
||
|
||
## Data Models
|
||
|
||
### 资产记录DTO
|
||
|
||
```csharp
|
||
public class AssetRecordDto
|
||
{
|
||
public string ChangeMoney { get; set; }
|
||
public string Content { get; set; }
|
||
public string AddTime { get; set; }
|
||
}
|
||
```
|
||
|
||
### VIP信息响应
|
||
|
||
```csharp
|
||
public class VipInfoResponse
|
||
{
|
||
public VipUserInfoDto Userinfo { get; set; }
|
||
public List<VipLevelDto> Data { get; set; }
|
||
}
|
||
|
||
public class VipUserInfoDto
|
||
{
|
||
public string Nickname { get; set; }
|
||
public string Headimg { get; set; }
|
||
public int Vip { get; set; }
|
||
public string UpgradeMoney { get; set; }
|
||
public int LastVip { get; set; }
|
||
public decimal JinDu { get; set; }
|
||
public string Notice { get; set; }
|
||
}
|
||
```
|
||
|
||
### 优惠券DTO
|
||
|
||
```csharp
|
||
public class CouponDto
|
||
{
|
||
public int Id { get; set; }
|
||
public int Status { get; set; }
|
||
public int Level { get; set; }
|
||
public string LevelText { get; set; }
|
||
public string LevelImg { get; set; }
|
||
public string Title { get; set; }
|
||
public string Num { get; set; }
|
||
public int KlNum { get; set; }
|
||
public int KlNum2 { get; set; }
|
||
public int YiLing { get; set; }
|
||
}
|
||
```
|
||
|
||
### 任务DTO
|
||
|
||
```csharp
|
||
public class TaskDto
|
||
{
|
||
public int Id { get; set; }
|
||
public int Type { get; set; }
|
||
public int Cate { get; set; }
|
||
public string Title { get; set; }
|
||
public int Number { get; set; }
|
||
public int ZNumber { get; set; }
|
||
public int IsComplete { get; set; }
|
||
public int Percentage { get; set; }
|
||
public int YwcCount { get; set; }
|
||
}
|
||
```
|
||
|
||
### 排行榜DTO
|
||
|
||
```csharp
|
||
public class RankItemDto
|
||
{
|
||
public int Rank { get; set; }
|
||
public int UserId { get; set; }
|
||
public string Nickname { get; set; }
|
||
public string Headimg { get; set; }
|
||
public decimal OrderTotal { get; set; }
|
||
public string PrizeTitle { get; set; }
|
||
public string PrizeImgurl { 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* asset record query with pagination, the returned last_page value SHALL correctly reflect the total number of pages based on total records and page size.
|
||
|
||
**Validates: Requirements 1.1, 1.2, 1.3, 1.4, 1.6**
|
||
|
||
### Property 2: VIP等级计算正确性
|
||
|
||
*For any* user with total consumption amount X, the calculated VIP level SHALL be the highest level whose condition is less than or equal to X.
|
||
|
||
**Validates: Requirements 2.1, 2.2**
|
||
|
||
### Property 3: VIP升级进度计算
|
||
|
||
*For any* user not at maximum VIP level, the upgrade progress percentage SHALL equal (current_consumption / next_level_threshold) * 100.
|
||
|
||
**Validates: Requirements 2.4**
|
||
|
||
### Property 4: 优惠券等级映射
|
||
|
||
*For any* coupon with level L, the level_text and level_img SHALL correctly map to: 1=特级赏券, 2=终极赏券, 3=高级赏券, 4=普通赏券.
|
||
|
||
**Validates: Requirements 3.3**
|
||
|
||
### Property 5: 优惠券领取随机金额
|
||
|
||
*For any* coupon claim, the random amount SHALL be between minimum (1) and remaining pool, and the sum of all claimed amounts SHALL not exceed the original coupon value.
|
||
|
||
**Validates: Requirements 6.1**
|
||
|
||
### Property 6: 优惠券合成损耗
|
||
|
||
*For any* coupon synthesis, the new coupon value SHALL equal sum of original values minus 10% loss.
|
||
|
||
**Validates: Requirements 7.2**
|
||
|
||
### Property 7: 任务周期计算
|
||
|
||
*For any* daily task, the progress SHALL only count activities within current day (00:00:00 to 23:59:59).
|
||
*For any* weekly task, the progress SHALL only count activities within current week (Monday 00:00:00 to Sunday 23:59:59).
|
||
|
||
**Validates: Requirements 8.2, 8.3**
|
||
|
||
### Property 8: 排行榜排序正确性
|
||
|
||
*For any* ranking query, the returned list SHALL be sorted by consumption amount in descending order, with ties broken by user_id in ascending order.
|
||
|
||
**Validates: Requirements 10.1, 10.2**
|
||
|
||
### Property 9: 福利屋解锁金额验证
|
||
|
||
*For any* welfare house with unlock_amount > 0, only users whose total consumption >= unlock_amount SHALL be able to view the activity.
|
||
|
||
**Validates: Requirements 12.3, 13.1**
|
||
|
||
## Error Handling
|
||
|
||
### 通用错误处理
|
||
|
||
| 错误场景 | 错误码 | 错误消息 |
|
||
|---------|--------|---------|
|
||
| 参数缺失 | 0 | 缺少必要参数 |
|
||
| 数据不存在 | 0 | 数据不存在/参数错误 |
|
||
| 未授权 | -1 | 请先登录 |
|
||
| 业务限制 | 2222 | 具体业务提示 |
|
||
|
||
### 优惠券特殊错误
|
||
|
||
| 错误场景 | 错误码 | 错误消息 |
|
||
|---------|--------|---------|
|
||
| 领取自己的券 | 2222 | 请勿开启自己的劵 |
|
||
| 已领取过 | 2222 | 你已经领取过了 |
|
||
| 已被领完 | 2222 | 来晚了, 已经被人领完了 |
|
||
| 达到每日上限 | 0 | 每天最多领取N次 |
|
||
| 特级/终极券不能合成 | 0 | 特级,终极赏券不能合成 |
|
||
| 超过合成数量限制 | 0 | 最多只能20个合成 |
|
||
|
||
## Testing Strategy
|
||
|
||
### 单元测试
|
||
|
||
- 测试各服务的核心业务逻辑
|
||
- 测试边界条件和错误处理
|
||
- 使用Mock隔离外部依赖
|
||
|
||
### 属性测试
|
||
|
||
使用FsCheck进行属性测试,验证以下属性:
|
||
- VIP等级计算正确性
|
||
- 优惠券合成损耗计算
|
||
- 任务周期边界计算
|
||
- 排行榜排序正确性
|
||
|
||
### 集成测试
|
||
|
||
- 测试完整的API请求响应流程
|
||
- 测试数据库事务一致性
|
||
- 测试Redis缓存行为
|
||
|
||
### 测试配置
|
||
|
||
```csharp
|
||
// 属性测试配置
|
||
[Property(MaxTest = 100)]
|
||
public Property VipLevelCalculation_ShouldBeCorrect()
|
||
{
|
||
return Prop.ForAll<decimal>(consumption =>
|
||
{
|
||
var level = CalculateVipLevel(consumption);
|
||
// 验证等级正确性
|
||
});
|
||
}
|
||
```
|