【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-0015.1.2 发送验证码FR-0045.1.3 密码登录FR-0025.1.4 短信登录FR-0035.1.5 登录拦截FR-0055.2 FR-006 ~ FR-007 人员管理5.2.1 创建普通用户FR-0065.2.2 用户列表FR-0075.3 FR-008 ~ FR-010 奖品管理5.3.1 创建奖品FR-0085.3.2 奖品分页列表FR-0095.3.3 奖品全量列表FR-0105.4 FR-011 ~ FR-013 活动管理5.4.1 创建活动FR-0115.4.2 活动列表FR-0125.4.3 活动详情FR-0135.5 FR-014 ~ FR-016 抽奖与结果5.5.1 提交抽奖FR-0145.5.2 查询中奖记录FR-0155.5.3 抽奖大屏FR-0165.6 FR-017 ~ FR-018 通知5.6.1 中奖邮件FR-0175.6.2 中奖短信FR-0186. 接口规格索引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默认端口开发用80802.2 技术栈规格层次技术版本/说明后端框架Spring Boot3.2.6语言Java17ORMMyBatis3.0.3注解方式数据库MySQL库名lottery_system缓存RedisLettuce默认端口配置 8888消息队列RabbitMQDirect 交换机 死信队列认证JWTjjwt 0.11.5Header:user_token前端HTML jQuery CSS静态资源/staticUI 借助 AI 辅助实现主打美观效果日志SLF4J Logbacklogback-spring.xml短信Spug 推送SMSUtilHTTP 调用邮件Spring MailQQ SMTP2.3 模块划分模块包路径/组件职责用户模块UserController、UserServiceImpl注册、登录、用户列表验证码模块VerificationCodeServiceImpl验证码生成、Redis 缓存、Spug 发送奖品模块PrizeController、PrizeServiceImpl奖品 CRUD、图片上传活动模块ActivityController、ActivityServiceImpl活动创建、列表、详情、Redis 缓存抽奖模块DrawPrizeController、DrawPrizeServiceImpl发 MQ、校验、落库、查记录MQ 消费MqReceiver、DlxReceiver异步抽奖、回滚、死信重投状态管理ActivityStatusManagerImpl Operator活动/奖品/用户状态扭转通用LoginInterceptor、GlobalException鉴权、统一响应3. 系统架构规格3.1 逻辑架构3.2 抽奖异步链路规格步骤组件行为1DrawPrizeController接收 JSON调用drawPrize()2DrawPrizeServiceImpl.drawPrize构造{messageId, messageData}发 MQ3Controller立即返回{code:200, data:true}4MqReceiver.process消费消息5—checkDrawPrizeParam校验6—ActivityStatusManager.handlerEvent扭转状态7—saveWinnerRecords写库 缓存8—线程池异步发邮件短信占位9异常回滚 抛异常 → MQ 重试 → 死信3.3 缓存规格键前缀内容TTLVERIFICATION_CODE_{phone}4 位验证码60 秒ACTIVITY_{activityId}活动详情 JSON3 天WINNING_RECORDS_{activityId}活动全量中奖记录2 天WINNING_RECORDS_{activityId}_{prizeId}单奖品中奖记录2 天4. 数据规格4.1 数据库表表名说明关键约束user用户邮箱唯一、手机号唯一prize奖品库—activity活动status: RUNNING/COMPLETEDactivity_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输入name、mail、phoneNumber、password管理员必填、identityADMIN/NORMAL处理逻辑JSR303 非空校验邮箱/手机号格式校验身份合法性校验管理员密码必填且强度校验邮箱/手机号唯一性校验密码 SHA256 后入库手机号 AES 加密入库输出{ userId }页面register.html管理员后台创建时adminfalsejumpListtrue5.1.2 发送验证码FR-004输入Query 参数phone处理逻辑手机号格式校验MyCaptchaUtil.getCaptcha(4)生成 4 位数字SMSUtil.sendSms(phone, code)调用 SpugRedis 存储键VERIFICATION_CODE_{phone}60 秒输出{ code:200, data:true }5.1.3 密码登录FR-002输入loginName手机/邮箱、password、mandatoryIdentity可选处理逻辑按格式查用户手机需 Encrypt 包装校验用户存在、身份匹配、密码 SHA256 比对JWT Claims:{ id, identity }有效期 1 小时输出{ token, identity }5.1.4 短信登录FR-003输入loginMobile、verificationCode、mandatoryIdentity可选处理逻辑查用户、校验身份从 Redis 取验证码比对签发 JWT5.1.5 登录拦截FR-005白名单无需 Token静态资源/**/*.html、/css/**、/js/**、/pic/**等/**/login含/password/login、/message/login/register/verification-code/send/winning-records/show鉴权失败HTTP 401无 JSON Body5.2 FR-006 ~ FR-007 人员管理5.2.1 创建普通用户FR-006与注册共用/registeridentityNORMAL不传密码。5.2.2 用户列表FR-007输入Queryidentity可选ADMIN/NORMAL空则全部输出[{ userId, userName, identity }]5.3 FR-008 ~ FR-010 奖品管理5.3.1 创建奖品FR-008Content-Typemultipart/form-dataPart 名类型说明paramJSON 字符串{ prizeName, description, price }prizePicFile奖品图片最大 10MB处理图片存本地pic.local-path文件名 UUID后缀imageUrl存文件名输出奖品 IDLong5.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前端行为validtrue → 「活动进行中去抽奖」validfalse → 「活动已完成查看中奖名单」5.4.3 活动详情FR-013输入QueryactivityId输出字段说明valid活动是否进行中prizes[].valid奖品是否未抽取INITtrueprizes[].prizeTierName等级中文名prizes按等级 code 升序排列users[].valid用户是否未中奖INITtrue读取顺序Redis → MySQL 多表组装 → 回写 Redis5.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奖品非 COMPLETEDwinnerList.size() prizeAmount5.5.2 查询中奖记录FR-015输入activityId必填、prizeId可选逻辑无 prizeId查活动维度全量有 prizeId查该奖品维度读取Redis → MySQL → 回写 Redis免登录在白名单中5.5.3 抽奖大屏FR-016URL 参数activityId、activityName、validtrue/false权限validtrue 且 localStorageuser_identityADMIN可抽奖validtrue 且非 ADMIN弹窗提示不可操作validfalse直接展示全量中奖名单刷新恢复已抽完奖品validfalse点击开始 → 直接查/winning-records/show?prizeId展示名单分享复制链接附加validfalsehideButtontrue隐藏操作按钮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.12GET/verification-code/send否见接口设计文档 §4.23*/password/login否见接口设计文档 §4.34*/message/login否见接口设计文档 §4.45GET/base-user/find-list是见接口设计文档 §4.56*/pic/upload是见接口设计文档 §5.17*/prize/create是见接口设计文档 §5.28GET/prize/find-list是见接口设计文档 §5.39GET/prize/find-listAll是见接口设计文档 §5.410*/activity/create是见接口设计文档 §6.111GET/activity/find-list是见接口设计文档 §6.212GET/activity-detail/find是见接口设计文档 §6.313*/draw-prize是见接口设计文档 §7.114*/winning-records/show否见接口设计文档 §7.2注标注*的接口 Controller 使用RequestMapping未限定 HTTP 方法前端实际使用 POSTJSON或 GETQuery。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_token、localStorage.user_identity请求头user_token: {JWT}8. 状态机规格8.1 状态扭转顺序ActivityStatusManagerImpl.handlerEventSequence 1PrizeOperator、UserOperator并行遍历先奖品/用户Sequence 2ActivityOperator全部奖品 COMPLETED 后才转活动8.2 抽奖正向扭转对象原状态目标状态activity_prizeINITCOMPLETEDactivity_user中奖者INITCOMPLETEDactivityRUNNINGCOMPLETED全部奖品抽完后8.3 异常回滚对象回滚目标activity_prizeINITactivity_userINITactivityRUNNINGwinning_record删除对应记录 清缓存9. 安全规格编号规格SEC-01JWT Header 名称固定为user_tokenSEC-02Token 解析失败返回 HTTP 401SEC-03业务异常统一{ code:500, msg:业务消息 }SEC-04图片上传限制 10MBSEC-05手机号不得明文落库10. 异常与容错规格10.1 MQ 重试spring.rabbitmq.listener.simple.retry.enabledtruemax-attempts510.2 死信队列正常队列DirectQueue→ 死信交换机DlxDirectExchange死信消费者DlxReceiver重新投递到正常队列10.3 校验失败静默返回checkDrawPrizeParam返回 false 时MqReceiver直接 return不抛异常消息被 ACK11. 验收标准11.1 功能验收编号验收项通过标准AC-01管理员注册登录可进入 admin.htmlAC-02创建普通用户列表可见 NORMAL 用户AC-03创建奖品列表展示图片与信息AC-04创建活动返回 activityId详情正确AC-05完整抽奖流程每轮落库最终活动 COMPLETEDAC-06刷新恢复已抽奖品不重复抽AC-07分享链接仅展示结果无操作按钮AC-08邮件通知中奖者收到邮件AC-09未登录拦截受保护接口返回 40111.2 非功能验收编号验收项通过标准AC-N01抽奖接口响应500ms 内返回P95AC-N02缓存命中二次查活动详情走 RedisAC-N03异常回滚模拟落库异常后状态恢复文档结束下一文档我们将手动实现数据库的设计。

相关新闻

STM32+ESP8266(AT指令)极简WiFi驱动|串口透传、自动连热点、数据上传上位机

STM32+ESP8266(AT指令)极简WiFi驱动|串口透传、自动连热点、数据上传上位机

一、前言(为什么工控首选ESP8266 AT固件) 在物联网采集、无线监控、设备远程上报项目中,STM32本身不带网络功能,常用联网方案对比: LWIP网络栈:代码量大、配置复杂、极易内存溢出,小单片机不友好。 ESP8266 SDK开发:需要单独编程、双设备联调、开发成本高。 ESP8266 AT…

2026/7/5 13:37:29阅读更多 →
HCI 功能规范【4.5. Command error handling】

HCI 功能规范【4.5. Command error handling】

这部分是 4.5 Command error handling,讲的是:HCI Command 发生错误时,Controller 应该通过什么事件返回错误、错误码放在哪里、命令是否还会继续执行、哪些返回参数仍然有效。前面 4.4 讲的是命令流控:Host 能不能继续发 HCI Com…

2026/7/5 13:37:29阅读更多 →
编程启蒙|Scratch 转 Python 系列第 3 天完整教程

编程启蒙|Scratch 转 Python 系列第 3 天完整教程

本篇是零基础 Python 自学系列 Scratch 转 Python 第 3 天笔记,适合纯小白入门,内容包含实操代码、详细讲解与配套练习题,全程 Scratch 积木代码 Python 双向对照教学。 一、昨日内容复盘(Scratch 转 Python Day2 for 循环与 ra…

2026/7/5 13:37:29阅读更多 →
把 TeXstudio / LaTeX 工程交给 AI:texstudio-mcp 功能详解

把 TeXstudio / LaTeX 工程交给 AI:texstudio-mcp 功能详解

.tex、跑编译、看日志,而不是只会泛泛而谈,那么需要一个专门面向 LaTeX 工作流的 MCP 服务。texstudio-mcp 就是这样一层桥:它在你的工程目录(workspace_root)里安全地读写文件,按需调用本机已安装的 TeX 工…

2026/7/5 14:27:33阅读更多 →
只看 inline 关键字,如何准确判别代码属于 C 还是 C++ 语义?

只看 inline 关键字,如何准确判别代码属于 C 还是 C++ 语义?

一、 源码中 inline 关键字的排查 对项目仓库中所有 .c / .h / .cpp / .hpp 文件中的 inline 关键字进行了全面的审计与排查, 1、 核心结论 结论:确认代码库中所有的 inline 均属于标准 C 的 inline 关键字语义,未发现异常或误用的情况。统计…

2026/7/5 14:27:33阅读更多 →
FFmpeg移动端硬解机制

FFmpeg移动端硬解机制

一文看懂 FFmpeg 在 Android 和 iOS 上的硬件解码:MediaCodec、VideoToolbox 与 AVHWAccel FFmpeg 的硬解不是一个“开关”,而是一套把各平台系统解码器接进 AVPacket → AVFrame 通用流水线的抽象层。 做移动端播放器、剪辑器或转码工具时,迟…

2026/7/5 14:27:33阅读更多 →
OpCore-Simplify:让PC硬件说macOS语言的智能翻译器

OpCore-Simplify:让PC硬件说macOS语言的智能翻译器

OpCore-Simplify:让PC硬件说macOS语言的智能翻译器 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 你是否曾想过,为什么在PC上…

2026/7/5 14:27:33阅读更多 →
Kafka 消息重试设计:别让失败消息原地打转

Kafka 消息重试设计:别让失败消息原地打转

Kafka 消息重试设计:别让失败消息原地打转 一、重试不是直接再消费一次 Kafka 常用于微服务解耦。消费失败时,很多代码会直接抛异常,让消息再次被消费。这样简单,但如果下游一直不可用或消息本身有问题,就会原地打转&a…

2026/7/5 14:27:33阅读更多 →
ROS集成开发环境

ROS集成开发环境

1.TER快捷键2.VS code 安装首先 在网站下载VS code,Linux最好用.deb格式下载好以后,直接拖到linux的文件夹中在这个文件夹打开终端sudo dpkg -i x.debx.deb是你的安装包名卸载代码code的代码:sudo dpkg --purge code插件里面ros现在使用robot…

2026/7/5 14:22:33阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/5 0:01:08阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/5 0:01:08阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/5 0:01:08阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/5 0:01:08阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/5 0:01:08阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/5 0:01:08阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/5 1:30:27阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/5 3:48:10阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/5 3:48:09阅读更多 →