16 KiB
16 KiB
阶段4:商品系统
阶段概述
时间: 3周
目标: 实现完整的商品管理系统,包括商品列表、详情、分类、库存管理、收藏等功能
优先级: P1 (高优先级)
详细任务清单
4.1 商品基础数据模型 (3天)
任务描述
设计和实现商品相关的数据模型和基础服务
具体工作
- 设计商品主表数据模型
- 设计商品列表(奖品)数据模型
- 设计商品分类数据模型
- 设计商品扩展配置模型
- 实现基础的商品服务接口
数据模型设计
// 商品主表
public class Goods
{
public int Id { get; set; }
public string Title { get; set; }
public string ImgUrl { get; set; }
public string ImgUrlDetail { get; set; }
public decimal Price { get; set; }
public int Type { get; set; }
public int Stock { get; set; }
public int SaleStock { get; set; }
public int Status { get; set; }
public int LockIs { get; set; }
public int IsShouZhe { get; set; }
public int NewIs { get; set; }
public decimal UnlockAmount { get; set; }
public int QuanjuXiangou { get; set; }
public int DailyXiangou { get; set; }
public DateTime? SaleTime { get; set; }
public int Sort { get; set; }
public DateTime AddTime { get; set; }
}
// 商品奖品列表
public class GoodsList
{
public int Id { get; set; }
public int GoodsId { get; set; }
public int Num { get; set; }
public int ShangId { get; set; }
public string Title { get; set; }
public int Stock { get; set; }
public int SurplusStock { get; set; }
public string ImgUrl { get; set; }
public int GoodsType { get; set; }
public decimal Price { get; set; }
public decimal ScMoney { get; set; }
public decimal RealPro { get; set; }
public int GoodsListId { get; set; }
public DateTime? SaleTime { get; set; }
public int Sort { get; set; }
}
// 商品类型配置
public class GoodsType
{
public int Id { get; set; }
public int Value { get; set; }
public string CornerText { get; set; }
public int PayWechat { get; set; }
public int PayBalance { get; set; }
public int PayCurrency { get; set; }
public int PayCurrency2 { get; set; }
public int PayCoupon { get; set; }
public int IsDeduction { get; set; }
}
// 商品扩展配置
public class GoodsExtend
{
public int Id { get; set; }
public int GoodsId { get; set; }
public int PayWechat { get; set; }
public int PayBalance { get; set; }
public int PayCurrency { get; set; }
public int PayCurrency2 { get; set; }
public int PayCoupon { get; set; }
public int IsDeduction { get; set; }
}
4.2 商品列表查询 (4天)
任务描述
实现商品列表查询功能,支持分类筛选、分页、缓存等
具体工作
- 实现商品列表查询接口
- 实现分类筛选功能
- 实现商品状态过滤
- 添加Redis缓存机制
- 实现参与次数统计
核心接口实现
商品列表接口
GET /api/v1/goods
Authorization: Bearer {token}
Query Parameters:
- type: 商品类型 (-1=全部, 1=一番赏, 2=无限赏, 3=擂台赏, 5=积分赏, 6=全局赏, 7=福利盲盒, 8=领主赏, 9=连击赏, 10=商品赏, 11=其他, 12=其他, 15=其他, 16=其他)
- page: 页码,默认1
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"data": [
{
"id": 123,
"title": "商品标题",
"imgurl": "https://example.com/goods.jpg",
"price": "10.00",
"type": 1,
"type_text": "一番赏",
"stock": 100,
"sale_stock": 80,
"status": 1,
"lock_is": 0,
"is_shou_zhe": 0,
"new_is": 1,
"join_count": 150,
"need_draw_num": 0
}
],
"last_page": 5
}
}
技术实现要点
// 商品服务接口
public interface IGoodsService
{
Task<PagedResult<GoodsListDto>> GetGoodsListAsync(GoodsQueryDto query, int userId);
Task<GoodsDetailDto> GetGoodsDetailAsync(int goodsId, int goodsNum, int userId);
Task<List<GoodsChildrenDto>> GetGoodsChildrenAsync(int goodsId, int goodsNum, int goodsListId);
}
// 商品查询DTO
public class GoodsQueryDto
{
public int Type { get; set; } = -1;
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 15;
}
// 商品列表DTO
public class GoodsListDto
{
public int Id { get; set; }
public string Title { get; set; }
public string ImgUrl { get; set; }
public decimal Price { get; set; }
public int Type { get; set; }
public string TypeText { get; set; }
public int Stock { get; set; }
public int SaleStock { get; set; }
public int Status { get; set; }
public int LockIs { get; set; }
public int IsShouZhe { get; set; }
public int NewIs { get; set; }
public int JoinCount { get; set; }
public int NeedDrawNum { get; set; }
}
4.3 商品详情查询 (4天)
任务描述
实现商品详情查询功能,包括奖品列表、概率计算、锁箱信息等
具体工作
- 实现商品详情查询接口
- 实现奖品列表查询
- 实现概率计算逻辑
- 实现锁箱状态查询
- 实现参与用户统计
核心接口实现
商品详情接口
GET /api/v1/goods/{goodsId}/detail
Authorization: Bearer {token}
Query Parameters:
- goods_num: 箱号,默认0(自动选择)
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"goods": {
"id": 123,
"title": "商品标题",
"imgurl_detail": "https://example.com/detail.jpg",
"price": "10.00",
"type": 1,
"type_text": "一番赏",
"stock": 100,
"sale_stock": 80,
"surplus_stock": 20,
"goodslist_stock": 100,
"goodslist_surplus_stock": 20,
"lock_is": 0,
"status": 1,
"addtime": "01-15",
"num": 1,
"collection_is": 0,
"three_time": 3,
"five_time": 5
},
"lock_info": {
"lock_is": 0,
"goods_lock_user_nickname": "",
"goods_lock_user_headimg": "",
"goods_lock_surplus_time": 0
},
"join_user": [
"https://example.com/avatar1.jpg",
"https://example.com/avatar2.jpg"
],
"join_count": 150,
"goodslist": [
{
"id": 456,
"shang_id": 10,
"shang_info": {
"id": 10,
"title": "A赏",
"color": "#FF0000"
},
"title": "奖品标题",
"stock": 10,
"surplus_stock": 5,
"imgurl": "https://example.com/prize.jpg",
"goods_type": 1,
"price": "100.00",
"sc_money": "0.00",
"sale_time": "2024-01-15",
"pro": "概率:10%",
"children": false
}
],
"limitInfo": {
"canPurchase": true,
"dailyLimit": 10,
"dailyUsed": 3,
"globalLimit": 100,
"globalUsed": 50
}
}
}
商品子奖品接口
GET /api/v1/goods/{goodsId}/children
Authorization: Bearer {token}
Query Parameters:
- goods_num: 箱号
- goods_list_id: 父奖品ID
Response:
{
"status": 1,
"msg": "请求成功",
"data": [
{
"id": 789,
"shang_id": 38,
"title": "子奖品",
"stock": 5,
"surplus_stock": 3,
"imgurl": "https://example.com/child_prize.jpg",
"goods_type": 1,
"price": "50.00",
"real_pro": 20.5,
"pro": "概率:20.5%",
"pro_num": 20.5
}
]
}
4.4 商品扩展配置 (2天)
任务描述
实现商品扩展配置查询,包括支付方式、抵扣设置等
具体工作
- 实现商品扩展配置查询接口
- 实现默认配置获取逻辑
- 实现配置继承机制
核心接口实现
商品扩展配置接口
GET /api/v1/goods/{goodsId}/extend
Authorization: Bearer {token}
Query Parameters:
- goods_type: 商品类型
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"goods_id": 123,
"pay_wechat": 1,
"pay_balance": 1,
"pay_currency": 1,
"pay_currency2": 1,
"pay_coupon": 1,
"is_deduction": 1
}
}
4.5 商品箱号管理 (3天)
任务描述
实现商品箱号查询和管理功能
具体工作
- 实现箱号列表查询接口
- 实现箱号详情查询接口
- 实现箱号排序功能
- 实现余量统计功能
核心接口实现
箱号列表接口
GET /api/v1/goods/{goodsId}/boxes
Authorization: Bearer {token}
Response:
{
"status": 1,
"msg": "请求成功",
"data": [
{
"title": "1-10",
"page_no": 0
},
{
"title": "11-20",
"page_no": 1
}
]
}
箱号详情接口
GET /api/v1/goods/{goodsId}/boxes/detail
Authorization: Bearer {token}
Query Parameters:
- page_no: 页码
- sort: 排序方式 (0=箱号, 1=箱号高, 2=余量高)
Response:
{
"status": 1,
"msg": "请求成功",
"data": [
{
"num": 1,
"surplus_all_stock": 15,
"goodslist": [
{
"shang_id": 10,
"shang_info": {
"title": "A赏",
"color": "#FF0000"
},
"stock": 10,
"surplus_stock": 5
}
]
}
]
}
4.6 商品收藏功能 (2天)
任务描述
实现商品收藏和取消收藏功能
具体工作
- 设计收藏数据模型
- 实现收藏状态查询
- 实现收藏操作接口
- 实现收藏列表查询
核心接口实现
收藏/取消收藏接口
POST /api/v1/goods/{goodsId}/collect
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"goods_num": 1,
"action": "add" // add=收藏, remove=取消收藏
}
Response:
{
"status": 1,
"msg": "收藏成功"
}
收藏列表接口
GET /api/v1/user/collections
Authorization: Bearer {token}
Query Parameters:
- page: 页码
- limit: 每页数量
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"data": [
{
"id": 123,
"goods_id": 456,
"goods_num": 1,
"goods_title": "商品标题",
"goods_imgurl": "https://example.com/goods.jpg",
"goods_price": "10.00",
"collect_time": "2024-01-01 12:00:00"
}
],
"last_page": 3
}
}
4.7 商品奖品统计 (1天)
任务描述
实现商品奖品数量和内容统计功能
具体工作
- 实现奖品数量统计接口
- 实现奖品内容查询接口
核心接口实现
商品奖品数量统计接口
POST /api/v1/goods/prize-count
Authorization: Bearer {token}
Request:
{
"goods_id": 1001
}
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"total_count": 100,
"surplus_count": 50,
"category_count": [
{
"shang_id": 10,
"shang_title": "A赏",
"total": 10,
"surplus": 5
}
]
}
}
商品奖品内容接口
POST /api/v1/goods/prize-content
Authorization: Bearer {token}
Request:
{
"goods_id": 1001,
"num": 0
}
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"goods_list": [
{
"id": 456,
"title": "奖品标题",
"imgurl": "https://example.com/prize.jpg",
"price": "100.00",
"stock": 10,
"surplus_stock": 5
}
]
}
}
4.8 中奖记录查询 (3天)
任务描述
实现商品中奖记录查询功能
具体工作
- 实现中奖记录查询接口
- 实现奖品分类筛选
- 实现中奖统计功能
- 优化查询性能
核心接口实现
中奖记录接口
GET /api/v1/goods/{goodsId}/prize-logs
Authorization: Bearer {token}
Query Parameters:
- goods_num: 箱号
- shang_id: 奖品分类ID,0=全部
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"category": [
{
"shang_id": 0,
"shang_title": "全部"
},
{
"shang_id": 10,
"shang_title": "A赏"
}
],
"data": [
{
"user_id": 123,
"user_info": {
"nickname": "用户昵称",
"headimg": "https://example.com/avatar.jpg"
},
"goodslist_title": "奖品标题",
"goodslist_imgurl": "https://example.com/prize.jpg",
"shang_id": 10,
"shang_title": "A赏",
"shang_color": "#FF0000",
"prize_num": 1,
"addtime": "2024-01-01 12:00:00"
}
],
"last_page": 5
}
}
缓存策略设计
Redis缓存键设计
// 商品列表缓存
public static class CacheKeys
{
public const string GoodsList = "goods_list_{0}_{1}_{2}"; // type_userId_page
public const string GoodsDetail = "goods_detail_{0}_{1}"; // goodsId_goodsNum
public const string GoodsJoinCount = "order_goods_count:{0}"; // goodsId
public const string GoodsBoxes = "goods_boxes_{0}"; // goodsId
// 缓存过期时间
public static readonly TimeSpan GoodsListExpiry = TimeSpan.FromSeconds(30);
public static readonly TimeSpan GoodsDetailExpiry = TimeSpan.FromMinutes(5);
public static readonly TimeSpan JoinCountExpiry = TimeSpan.FromMinutes(5);
}
缓存更新策略
public class GoodsCacheService
{
public async Task InvalidateGoodsCache(int goodsId)
{
// 清除相关缓存
await _redis.DeleteAsync($"goods_detail_{goodsId}_*");
await _redis.DeleteAsync($"order_goods_count:{goodsId}");
await _redis.DeleteAsync("goods_list_*");
}
public async Task UpdateJoinCount(int goodsId)
{
var key = $"order_goods_count:{goodsId}";
await _redis.IncrementAsync(key);
await _redis.ExpireAsync(key, CacheKeys.JoinCountExpiry);
}
}
性能优化方案
数据库查询优化
-- 商品列表查询索引
CREATE INDEX idx_goods_status_type_sort ON goods(status, type, sort DESC, id DESC);
CREATE INDEX idx_goods_unlock_amount ON goods(unlock_amount);
-- 商品奖品查询索引
CREATE INDEX idx_goodslist_goods_num ON goods_list(goods_id, num, shang_id);
CREATE INDEX idx_goodslist_surplus ON goods_list(goods_id, surplus_stock);
-- 订单统计查询索引
CREATE INDEX idx_orderlist_goods_count ON order_list(goods_id, num, shang_id, order_type);
批量查询优化
public async Task<List<GoodsListDto>> GetGoodsListWithJoinCountAsync(List<int> goodsIds)
{
// 批量查询商品信息
var goods = await _context.Goods
.Where(g => goodsIds.Contains(g.Id))
.ToListAsync();
// 批量查询参与次数
var joinCounts = await GetBatchJoinCountsAsync(goodsIds);
// 组装结果
return goods.Select(g => new GoodsListDto
{
// ... 其他属性
JoinCount = joinCounts.GetValueOrDefault(g.Id, 0)
}).ToList();
}
验收标准
功能验收
- 商品列表查询功能正常,支持分类筛选
- 商品详情查询功能正常,包含完整奖品信息
- 商品箱号管理功能正常
- 商品收藏功能正常
- 中奖记录查询功能正常
- 商品扩展配置查询正常
- 商品奖品数量统计正常
- 商品奖品内容查询正常
性能验收
- 商品列表接口响应时间 < 300ms
- 商品详情接口响应时间 < 500ms
- 缓存命中率 > 80%
- 支持并发查询 > 100 QPS
数据准确性验收
- 商品库存计算准确
- 奖品概率计算正确
- 参与次数统计准确
- 收藏状态同步正确
风险点和注意事项
技术风险
- 缓存一致性: 商品信息更新时的缓存同步
- 查询性能: 大量商品和奖品数据的查询优化
- 概率计算: 复杂的概率计算逻辑准确性
- 并发访问: 高并发下的数据一致性
解决方案
- 缓存策略: 合理的缓存过期时间和更新机制
- 数据库优化: 适当的索引和查询优化
- 单元测试: 概率计算逻辑的充分测试
- 监控告警: 关键接口的性能监控
下一阶段准备
为阶段5准备的内容
- 订单数据模型设计
- 购物车功能基础
- 库存扣减机制
- 订单状态管理
交接文档
- 商品系统架构说明
- 概率计算规则文档
- 缓存策略说明
- 数据库索引优化指南
阶段4完成标志: 商品系统功能完整,包括商品查询、详情展示、收藏管理、中奖记录等功能正常运行,性能和数据准确性达到要求。