APP产品需求说明书.docx编写指南:从状态机到验收标准
简介APP产品需求说明书.docx 是一份面向移动电商APP全流程的产品需求文档目标读者覆盖产品总监、产品设计、技术总监、项目经理、开发与测试人员。内容以手机客户端为核心完整梳理了由手机端、PC端、服务器端组成的产品架构并围绕首页、交易大厅、专场、业务中心等前台模块逐项说明页面功能、事件流与业务规则覆盖图片轮播、新闻公告、竞价公告、会员登录、业务提醒以及买方/卖方在业务中心的验货、发货、评价等操作流程同时明确标注了手机端不支持支付和订单异议处理需在PC端完成的边界。文档结构完整从简介、产品功能业务需求到界面展示说明均有章节对应可直接作为需求评审、原型设计、开发排期和测试用例编写的输入。资源为一个docx文件压缩包大小约2.08MB便于团队共享与存档。已有476人学习/下载适合正在规划或迭代APP产品、需要规范需求说明书的项目团队参考。1. 为什么 APP 产品需求说明书要交付成 docx而不是一张原型图“点完‘预约’按钮之后是直接跳到支付页还是先弹出确认框”这句话在 App 开发会上反复出现。原型图能展示页面布局却回答不了交互时序、异常分支和字段规则。于是团队需要一个文本形态的 APP 产品需求说明书.docx 来承接这些问题。这个 docx 不只是给产品经理存档它是开发取接口字段、测试写用例、设计抽组件的单一事实来源。它适合业务逻辑复杂、角色权限非对称、有支付和状态流转的 App 项目。下面的内容会从需求结构、模板生成和验收标准三个层面把一份可直接投递的 docx 写透。2. 写 APP 产品需求说明书之前先定范围、用户和核心路径2.1 用一句话定位圈定功能边界许多 APP 产品需求说明书失控都是因为跳过定位直接开始罗列功能。理想的第一句话要能回答“谁在什么场景下靠什么功能解决什么痛点”。例如“让没有专职运营的健身工作室用 10 分钟搞定一周排班和学员通知”这句话一出来你就知道第一期不需要社区动态不需要社交关系链甚至不需要复杂的推荐算法。把这句话写成可衡量的记录比写“本产品致力于提升效率”有用得多。例如“当管理员导入 500 名学员时页面在 3 秒内显示名单且不卡死”就是一个可以从设计阶段验证到测试阶段的描述。功能的 Must 范围应该和这句话强相关其他所有需求都要回到这句话问一句“它是否真的在支撑核心让利点”。如果回答不了就放进 Wont 列表。用一张范围表在评审时达成共识避免开发排期后需求还在膨胀功能模块与核心定位的关系是否进入第一期教练排班核心解决排班效率是学员通知核心解决触达效率是课程评价增强学员信任但非必需延期热门推荐探索功能与核心定位弱相关不做范围表最好放在需求说明书的第 1.1 节下面让评审人先看边界再看细节。后加的优先需求必须经过产品、开发、测试三方确认而不是产品经理单方面调整优先级。2.2 用用例表和角色权限表对齐点击逻辑App 需求往往涉及多个端除了用户端 App还有管理后台和客服工作台。很多说明书只写“用户”一个角色导致游客、普通用户、店长在同一个功能上的行为完全无法区分。可以把用户故事写成统一的句式作为某个角色在某个条件下希望通过某个操作达到某个结果。这个句式之外必须补一句“如果不允许操作会怎样”。权限要具体到页面、按钮、接口三层。比如运营人员能看到课程管理入口但只有店长能点击“下架课程”游客能浏览课程列表点击“预约”时去登录页但服务端也要在返回数据里校验登录状态不能只在客户端藏起按钮。权限对不上就会出现“安卓能删除订单iOS 却报错”的怪问题。权限表可以单独成附录字段如下角色页面权限按钮权限接口权限校验时机游客首页、课程列表只可浏览不可预约查询类接口每次请求时校验普通用户已登录页面可预约、取消预约创建订单、取消订单进入页面和关键动作时校验店长管理后台全部可上架、下架课程修改课程状态每次请求时校验这张表进入评审后后端要逐个接口核对客户端要逐个页面核对。需求说明书里出现“如果有权限限制”这种模糊描述开发一定会在联调时才问“到底怎么判”。2.3 用状态表描述核心业务流程用户故事列表替代不了流程特别是订单、预约这类状态驱动的场景。常见做法是给核心实体画一张状态表而不是直接画 Uml 图因为文字状态表在评审会上更省时间每个人都能直接看迁移路径。以“预约单”为例状态至少包括待支付、已支付、已核销、已完成、已取消、退款中、已退款。状态机可以用一段 Python 代码来自检这段代码看起来像后端设计实际上评审时可以用它解释迁移规则transitions { 待支付: {支付: 已支付, 取消: 已取消}, 已支付: {核销: 已核销, 退款: 退款中}, 已核销: {复核: 已完成}, 退款中: {确认退款: 已退款}, 已取消: {}, 已完成: {}, 已退款: {}, } def can_transit(src, action): if src not in transitions: return False return action in transitions[src] print(can_transit(待支付, 支付)) # True print(can_transit(已支付, 取消)) # False逻辑说明dict 的 key 是动作value 是目标状态动作名要尽量和接口回调事件保持一致例如支付回调事件叫payment.success状态表里就不要写成“支付完成”。参数说明所有终态字典为空表示没有后续动作开发实现时先调用can_transit可以避免重复回调导致状态被覆盖。这张表最终要能反推数据库枚举字段它出现在哪里后端 constants 里就应该有对应枚举。3. 用 python-docx 生成模板从骨架到可评审文档3.1 安装依赖并生成文档元信息为什么要用脚本生成需求说明书模板因为多项目复用时手工设置标题层级、表格样式、元信息非常容易漏。而且脚本可以被接进需求管理平台的 CI做到每次导出版本都能自动记录更新时间。依赖已经很成熟安装只需要一条命令pip install python-docxpython-docx 不依赖 Office在 Linux 构建机上也能运行。生成一个最简文档骨架from docx import Document from docx.shared import Pt, RGBColor doc Document() doc.add_heading(APP 产品需求说明书, level0) meta [ (版本, v0.1), (状态, 评审中), (负责人, 产品组), (最后更新, 2025-06-01), ] for key, value in meta: p doc.add_paragraph() run p.add_run(f{key}{value}) run.font.color.rgb RGBColor(0x40, 0x40, 0x40) run.font.size Pt(10) doc.save(APP产品需求说明书.docx)逻辑说明文档创建后第一页放元信息评审人不用打开文件属性就知道这份文档是否过期。参数说明状态建议固定为“草稿 / 评审中 / 已确认 / 已废弃”四态只有“已确认”版本能进入开发排期。“负责人”建议写角色名而不是个人姓名避免人员变动后文档失联。3.2 用脚本批量生成标题和页面样式手工敲标题不仅慢还容易把二级标题误设成一级。可以定义一个章节列表用循环统一写入同时统一中文字体和字号from docx import Document from docx.shared import Pt doc Document() structure [ (chapter, 一、产品概述), (section, 1.1 产品定位), (section, 1.2 目标用户), (chapter, 二、功能需求), (section, 2.1 登录), (section, 2.2 预约), (chapter, 三、非功能需求), ] for level, text in structure: if level chapter: h doc.add_heading(text, level1) else: h doc.add_heading(text, level2) for run in h.runs: run.font.name 微软雅黑 run.font.size Pt(16 if level chapter else 13) doc.save(template.docx)逻辑说明用add_heading生成标题会自动挂到 Word 的 Heading 样式后续可以生成目录。参数说明这里的编号已经写死例如“1.1”“1.2”适合文档结构稳定后输出如果要支持自动多级编号需要修改 Word OpenXML 的 numbering 部分对大多数评审场景来说写死编号更可控。3.3 把功能需求写进表格并保持可追踪需求正文最好用表格而不是长段落。每一行都是一条可追踪的需求记录测试也能直接对着写用例。下面代码生成一张功能需求表from docx import Document from docx.shared import Cm, Pt doc Document() headers [需求ID, 模块, 用户故事, 优先级, 验收标准] rows [ [F-001, 登录, 作为游客我希望用手机号验证码登录以便预约课程, Must, 验证码输入错误时提示“验证码不正确”60 秒后自动失效], [F-002, 预约, 作为用户我希望选择教练和时段以便生成预约单, Must, 同一教练同一时段被预约后其他人收到“该时段已满”], ] table doc.add_table(rows1, colslen(headers)) table.style Table Grid for i, h in enumerate(headers): table.rows[0].cells[i].text h for row in rows: cells table.add_row().cells for i, v in enumerate(row): cells[i].text v for para in cells[i].paragraphs: for run in para.runs: run.font.size Pt(9) widths [Cm(1.5), Cm(1.5), Cm(4.5), Cm(1.5), Cm(5.5)] for col, width in zip(table.columns, widths): for cell in col.cells: cell.width width doc.save(需求功能表.docx)逻辑说明表头固定 5 列验收标准写成“当…时显示…”的句式避免“界面友好”“体验良好”这种无法验证的描述。参数说明Table Grid是黑白打印最稳妥的表格样式列宽逐个单元格设置是为了兼容 LibreOffice 打开 docx 时的排版一致性。需求 ID 建议用模块缩写加序号比如订单模块用ORD-001多人协作时不冲突。提示新建的 docx 必须保存后再次打开检查一次表格列宽部分低版本 WPS 会忽略列宽设置导致导出 PDF 时内容被截断。4. 把非功能需求和异常态写进说明书4.1 页面状态加载中、空数据、失败、无权限很多 APP 产品需求说明书的缺陷是只描述 happy path比如“用户打开我的预约看到课程列表”。但真实环境有弱网、空列表、token 失效、服务端 500。每个页面都应该定义状态优先级先加载缓存再请求网络失败后展示可重试页面。客户端可以沉淀一套通用状态组件需求说明书里直接引用组件名称比逐页画四张图更清晰。页面状态表要覆盖以下四种情况状态类型触发条件示例文案默认操作loading首次加载或下拉刷新无展示骨架图请求超过 3 秒可提示弱网empty接口成功列表为空暂无预约提供“去预约”按钮error网络超时或 HTTP 5xx加载失败请重试点击重试重新请求forbiddentoken 缺失或无效请先登录跳转登录页登录后回跳原页面页面状态必须和第 2.3 节的业务状态机一起看。例如预约失败不能把订单置为 error 状态而是保持“待支付”不变只在页面上提示。要不然客户端和服务端的状态会对不上用户看到的现象就是“App 显示失败后台订单已经生成”。4.2 接口、埋点、推送的数据边界需求说明书可以不写完整接口文档但要在每个功能点后面附数据字段草案。特别是埋点事件如果不在 PRD 阶段定好后面统计数据时会出现“iOS 上报 eventA安卓上报 eventB后台两张表”的局面。埋点 JSON 可以这样约定{ page: appointment_list, event: click_reserve, payload: { course_id: string, coach_id: string, source: home_recommend } }参数说明page表示页面名event用动词_对象风格避免大小写混用payload只放业务字段设备型号、网络状态这种字段交给客户端 SDK 自动采集。推送要写明触发点在哪里例如“开课前 2 小时提醒”触发点应该是服务端定时任务而不是用户打开 App 时才计算否则离线用户永远收不到提醒。这种边界写进需求说明书开发和测试都不会再为“什么时候该推送”争论。注意埋点和接口字段一旦在文档评审时确认后续改动要进版本变更记录不能在评审群里发一句“新加一个参数”就完事。4.3 风险表多端不一致、时区、幂等性App 两端由不同人开发最容易出现的坑往往不是复杂算法而是细节约定不明确。风险表要在评审前写清楚每条带一个应对动作风险场景对策多端权限不一致iOS 可以删除订单安卓不行在权限附表对应单元格写清两端行为一致时间格式不一致客户端传“2025-06-01 10:00”服务端按 UTC 解析统一传 ISO8601 并带时区例如2025-06-01T10:00:0008:00重复提交用户双击“创建订单”产生两笔订单客户端禁用按钮服务端校验幂等键idempotent_key空字符串用户昵称为空导致列表布局错乱规定null与都展示默认头像和“未设置昵称”风险表放进需求说明书的风险章节每一条都指定负责人。幂等键是支付类 App 的必选项不能只靠前端防抖后端必须在创建订单时校验同一个idempotent_key只能成功一次。5. 从 PRD 到开发评审现场核对需求和验收标准5.1 一份可执行的需求评审议程不要一上来就放原型图过每张页面那会让评审变成“你们看看视觉对不对”。建议在评审前让开发先通读 docx 10 分钟然后按照下面的议程走产品经理朗读核心路径 2 分钟确保所有人理解业务背景后端逐行过状态表和权限表检查是否允许非法迁移客户端和测试共同核对页面状态表看四态是否全部覆盖产品经理逐条朗读 Must 功能的验收标准所有待确认问题记录到“待确认问题表”写清负责人和解决日期待确认问题不直接改正文而是追加在 docx 末尾保证原始内容可追溯问题编号问题描述提出人负责人解决状态Q-01退款到账周期是 T1 还是 T2后端产品待确认Q-02取消预约是否自动退款测试业务待确认5.2 用“给定-当-则”重写验收标准评审现场最有效的动作是把所有“描述性验收”改成 Given-When-Then。比如“用户点击预约后如果失败要有提示”改写为需求IDGivenWhenThenF-001用户未登录正在课程详情页点击预约按钮跳转登录页登录成功后回到原课程详情页F-002用户已登录但教练当前时段已满点击预约按钮页面提示“该时段已满”按钮置灰改写过程中如果发现“Given”条件在需求说明书里找不到来源那就是漏了前置状态。能写成 When-Then 的需求测试可以直接转成用例写不出来的需求大概率还没想清楚。5.3 版本变更记录怎么写在 docx 里docx 最大的优势是适合版本管理。在文档第二阶段加一张“变更记录”表每次改动追加一行而不是覆盖原描述。变更记录表和正文表格不同它更像项目的审计日志。每次评审完更新版本号和状态让开发知道当前看到的哪一版是准的。一个常用的快速校验命令可以在发版前检查需求文档是否包含足够表格python -c from docx import Document; dDocument(APP产品需求说明书.docx); print(tables:, len(d.tables)); print(headings:, len([p for p in d.paragraphs if p.style.name.startswith(Heading)]))逻辑说明这条命令直接读取 docx 文件统计表格数量和标题数量。表格数少于 10 个可能说明需求拆解不够标题数超过 40 个可能说明需求碎片化需要合并。参数说明startswith(Heading)只统计通过样式设置的标题手工加粗的段落不会被算进去这恰好能暴露文档是否误用直接字体加粗代替标题样式。6. 让 APP 产品需求说明书自己会说话用主场景脚本做回归验证6.1 把核心路径写成一条可执行脚本把文档合上在一张白纸上写下这条路径游客进入首页 → 注册登录 → 选择课程 → 创建预约 → 支付 → 查看预约单 → 取消或退款。每一步都要能在需求说明书里找到对应的章节、状态迁移和验收标准。找不到的直接标成缺口找得到的打勾。这个动作看似原始但它能在评审会之前拦截至少一半的“文档没写完”问题。6.2 用轻量命令检查 docx 结构验证整份说明书时可以写一个临时脚本同时检查表格数量、标题数量和是否包含状态表python - PY from docx import Document doc Document(APP产品需求说明书.docx) print(tables:, len(doc.tables)) print(headings:, len([p for p in doc.paragraphs if p.style.name.startswith(Heading)])) for t in doc.tables: first_row [c.text for c in t.rows[0].cells] if 状态 in first_row and 动作 in first_row: print(状态表: 已找到) PY逻辑说明脚本遍历所有表格检查表头是否包含“状态”和“动作”。如果没找到说明第 2.3 节的状态机没有落进 docx后续开发大概率靠口头沟通。参数说明表头名称要和你实际用的列名一致比如写的是“当前状态 / 动作 / 目标状态”脚本里的关键词也要对应调整。6.3 导出 PDF 做逐页评审docx 用于编辑PDF 用于评审。把版本状态改成“已确认”后导出 PDF并在最后一页附加“评审疑问收集表”每个人都只往表格里写“页码 疑问 需求ID”不要直接改正文。收集表收集满后产品经理逐条关闭每关闭一条就在变更记录里加一行。这个过程下来评审意见和结论都留在文档里自然形成可追溯的 APP 产品需求说明书。本文还有配套的精品资源点击获取