当前位置: 首页 > news >正文

【Java项目-企悦抽】02-AI赋能产品需求规格说明书

声明:本文档AI辅助完成,内容仅供参考

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🎯你正在阅读「Java项目-企悦抽」系列文章🎯
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

🔥弹简特 个人主页

❄️个人专栏直通车:

  • 🔌接口测试从入门到跑路
  • 一个后端的 JavaEE 续命指南
  • 🛜网络原理续命手册
  • Java项目-轻聊

靠热爱去书写自己,靠勇敢去书写生活!
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨


🌟 博主简介:



文章目录:

  • 企悦抽-产品需求规格说明书
    • 修订记录
    • 1. 引言
      • 1.1 编写目的
      • 1.2 文档关系
    • 2. 系统概述
      • 2.1 系统名称
      • 2.2 技术栈规格
      • 2.3 模块划分
    • 3. 系统架构规格
      • 3.1 逻辑架构
      • 3.2 抽奖异步链路规格
      • 3.3 缓存规格
    • 4. 数据规格
      • 4.1 数据库表
      • 4.2 枚举规格
      • 4.3 字段校验规格
      • 4.4 加密规格
    • 5. 功能规格详述
      • 5.1 FR-001 ~ FR-005 用户与认证
        • 5.1.1 注册(FR-001)
        • 5.1.2 发送验证码(FR-004)
        • 5.1.3 密码登录(FR-002)
        • 5.1.4 短信登录(FR-003)
        • 5.1.5 登录拦截(FR-005)
      • 5.2 FR-006 ~ FR-007 人员管理
        • 5.2.1 创建普通用户(FR-006)
        • 5.2.2 用户列表(FR-007)
      • 5.3 FR-008 ~ FR-010 奖品管理
        • 5.3.1 创建奖品(FR-008)
        • 5.3.2 奖品分页列表(FR-009)
        • 5.3.3 奖品全量列表(FR-010)
      • 5.4 FR-011 ~ FR-013 活动管理
        • 5.4.1 创建活动(FR-011)
        • 5.4.2 活动列表(FR-012)
        • 5.4.3 活动详情(FR-013)
      • 5.5 FR-014 ~ FR-016 抽奖与结果
        • 5.5.1 提交抽奖(FR-014)
        • 5.5.2 查询中奖记录(FR-015)
        • 5.5.3 抽奖大屏(FR-016)
      • 5.6 FR-017 ~ FR-018 通知
        • 5.6.1 中奖邮件(FR-017)
        • 5.6.2 中奖短信(FR-018)
    • 6. 接口规格索引
    • 7. 前端页面规格
      • 7.1 实现说明
      • 7.2 页面清单
      • 7.3 通用前端约定
    • 8. 状态机规格
      • 8.1 状态扭转顺序
      • 8.2 抽奖正向扭转
      • 8.3 异常回滚
    • 9. 安全规格
    • 10. 异常与容错规格
      • 10.1 MQ 重试
      • 10.2 死信队列
      • 10.3 校验失败静默返回
    • 11. 验收标准
      • 11.1 功能验收
      • 11.2 非功能验收

企悦抽-产品需求规格说明书

文档属性内容
产品名称企悦抽(QiYueChou)
文档类型产品需求规格说明书(PRS)
文档版本V1.0
编写日期2025-07-03
上游文档AI赋能产品需求文档
关联代码lottery-system
文档状态已定稿

修订记录

版本日期修订说明
V1.02025-07-03首版,由 PRD 拆解为可开发/可测试规格

1. 引言

1.1 编写目的

本文档在 PRD 基础上,将产品需求转化为可实施、可验证的功能规格、数据规格、状态规则与验收标准,供研发与测试直接使用。

1.2 文档关系

PRD(为什么做、做什么) ↓ PRS(怎么做、做到什么标准) ← 本文档 ↓ 接口设计文档(接口级定义) ↓ 接口测试需求文档(测试用例输入)

2. 系统概述

2.1 系统名称

  • 产品名:企悦抽
  • 工程名:lottery-system
  • 默认端口(开发用):8080

2.2 技术栈规格

层次技术版本/说明
后端框架Spring Boot3.2.6
语言Java17
ORMMyBatis3.0.3(注解方式)
数据库MySQL库名lottery_system
缓存RedisLettuce,默认端口配置 8888
消息队列RabbitMQDirect 交换机 + 死信队列
认证JWTjjwt 0.11.5,Header:user_token
前端HTML + jQuery + CSS静态资源/staticUI 借助 AI 辅助实现,主打美观效果
日志SLF4J + Logbacklogback-spring.xml
短信Spug 推送SMSUtilHTTP 调用
邮件Spring MailQQ SMTP

2.3 模块划分

模块包路径/组件职责
用户模块UserControllerUserServiceImpl注册、登录、用户列表
验证码模块VerificationCodeServiceImpl验证码生成、Redis 缓存、Spug 发送
奖品模块PrizeControllerPrizeServiceImpl奖品 CRUD、图片上传
活动模块ActivityControllerActivityServiceImpl活动创建、列表、详情、Redis 缓存
抽奖模块DrawPrizeControllerDrawPrizeServiceImpl发 MQ、校验、落库、查记录
MQ 消费MqReceiverDlxReceiver异步抽奖、回滚、死信重投
状态管理ActivityStatusManagerImpl+ Operator活动/奖品/用户状态扭转
通用LoginInterceptorGlobalException鉴权、统一响应

3. 系统架构规格

3.1 逻辑架构

3.2 抽奖异步链路规格

步骤组件行为
1DrawPrizeController接收 JSON,调用drawPrize()
2DrawPrizeServiceImpl.drawPrize构造{messageId, messageData}发 MQ
3Controller立即返回{code:200, data:true}
4MqReceiver.process消费消息
5checkDrawPrizeParam校验
6ActivityStatusManager.handlerEvent扭转状态
7saveWinnerRecords写库 + 缓存
8线程池异步发邮件(短信占位)
9异常回滚 + 抛异常 → MQ 重试 → 死信

3.3 缓存规格

键前缀内容TTL
VERIFICATION_CODE_{phone}4 位验证码60 秒
ACTIVITY_{activityId}活动详情 JSON3 天
WINNING_RECORDS_{activityId}活动全量中奖记录2 天
WINNING_RECORDS_{activityId}_{prizeId}单奖品中奖记录2 天

4. 数据规格

4.1 数据库表

表名说明关键约束
user用户邮箱唯一、手机号唯一
prize奖品库
activity活动status: RUNNING/COMPLETED
activity_prize活动-奖品uk(activity_id, prize_id)
activity_user活动-用户uk(activity_id, user_id)
winning_record中奖记录uk(winner_id, activity_id, prize_id)

4.2 枚举规格

用户身份UserIdentityEnum

含义
ADMIN管理员
NORMAL普通用户

活动状态ActivityStatusEnum

含义
RUNNING进行中
COMPLETED已完成

活动奖品状态ActivityPrizeStatusEnum

含义
INIT未抽取
COMPLETED已抽取

活动用户状态ActivityUserStatusEnum

含义
INIT未中奖
COMPLETED已中奖

奖品等级ActivityPrizeTiersEnum

code中文
FIRST_PRIZE1一等奖
SECOND_PRIZE2二等奖
THIRD_PRIZE3三等奖

4.3 字段校验规格

字段规则实现
邮箱小写邮箱格式RegexUtil.checkMail
手机号1 开头 11 位RegexUtil.checkMobile
密码6~12 位字母数字RegexUtil.checkPassword
管理员密码必填注册/创建时校验

4.4 加密规格

数据算法说明
密码SHA256 Hex注册/登录时DigestUtil.sha256Hex
手机号AESEncryptTypeHandler,密钥 16 字节

5. 功能规格详述

5.1 FR-001 ~ FR-005 用户与认证

5.1.1 注册(FR-001)

输入namemailphoneNumberpassword(管理员必填)、identity(ADMIN/NORMAL)

处理逻辑

  1. JSR303 非空校验
  2. 邮箱/手机号格式校验
  3. 身份合法性校验
  4. 管理员密码必填且强度校验
  5. 邮箱/手机号唯一性校验
  6. 密码 SHA256 后入库;手机号 AES 加密入库

输出{ userId }

页面register.html;管理员后台创建时admin=false&jumpList=true

5.1.2 发送验证码(FR-004)

输入:Query 参数phone

处理逻辑

  1. 手机号格式校验
  2. MyCaptchaUtil.getCaptcha(4)生成 4 位数字
  3. SMSUtil.sendSms(phone, code)调用 Spug
  4. Redis 存储,键VERIFICATION_CODE_{phone},60 秒

输出{ code:200, data:true }

5.1.3 密码登录(FR-002)

输入loginName(手机/邮箱)、passwordmandatoryIdentity(可选)

处理逻辑

  1. 按格式查用户(手机需 Encrypt 包装)
  2. 校验用户存在、身份匹配、密码 SHA256 比对
  3. JWT Claims:{ id, identity },有效期 1 小时

输出{ token, identity }

5.1.4 短信登录(FR-003)

输入loginMobileverificationCodemandatoryIdentity(可选)

处理逻辑

  1. 查用户、校验身份
  2. 从 Redis 取验证码比对
  3. 签发 JWT
5.1.5 登录拦截(FR-005)

白名单(无需 Token):

  • 静态资源/**/*.html/css/**/js/**/pic/**
  • /**/login(含/password/login/message/login
  • /register
  • /verification-code/send
  • /winning-records/show

鉴权失败:HTTP 401,无 JSON Body


5.2 FR-006 ~ FR-007 人员管理

5.2.1 创建普通用户(FR-006)

与注册共用/registeridentity=NORMAL,不传密码。

5.2.2 用户列表(FR-007)

输入:Queryidentity(可选,ADMIN/NORMAL,空则全部)

输出[{ userId, userName, identity }]


5.3 FR-008 ~ FR-010 奖品管理

5.3.1 创建奖品(FR-008)

Content-Typemultipart/form-data

Part 名类型说明
paramJSON 字符串{ prizeName, description, price }
prizePicFile奖品图片,最大 10MB

处理:图片存本地pic.local-path,文件名 UUID+后缀;imageUrl存文件名

输出:奖品 ID(Long)

5.3.2 奖品分页列表(FR-009)

输入currentPage(默认 1)、pageSize(默认 10)

输出{ total, records:[{ prizeId, prizeName, description, price, imageUrl }] }

5.3.3 奖品全量列表(FR-010)

输出[{ prizeId, prizeName }]


5.4 FR-011 ~ FR-013 活动管理

5.4.1 创建活动(FR-011)

输入

{"activityName":"string, 必填","description":"string, 必填","activityPrizeList":[{"prizeId":"long","prizeAmount":"long","prizeTiers":"FIRST_PRIZE|SECOND_PRIZE|THIRD_PRIZE"}],"activityUserList":[{"userId":"long","userName":"string"}]}

校验

  • 奖品 ID、用户 ID 均存在于主表
  • 参与人数 ≥ 奖品总数
  • 奖品等级合法

事务:写 activity + activity_prize + activity_user,初始状态分别为 RUNNING、INIT、INIT

缓存:组装ActivityDetailDTO写入 Redis

输出{ activityId }

5.4.2 活动列表(FR-012)

输出字段validstatus == RUNNING为 true

前端行为

  • valid=true → 「活动进行中,去抽奖」
  • valid=false → 「活动已完成,查看中奖名单」
5.4.3 活动详情(FR-013)

输入:QueryactivityId

输出

字段说明
valid活动是否进行中
prizes[].valid奖品是否未抽取(INIT=true)
prizes[].prizeTierName等级中文名
prizes按等级 code 升序排列
users[].valid用户是否未中奖(INIT=true)

读取顺序:Redis → MySQL 多表组装 → 回写 Redis


5.5 FR-014 ~ FR-016 抽奖与结果

5.5.1 提交抽奖(FR-014)

输入

{"activityId":"long, 必填","prizeId":"long, 必填","winningTime":"Date, 必填","winnerList":[{"userId":"long, 必填","userName":"string, 必填"}]}

同步行为:仅发送 RabbitMQ 消息,不做业务落库

MQ 消费校验(失败则 return 或回滚):

  • 活动、活动奖品存在
  • 活动非 COMPLETED
  • 奖品非 COMPLETED
  • winnerList.size() == prizeAmount
5.5.2 查询中奖记录(FR-015)

输入activityId(必填)、prizeId(可选)

逻辑

  • 无 prizeId:查活动维度全量
  • 有 prizeId:查该奖品维度

读取:Redis → MySQL → 回写 Redis

免登录:在白名单中

5.5.3 抽奖大屏(FR-016)

URL 参数activityIdactivityNamevalid(true/false)

权限

  • valid=true 且 localStorageuser_identity=ADMIN:可抽奖
  • valid=true 且非 ADMIN:弹窗提示,不可操作
  • valid=false:直接展示全量中奖名单

刷新恢复:已抽完奖品(valid=false)点击开始 → 直接查/winning-records/show?prizeId=展示名单

分享:复制链接,附加valid=false&hideButton=true,隐藏操作按钮


5.6 FR-017 ~ FR-018 通知

5.6.1 中奖邮件(FR-017)

触发:MQ 消费成功后,线程池异步执行

模板(实际代码):

Hi,{winnerName}! 有个好消息要告诉你:你在【{activityName}】活动中,获得了{prizeTier中文}的惊喜福利:{prizeName}! 福利发放时间:{HH:mm:ss},快来领取你的专属惊喜吧~

收件人:中奖用户邮箱

5.6.2 中奖短信(FR-018)

状态:V1.0 未实现,MqReceiver.sendMessage仅打印日志


6. 接口规格索引

序号方法路径鉴权详细定义
1POST/register见接口设计文档 §4.1
2GET/verification-code/send见接口设计文档 §4.2
3*/password/login见接口设计文档 §4.3
4*/message/login见接口设计文档 §4.4
5GET/base-user/find-list见接口设计文档 §4.5
6*/pic/upload见接口设计文档 §5.1
7*/prize/create见接口设计文档 §5.2
8GET/prize/find-list见接口设计文档 §5.3
9GET/prize/find-listAll见接口设计文档 §5.4
10*/activity/create见接口设计文档 §6.1
11GET/activity/find-list见接口设计文档 §6.2
12GET/activity-detail/find见接口设计文档 §6.3
13*/draw-prize见接口设计文档 §7.1
14*/winning-records/show见接口设计文档 §7.2

注:标注*的接口 Controller 使用@RequestMapping,未限定 HTTP 方法;前端实际使用 POST(JSON)或 GET(Query)。


7. 前端页面规格

7.1 实现说明

本项目 Web 前端(src/main/resources/static)在页面结构、样式与部分交互实现上借助 AI 辅助完成,设计取向为美观、现代化视觉与现场展示效果,而非传统 B 端「功能优先、样式从简」风格。典型体现包括:

  • 登录/注册页:分栏布局、渐变背景与表单视觉优化
  • 管理后台:iframe 导航 + 统一卡片/表格样式
  • 抽奖大屏(draw.html):全屏背景、奖品展示、人名滚动动效、中奖确认交互

规格边界:本文档对前端的约束以页面路由、功能行为、Token 传递、接口调用为准;颜色、间距、动效细节以当前 AI 辅助产出为基线,不作为像素级设计稿验收项。后端 REST 接口规格不受 UI 实现方式影响。

7.2 页面清单

页面路径功能
后台登录/blogin.html密码/验证码 Tab 登录
管理后台/admin.htmliframe 框架
注册用户/register.html管理员/普通用户注册
人员列表/user-list.html用户列表
创建奖品/create-prizes.html表单 + 图片
奖品列表/prizes-list.html分页
创建活动/create-activity.html圈选奖品/人员
活动列表/activities-list.html分页 + 跳转 draw
抽奖大屏/draw.html核心抽奖交互

7.3 通用前端约定

Token 存储localStorage.user_tokenlocalStorage.user_identity

请求头user_token: {JWT}


8. 状态机规格

8.1 状态扭转顺序

ActivityStatusManagerImpl.handlerEvent

  1. Sequence 1PrizeOperatorUserOperator(并行遍历,先奖品/用户)
  2. Sequence 2ActivityOperator(全部奖品 COMPLETED 后才转活动)

8.2 抽奖正向扭转

对象原状态目标状态
activity_prizeINITCOMPLETED
activity_user(中奖者)INITCOMPLETED
activityRUNNINGCOMPLETED(全部奖品抽完后)

8.3 异常回滚

对象回滚目标
activity_prizeINIT
activity_userINIT
activityRUNNING
winning_record删除对应记录 + 清缓存

9. 安全规格

编号规格
SEC-01JWT Header 名称固定为user_token
SEC-02Token 解析失败返回 HTTP 401
SEC-03业务异常统一{ code:500, msg:业务消息 }
SEC-04图片上传限制 10MB
SEC-05手机号不得明文落库

10. 异常与容错规格

10.1 MQ 重试

  • spring.rabbitmq.listener.simple.retry.enabled=true
  • max-attempts=5

10.2 死信队列

  • 正常队列:DirectQueue→ 死信交换机DlxDirectExchange
  • 死信消费者DlxReceiver重新投递到正常队列

10.3 校验失败静默返回

checkDrawPrizeParam返回 false 时,MqReceiver直接 return,不抛异常(消息被 ACK)


11. 验收标准

11.1 功能验收

编号验收项通过标准
AC-01管理员注册登录可进入 admin.html
AC-02创建普通用户列表可见 NORMAL 用户
AC-03创建奖品列表展示图片与信息
AC-04创建活动返回 activityId,详情正确
AC-05完整抽奖流程每轮落库,最终活动 COMPLETED
AC-06刷新恢复已抽奖品不重复抽
AC-07分享链接仅展示结果,无操作按钮
AC-08邮件通知中奖者收到邮件
AC-09未登录拦截受保护接口返回 401

11.2 非功能验收

编号验收项通过标准
AC-N01抽奖接口响应500ms 内返回(P95)
AC-N02缓存命中二次查活动详情走 Redis
AC-N03异常回滚模拟落库异常后状态恢复

文档结束,下一文档我们将手动实现数据库的设计。

http://www.gsyq.cn/news/1640490.html

相关文章:

  • 医用修护敷料选购指南:资质、成分与剂型的硬核拆解
  • TensorRT量化模型部署实战:从QAT到INT8推理的工程陷阱
  • 第十八周小学期
  • 前端工程化-02:一个完整的vue工程结构模板
  • 开源商城源码下载后能商用吗?这3款Apache-2.0协议商城放心用
  • 卫星被云挡住后,AI还能知道洪水淹到哪里吗?
  • 高精度电压管理系统设计与STM32实现
  • 纯电动汽车骑车辅件介绍
  • 大模型技术实战:AIGC与Agent智能体开发指南
  • 总目录 2026版国家级全领域科研痛点攻关
  • 1:配置git
  • Claude Code 会话上下文管理,长会话不失控的三把刀
  • 基于LangChain+Redis构建会话持久化的智能 Agent系统
  • 在半导体功率循环测试以及热特性表征中,从测试得到的VCE 曲线推导热阻Rth和时间常数谱是核心技术
  • AI 编译缓存:命中同一张图之前,先确认输入形状稳定
  • 《龙之家族第三季》 美剧|在线观看|夸克|下载|第一集
  • 专业指南:如何让你的老款Mac电脑免费升级到最新macOS系统
  • 仲景中医AI模型:3步快速部署你的智能辨证论治助手
  • Transformer的核心——注意力机制
  • 基于MATLAB图像处理的药片检测与计数系统设计与实现
  • 泳池设备品牌哪家好
  • 红外光伏板缺陷检测 光伏数据集 AI红外光伏板识别 训练模型
  • 终极指南:使用KMS智能激活脚本免费激活Windows和Office系统
  • 用Python写爬虫的常见陷阱与避坑指南
  • 3分钟上手NSC_BUILDER:Switch游戏文件管理的终极解决方案
  • 【Python工程化实战】Feature Flag 工程化:Unleash / LaunchDarkly 在 Python 服务中的集成实战
  • OpenDog V3:开源四足机器人的分布式运动控制架构解析与实践指南
  • 森林火灾识别数据集| 6200张YOLO火灾预警数据集 适用于森林火灾早期预警、无人机巡检与目标检测研究
  • Signal for LLM
  • 后端框架选型指南:SpringBoot与主流方案的对比分析