6.6 KiB
Requirements Document
Introduction
本文档定义了抽奖系统从PHP迁移到.NET 8的需求。抽奖系统是盲盒平台的核心功能,包括一番赏抽奖、无限赏抽奖、抽奖结果查询、中奖记录展示等功能。迁移需要确保与PHP API的完全兼容性,同时保持抽奖算法的准确性和公平性。
Glossary
- Lottery_Engine: 抽奖引擎,负责执行抽奖算法和概率计算
- Prize_Service: 奖品服务,负责奖品查询和库存管理
- Order_Item: 订单奖品记录,存储用户抽中的奖品信息
- Goods_Item: 商品奖品项,存储商品的奖品配置和库存
- Shang_Level: 赏品等级,如A赏、B赏等奖品分类
- Weighted_Random: 权重随机算法,根据库存计算概率进行抽奖
- Prize_Log: 中奖记录,展示用户的抽奖历史
Requirements
Requirement 1: 一番赏抽奖结果查询
User Story: As a user, I want to view my lottery results after payment, so that I can see what prizes I won.
Acceptance Criteria
- WHEN a user requests lottery results with a valid order number, THE Prize_Service SHALL return the list of won prizes for that order
- WHEN a user requests lottery results with an invalid order number, THE Prize_Service SHALL return an empty list
- THE Prize_Service SHALL return prize details including title, image, price, recovery value, prize code, and luck number
- THE Prize_Service SHALL format the response to match PHP API structure with snake_case field names
Requirement 2: 无限赏抽奖结果查询
User Story: As a user, I want to view my infinite lottery results, so that I can see what prizes I won from infinite pool.
Acceptance Criteria
- WHEN a user requests infinite lottery results with a valid order number, THE Prize_Service SHALL return the list of won prizes
- WHEN the order type is infinite lottery (type=2), THE Prize_Service SHALL query from infinite order items
- THE Prize_Service SHALL return prize details consistent with the one-shot lottery format
Requirement 3: 一番赏中奖记录查询
User Story: As a user, I want to view winning records for a specific product, so that I can see who won what prizes.
Acceptance Criteria
- WHEN a user requests winning records for a product, THE Prize_Service SHALL return paginated winning records
- WHEN a shang_id filter is provided, THE Prize_Service SHALL filter records by prize level
- THE Prize_Service SHALL return category list for filtering options
- THE Prize_Service SHALL group records by order_id, goodslist_id, and user_id with prize count
- THE Prize_Service SHALL mask user nicknames for privacy (show partial name with ***)
- THE Prize_Service SHALL order records by time descending (newest first)
Requirement 4: 无限赏中奖记录查询
User Story: As a user, I want to view winning records for infinite lottery products, so that I can see recent winners.
Acceptance Criteria
- WHEN a user requests infinite winning records, THE Prize_Service SHALL return paginated records for infinite lottery type
- THE Prize_Service SHALL filter records by order_type=2 (infinite lottery)
- THE Prize_Service SHALL return records with user info, prize info, and timestamp
Requirement 5: 每日抽奖记录查询
User Story: As a user, I want to view daily lottery records for infinite products, so that I can track daily activity.
Acceptance Criteria
- WHEN a user requests daily records for a product, THE Prize_Service SHALL return today's winning records
- THE Prize_Service SHALL filter records by current date
- THE Prize_Service SHALL return records ordered by time descending
Requirement 6: 道具卡抽奖
User Story: As a user, I want to use item cards to draw prizes, so that I can get prizes without paying.
Acceptance Criteria
- WHEN a user uses an item card for lottery, THE Lottery_Engine SHALL validate the item card ownership
- WHEN the item card is valid, THE Lottery_Engine SHALL execute the lottery draw
- WHEN the item card is used, THE Lottery_Engine SHALL mark the item card as consumed
- IF the item card is invalid or already used, THEN THE Lottery_Engine SHALL return an error message
Requirement 7: 抽奖算法引擎
User Story: As a system, I want to execute fair lottery draws, so that prizes are distributed according to configured probabilities.
Acceptance Criteria
- THE Lottery_Engine SHALL calculate prize probability based on remaining stock (surplus_stock / total_surplus_stock * 100)
- THE Lottery_Engine SHALL use weighted random selection algorithm for prize selection
- THE Lottery_Engine SHALL exclude prizes with zero remaining stock from the draw pool
- THE Lottery_Engine SHALL deduct inventory atomically after prize selection
- THE Lottery_Engine SHALL record draw results in order_item table
- THE Lottery_Engine SHALL generate unique prize_code for each won prize
- IF all prizes are depleted, THEN THE Lottery_Engine SHALL return an error indicating no available prizes
Requirement 8: 库存管理
User Story: As a system, I want to manage prize inventory accurately, so that overselling is prevented.
Acceptance Criteria
- WHEN a prize is won, THE Prize_Service SHALL decrement surplus_stock by 1 atomically
- THE Prize_Service SHALL use database transactions to ensure inventory consistency
- IF concurrent draws occur, THE Prize_Service SHALL use optimistic locking to prevent race conditions
- THE Prize_Service SHALL validate stock availability before confirming the draw
Requirement 9: 抽奖记录持久化
User Story: As a system, I want to persist all lottery records, so that results can be audited and queried.
Acceptance Criteria
- WHEN a lottery draw completes, THE Prize_Service SHALL create order_item records for each prize
- THE Prize_Service SHALL record user_id, goods_id, goodslist_id, shang_id, prize_code, and timestamp
- THE Prize_Service SHALL set source=1 for lottery-won prizes (vs source=0 for purchased)
- THE Prize_Service SHALL set appropriate order_type based on lottery type (1=一番赏, 2=无限赏, etc.)
Requirement 10: API响应格式兼容
User Story: As a frontend developer, I want consistent API responses, so that existing frontend code works without changes.
Acceptance Criteria
- THE API SHALL return responses in format: { "status": 1, "msg": "success", "data": {...} }
- THE API SHALL use snake_case for all field names in response
- THE API SHALL return status=0 with error message for failures
- THE API SHALL maintain backward compatibility with PHP API response structure