简介:面向旅游小程序产品设计与开发团队,这份《红人》旅游小程序产品需求文档以O2O旅游服务平台为背景,围绕“能看、能买、能传播”的核心目标,完整梳理了从全局功能逻辑、订单流程、业务角色到产品信息结构、原型图与排期草稿的整套PRD内容。资源包为1个可编辑的docx文档,大小约5.27MB,便于产品经理、研发与运营人员直接查阅和二次调整。文档细化到商城主页6个模块的跳转规则、商品详情的客服与预订逻辑、订单6种状态及超3小时自动失效机制,还介绍了资讯图文表1对多存储、订单主表存地址库ID等建模思路,以及模块间高内聚低耦合、功能粒度按MECE划分的方法。目前已有258人学习下载,适合初入旅游赛道的产品新人,以及需要快速搭建同类小程序参考框架的团队。
1. 先说清楚「红人」两个字:这篇 PRD 的题眼不在旅游,而在内容与交易的粘合
「红人」旅游小程序,本质上不是把携程的酒店机票搬进微信里,而是让一个旅行达人成为商品的一部分。用户是先看到红人发布的图文视频、被某个目的地或某个行程安排打动,再进入小程序完成咨询、下单、支付和核销。这个行为路径和传统 OTA 的「搜索—比价—下单」完全不同,所以文档里的页面结构、商品字段和订单流程,都不能照抄商城模板。
这类 PRD 最容易被开发团队挑战的地方,其实是三个词:内容、社交、交易。红人动态要不要做得像社区?商品详情是挂在动态下面还是独立成页?核销码该由谁出示、谁扫?这些边界如果不在一开始给出明确答案,前端会按内容型产品做,后端会按电商型产品做,两边对不上。所以我的建议是,拿到「红人旅游小程序」这类需求时,先不要急着画页面,而是把三类用户和它们之间的流转关系理清楚,再把边界钉死。这篇内容按产品拆解、核心链路、小程序容器适配、数据与推荐模型、落地验证的顺序,把一份能直接开发执行的 PRD 该有的细节展开讲。
2. 从使用场景切功能边界:红人、用户、商家三个入口谁能先进 MVP
2.1 为什么先定入口而不是先画页面
「红人旅游小程序」和普通电商小程序的本质区别,在于平台上有三类用户:红人负责生产内容,用户负责消费和购买,商家负责提供线路、酒店、门票等履约资源。三个角色的诉求完全不同,如果直接进原型阶段,容易出现两种跑偏:一是页面画了一大堆,但没有任何一条链路能跑通;二是只做了用户下单,红人和商家都靠人工在微信里对接,小程序变成一张电子传单。
常见做法是先按角色拆出入口,再对每个入口做场景枚举。红人端关注的是内容发布效率、已成团订单和收益可见性;用户端关注的是内容可信度、行程匹配度和支付便捷性;商家端关注的是库存可控、核销闭环和结算清晰。把这三类诉求放到同一张表格里,才能看出哪些功能是地基,哪些是可以放二期再做的。
2.1.1 三个端的最小页面清单
| 角色 | 核心页面 | MVP 是否包含 | 取舍理由 |
|---|---|---|---|
| 用户 | 信息流/发现页 | 是 | 内容种草是流量入口 |
| 用户 | 红人主页 | 是 | 建立信任和关注关系 |
| 用户 | 行程详情页 | 是 | 同时承载内容和购买入口 |
| 用户 | 订单确认/支付 | 是 | 闭环的必要环节 |
| 用户 | 我的订单/核销码 | 是 | 履约凭证 |
| 红人 | 内容发布/草稿箱 | 否(P1) | 首版可后台代发 |
| 红人 | 收益看板 | 否(P2) | 涉及分账体系 |
| 商家 | 商品/SKU 管理 | 是(简化版) | 没有库存就无法售卖 |
| 商家 | 核销/验券工具 | 是 | 线下履约的核心动作 |
这张表的用途不是限制想象力,而是让产品、前端、后端第一轮排期时有一份共同语言。MVP 我一般建议压在「用户看到内容、用户付钱、商家把订单核销掉」这条最小闭环上,红人发布可以先用管理后台手动录入,等跑通后再开放移动端发布。
2.2 用场景故事把功能优先级钉死
画完清单后,要把功能串回场景里验证一次。这里我给一个常用的场景模板:一位用户在小红书上刷到某位红人的川西旅行 vlog,文中挂着小程序码,用户扫码进来,在小程序里看到同一篇图文和对应的 6 天 5 晚行程,日期可选、价格透明,支付定金后收到入群邀请,出行当天在集合点出示订单码,商家扫码核销,行程结束后订单状态变成已完成,用户可以在订单页给红人写评价。
这个场景里每一步都对应一个具体功能:扫码进入后的落地页、图文详情和商品详情的合并或拆分、团期选择器、定金/尾款两种支付方式、核销二维码、订单状态流转。写 PRD 时每一个动作都要给到明确的页面路径和数据字段,不能只写「用户可购买」。我会在第三章把状态流转单独展开,因为这是后端开发争论最多的地方。
2.3 MVP 里不建议出现的三个功能
第一是拼团裂变。旅游产品受团期和库存约束,拼团逻辑会跟库存扣减打架,首版做会显著拖慢开发节奏。第二是即时 IM 聊天。用户想咨询航班、酒店、集结时间,用表单收集需求比做客服对话框更快落地。第三是模板消息的过度打扰。订阅消息允许用户取消,营销味太重会把刚建立的信任消耗掉。
另外,小程序备案在这个阶段就要启动。备案备注信息怎么填,会影响审核周期,填法我在第四章给出一个可以参考的写法,这里先记住一条:把「红人内容展示、旅游产品在线交易、订单核销」这三个业务描述写清楚,不要只写「技术服务」。
3. 从种草到成单:内容、商品、订单三条链路如何在 PRD 里咬合
3.1 内容页和商品页的字段映射
红人旅游小程序最容易被开发挑战的问题,是「内容字段」和「商品字段」到底分开还是合并。我的建议是:底层完全拆成内容表、商品表、关联表,前台上让用户无感。内容表存文案、图片、视频、标签、点赞评论数;商品表存团期、价格、库存、出发地、目的地、适用人群;关联表把某篇动态和某个 SKU 拴在一起。这样同一个行程可以挂在不同红人的多篇动态下,同一个红人的一篇长文也可以带三个不同出发日期。
// 示例:内容与商品的关联结构(JSON 层面的示意) { "content_id": "ct_102939", "author_id": "hr_0088", "product_id": "pd_55012", "scene_type": "travel_note", // 内容类型:攻略/视频/直播回放 "publish_status": "on_shelf", // 上架状态:draft/on_shelf/off_shelf "audit_status": "approved", // 平台审核状态 "topic_tags": ["川西", "自驾", "6天5晚"], "linked_sku": "sku_group_20260718" }这段结构是在向开发传达:内容与商品是主子表关系,而不是平铺在同一张表里。字段publish_status和audit_status必须分开,因为红人草稿不一定过审,过审的商品也不一定立即上架,两个状态混在一起,运营后台会非常难排查。
3.2 团期与库存:别把「库存总数」当成可售数
旅游商品和普通实物商品最大的差异,在于同一商品的不同出发日期库存独立。一个「6 天 5 晚川西线」可能有 7 月 18 日、7 月 25 日两个团期,一个满员、另一个还剩 5 个名额,PRD 里必须写成「商品 → 团期 → 价格 → 库存」四级结构。
每个团期的状态建议用这几个值:可预订、即将满员、已满员、待确认、已出发、已结束。当库存剩余 3 个以内时,前端详情页应该给出明确提示,并禁止继续下单。这里的核心坑是超卖:用户在确认订单页停留时,库存可能已经被别人买走,所以提交订单接口必须做二次校验,返回「该团期已满员」的错误码,PRD 里要把这条错误提示写在明处。
3.2.1 订单状态机不能只画一条直线
WAIT_PAY(待支付) ——> PAID(已支付) ——> CONFIRMED(已确认) ——> TRAVELLING(出行中) ——> FINISHED(已完成) | | | | +——> CANCELLED +——> REFUNDING +——> CANCELLED +——> REFUNDING很多 PRD 把状态机画成一条单行道,但真实场景里退款、改期、取消会发生在多个节点。支付后未确认前,用户可以申请取消;确认后出行前,用户可以申请退款,但要扣除一定比例违约金;出行中取消则按协议只退未消费项目。每个状态下「用户能看到什么按钮、商家能做什么操作」都要在文档里对应上,我一般会专门用一页表格列这个。
3.3 核销流程:谁出示码、谁扫码,要写得像操作手册
「uniapp 小程序扫码功能」在这个项目里最常见的落点是核销。要提前定义清楚:核销是用户出示动态二维码,还是商家使用自己的小程序扫码?我建议采用「用户展示、商家扫」的模式,因为商家端通常只有一两个管理员,用户端则是全体游客,培训成本更小。
核销码必须是动态的,内容可以只是order_id + 随机串 + 过期时间,不要直接用订单号做静态二维码。核销接口要校验三个条件:订单状态必须是 CONFIRMED 或 TRAVELLING,核销码未被使用过,当前时间在有效期范围内。订单在核销完成后要把状态改为 TRAVELLING 或部分核销,因为一个订单可能包含多个子项目,比如第一天接机、第二天酒店、第三天门票,必须支持多次核销。
3.4 支付与分账的边界
支付环节要区分三种资金流向:用户付给平台的定金或全款、平台与商家的结算、平台给红人的分佣。微信小程序的交易担保能力和分账能力并不等同,分账往往要借由微信支付的二级商户或服务商模式实现。如果首版不想碰分账合规,可以先把钱全部收进平台主体,结算线下月结,但 PRD 里必须预留分账比例字段,否则二期上线时数据库要加字段,回填历史数据很痛苦。
4. 小程序容器适配:导航栏高度、动态标题、备案与审核细节
4.1 自定义导航栏高度不能写死 64px
红人旅游小程序的一大视觉特征是沉浸式头图,行程详情页的导航栏要和封面融为一体,所以多数页面要设置"navigationStyle": "custom"。但定制导航栏后,状态栏高度、胶囊按钮位置都会交给前端自行计算。不同机型差距很大:iPhone 刘海屏状态栏约 44px,普通安卓机约 24px,胶囊按钮的位置也不一致。
// 微信小程序端动态计算导航栏总高度 const getNavBarHeight = () => { const sysInfo = wx.getWindowInfo(); const capsule = wx.getMenuButtonBoundingClientRect(); const statusBarHeight = sysInfo.statusBarHeight || 44; const navBarHeight = (capsule.top - statusBarHeight) * 2 + capsule.height; return { statusBarHeight, navBarHeight, totalHeight: statusBarHeight + navBarHeight }; };这是微信小程序处理导航栏的通用方案:用wx.getMenuButtonBoundingClientRect拿到胶囊按钮相对屏幕顶部的位置和高度,反推出导航栏高度,而不是拍脑袋写死一个像素值。需要注意wx.getWindowInfo()是较新的 API,部分老基础库没有,PRD 里应注明最低基础库版本。如果是 uni-app 工程,可以包一层统一封装,页面只调getNavBarHeight()拿到总高度,动态下发给自定义组件。
4.2 小程序动态设置标题:三个页面必须做
在小程序里,navigationBarTitleText通常写死在页面配置里,但红人旅游小程序的场景更复杂。第一是红人主页:用户从 A 红人的视频里点进来,导航栏显示「A 的主页」,但页面组件是复用的;第二是订单详情页:用户从不同入口进入,导航栏应该显示「订单详情」还是「核销码」;第三是发现页向下滚动时,标题可以动态切换成当前分类名。
实现方法很简单,微信端用wx.setNavigationBarTitle,uni-app 端用uni.setNavigationBarTitle,把title从接口返回的数据里读取。PRD 里要写清楚的是触发时机:页面 onLoad 时读取路由参数里的author_name并设置标题,而不是等接口返回后再设置,否则会出现短暂的白屏标题。
4.3 小程序备案备注信息怎么填:一个能用且不给自己埋坑的写法
小程序备案现在是上线前的重要步骤,备注信息填不好会被退回。以微信小程序为例,备案信息里需要说明小程序的简介和备注,「红人旅游小程序」建议填写:基于红人内容的旅游产品展示与在线交易平台,面向用户提供旅游线路、门票、酒店预订及订单核销服务;面向商家和红人提供产品上架与内容发布功能。如果小程序涉及用户上传内容(红人发布动态),则需要在备注里说明设置了内容审核机制,避免备案审核时被归为 UGC 社区而要求额外资质。
这里有一个容易踩的坑:只填写「电子商务」会被认为范围过泛,只填写「旅游服务」又可能被要求提供旅行社业务经营许可证。内容展示加上交易服务是比较稳妥的定位描述,具体以微信公众平台当前要求为准,正文要写在 PRD 的合规检查清单里。
4.4 扫码进小程序的场景参数处理
用户接触红人旅游小程序的渠道很杂:分享卡片、公众号文章、线下海报、商家核销台。微信小程序的scene参数就是来区分这些场景的。从码进入时scene里通常带红人 ID 或商品 ID,PRD 应要求前端在 App onLaunch 时同步解析场景值,并埋点记录「用户从哪个红人的哪个渠道进来」。这个字段直接决定后续分佣结算和渠道投放效果,建议应用层自己拼接参数,不要完全依赖微信的scene原始值,因为不同的码可能被微信编码成不同格式,解析逻辑分散在各处后患无穷。
5. 把「红人」变量建模成一等公民:数据字段、推荐逻辑与埋点设计
5.1 红人表与内容表的字段边界
很多旅游小程序把红人退化成「商品详情页里的一行文字介绍」,这是对需求的浪费。红人应该是独立的主数据,拥有自己的表:author_id、nickname、avatar_url、verified_type(认证类型,比如旅行博主/摄影博主/本地向导)、follower_count、preferred_destinations(偏好目的地标签)、avg_rating(用户评价均分)。内容表和红人表通过author_id关联,商品表和内容表通过关联表连接。
这份结构允许后期做很多运营动作:按红人维度拉取转化率、按目的地标签聚合推荐、给高评分红人打标。如果首版就把红人信息塞进商品表里,之后做推荐系统时数据都取不出来,等于推倒重来。
5.2 轻量推荐逻辑:不需要算法团队也能做
推荐不用一开始就用深度学习,最常见的冷启动做法是「标签 + 热度」的加权排序。红人发布内容时选择目的地标签,用户浏览时收藏或下单也会留下带有目的地标签的数据。给用户算一组偏好向量,再和候选内容算余弦相似度,加上一个时间衰减因子,就能得到一个可用的推荐列表。
function scoreContent(userTags, contentTags, popularity, publishedTs) { // userTags: 用户近30天互动过的高频标签, 如 ['大理','温泉'] // contentTags: 内容发布时填写的标签 const common = userTags.filter(tag => contentTags.includes(tag)).length; const tagScore = common / Math.sqrt(userTags.length * contentTags.length); const hoursSincePublish = (Date.now() - publishedTs) / 3600000; const decay = Math.pow(0.98, hoursSincePublish); // 时间衰减 return tagScore * 0.7 + Math.log(popularity + 1) * 0.3 + decay; }这段代码体现的是推荐逻辑的骨架:标签相似度占七成权重,内容热度占三成,再叠加时间衰减。Math.log是为了削弱爆款内容的绝对热度优势,避免推荐列表被单条爆文霸榜。实际项目里这个函数对应后端一个 Redis 缓存的服务,用于发现页信息流的粗排,PRD 阶段需要明确的是:用户偏好标签从哪些行为中获取、内容标签如何维护、粗排结果如何混入人工置顶内容。
5.2.1 埋点事件表要跟着需求清单走
埋点设计不能等开发完再补。信息流页要埋曝光和点击,行程详情要埋加入购物车和支付点击,订单支付要埋成功和失败原因,核销页要埋扫码结果。事件名建议统一风格,比如content_show、content_click、order_submit,同时带上author_id、content_id、scene三个公共参数,这样才能算出来一个红人的真实带货率,而不仅仅是阅读量。
| 事件名 | 触发时机 | 必须携带参数 | 统计价值 |
|---|---|---|---|
| content_show | 内容曝光 | content_id, author_id, scene | 红人流量池 |
| content_click | 点击进入详情 | content_id, author_id | 内容吸引力 |
| order_submit_success | 提交订单成功 | product_id, sku_group_id, price | 转化漏斗 |
| pay_success | 支付成功 | order_id, pay_amount | 最终成单 |
| verify_success | 核销成功 | order_id, verify_scene | 履约完成 |
这张表可以直接贴给前端埋点同事,也可以作为后端接口日志的规范。这里要注意verify_scene和 4.4 的scene是两回事,前面的scene是用户从哪个渠道进来,后面的verify_scene是核销现场的信息,比如「景区门口」「酒店前台」,别混用。
5.3 订阅消息与「回访」的关系
微信小程序的订阅消息是一把双刃剑。用户支付成功后,可以引导用户订阅「行程提醒」和「审核结果通知」。我建议在 PRD 里把订阅时机放在两个节点:支付成功页弹窗订阅「出发通知」,行程结束后引导订阅「红人新内容上架」。前者服务履约,后者服务复购。不要一进来就弹订阅授权,新用户还没信任你,弹窗只会直接劝退。
6. 收尾阶段:用一份「异常流检查清单」确认 PRD 真的可以被开发接手
需求评审时最容易漏掉的是异常路径。红人旅游小程序的异常流比普通电商更多,我建议团队在提测前走一遍下面的自检:同一个团期最后一人在支付中途退出,库存释放了吗;用户在下单时切到后台超过五分钟,订单还能提交吗;红人内容过审后商品被下架,前端详情页展示什么;核销码被截图转发给另一个人,商家扫码后提示什么;用户退款后红人的分佣记录怎么处理。
这里的要点是,PRD 里每个功能至少写一条对应的错误码和提示文案。库存不足返回STOCK_NOT_ENOUGH,订单状态不允许核销返回ORDER_STATUS_INVALID,内容审核不过返回CONTENT_REJECTED。前端统一弹 toast 展示后端返回的 message,后端统一维护错误码表。比如核销接口的错误码可以这样约定:
{ "code": 401023, "message": "核销码已失效,请检查订单状态" }错误码的区间要提前规划,400000 以上是业务错误,500000 以上是系统错误。PRD 阶段把错误码表写出来,能让前端和后端在联调前就对齐边界条件,而不是联调时才讨论「这句提示文案该谁出」。
另外一个实用技巧是把 PRD 里的每一个页面和功能点建立编号,例如PG-01 发现页信息流、FN-03 团期库存校验。开发提测时直接说「FN-03 通过」,测试用例也按同一编号组织,需求和缺陷的追溯会清晰很多。用这个方式把 PRD 从一篇描述性质的文章,变成一份可逐条验收的工程约束文档,评审和排期的效率会明显不一样。
本文还有配套的精品资源,点击获取