# PRD: 订阅与每日运势推送功能 ## 1. 概述 ### 1.1 产品名称 万事宜 — 订阅与每日运势推送 ### 1.2 目标用户 已输入生辰信息并使用紫微斗数运势功能的微信小程序用户 ### 1.3 核心价值 用户无需手动打开小程序,每日自动收到个性化运势推送,提升日活与用户粘性 ### 1.4 约束条件 - 仅限微信小程序平台 - 依赖微信云开发(CloudBase)作为轻量后端 - 推送内容由现有算法本地/云端生成,无需外部数据源 ## 2. 功能范围 ### 2.1 范围内(MVP) | 功能 | 说明 | |------|------| | F1: 订阅入口 | 在运势页面提供订阅入口,引导用户订阅每日推送 | | F2: 微信订阅消息授权 | 调用 `wx.requestSubscribeMessage` 获取用户授权 | | F3: 生辰信息上传 | 将用户生辰信息上传至云数据库,用于云端生成运势 | | F4: 每日定时推送 | 云函数定时触发器每日 07:00 执行推送 | | F5: 推送内容生成 | 云函数调用共享算法包生成当日运势 | | F6: 推送时间配置 | 用户可自定义推送时间(默认 07:00) | | F7: 取消订阅 | 用户可随时取消推送,清理云数据库订阅记录 | | F8: 共享算法包抽取 | 将运势算法纯函数层抽取为独立 npm 包 | ### 2.2 范围外(后续迭代) | 功能 | 说明 | |------|------| | 黄历每日推送 | 未来可扩展为推送当日宜忌 | | 多模板推送 | 支持不同模板(运势、黄历、提醒等) | | 多平台推送 | H5 浏览器推送、App 原生推送 | | 推送统计 | 推送到达率、点击率分析 | ## 3. 用户故事 ### US-01: 订阅推送 > 作为已设置生辰信息的用户,我希望在运势页面看到订阅入口,一键订阅每日运势推送,从而每天自动收到我的运势信息。 **验收标准**: - [ ] 用户进入运势页面时,显示订阅入口(仅未订阅时) - [ ] 点击订阅后,弹出微信订阅消息授权弹窗 - [ ] 用户授权后,生辰信息上传至云数据库 - [ ] 订阅成功后显示"已订阅"状态和每日推送时间 - [ ] 未输入生辰信息的用户提示先设置生辰信息 ### US-02: 每日推送接收 > 作为已订阅用户,我希望每天在固定时间收到服务通知,查看当日的综合运势、各维度运势和幸运信息。 **验收标准**: - [ ] 每日在用户配置的时间(默认 07:00)收到服务通知 - [ ] 推送内容包含:日期、综合运势评分+等级、各维度运势、幸运色+数字 - [ ] 推送内容与小程序内当日运势一致 - [ ] 同一用户每日不会收到重复推送 ### US-03: 推送时间配置 > 作为已订阅用户,我希望在订阅管理页面修改推送时间,从而适配我的作息习惯。 **验收标准**: - [ ] 订阅管理页面显示当前推送时间 - [ ] 用户可修改推送时间(步长 30 分钟) - [ ] 修改后云端同步更新 - [ ] 修改后下一次推送按新时间执行 ### US-04: 取消订阅 > 作为已订阅用户,我希望在订阅管理页面一键取消订阅,从而不再收到每日推送。 **验收标准**: - [ ] 订阅管理页面提供"取消订阅"按钮 - [ ] 取消后删除云端订阅记录 - [ ] 取消后不再收到推送 - [ ] 取消后订阅入口重新显示 ## 4. 架构与数据流 ### 4.1 系统架构 ``` ┌──────────────────────────────────────────────────────┐ │ 微信小程序 │ │ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │ │ │ 运势页面 │ │ 订阅管理页面 │ │ 共享算法包 │ │ │ │ (订阅入口) │ │ (时间/取消) │ │ (本地使用) │ │ │ └──────┬───────┘ └──────┬───────┘ └───────────┘ │ │ │ │ │ │ └────────┬────────┘ │ │ │ │ │ wx.cloud.callFunction │ └──────────────────┼─────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────┐ │ 微信云开发 (CloudBase) │ │ ┌────────────────────┐ ┌────────────────────────┐ │ │ │ 云函数: subscribe │ │ 云函数: dailyPush │ │ │ │ - 存储订阅关系 │ │ - 定时触发器 07:00 │ │ │ │ - 存储生辰信息 │ │ - 调用共享算法包 │ │ │ │ - 更新推送时间 │ │ - 生成运势内容 │ │ │ │ - 取消订阅 │ │ - 调用 subscribe.send │ │ │ └────────────────────┘ └────────────────────────┘ │ │ ┌────────────────────────┐ │ │ │ 云函数: unsubscribe │ │ │ │ - 删除订阅记录 │ │ │ └────────────────────────┘ │ │ ┌────────────────────────────────────────────────┐ │ │ │ 云数据库: subscriptions 集合 │ │ │ │ { openid, templateId, birthInfo, pushTime, │ │ │ │ pushEnabled, subscribedAt, lastPushDate } │ │ │ └────────────────────────────────────────────────┘ │ │ ┌────────────────────────────────────────────────┐ │ │ │ 共享算法包 @everything-suitable/algorithm │ │ │ │ (云函数依赖,纯 TypeScript 计算) │ │ │ └────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────┘ ``` ### 4.2 数据流 **订阅流程**: ``` 1. 用户点击"订阅每日推送" 2. 小程序检查用户是否已输入生辰信息 3. 调用 wx.requestSubscribeMessage 请求授权 4. 用户授权 → 小程序调用云函数 subscribe 5. 云函数将 { openid, birthInfo, templateId, pushTime } 写入云数据库 6. 返回成功 → 小程序 UI 更新为"已订阅" ``` **每日推送流程**: ``` 1. 云函数定时触发器 (dailyPush) 在每日 07:00 触发 2. 查询云数据库 subscriptions 中 pushEnabled=true 且 lastPushDate != today 的记录 3. 对每条记录: a. 使用 birthInfo 计算 ZiweiChart(本地算法) b. 使用 chart + today 调用 generateDailyFortune c. 格式化推送内容(模板字段绑定) d. 调用 wx.subscribeMessage.send 发送 e. 更新 lastPushDate = today ``` ## 5. 共享算法包定义 ### 5.1 包结构 ``` packages/algorithm/ ├── package.json ├── tsconfig.json ├── src/ │ ├── index.ts # 导出入口 │ ├── fortuneStrategy.ts # 运势生成策略 │ ├── fortune.ts # 综合运势生成 │ ├── ziweiAlgorithm.ts # 紫微算法基础 │ ├── types.ts # 类型定义 │ ├── enums.ts # 枚举定义 │ └── __tests__/ # 算法测试 │ └── fortuneStrategy.test.ts └── README.md ``` ### 5.2 导出接口 ```typescript // 核心导出 export { generateDailyFortune } from './fortuneStrategy' export { generateComprehensiveFortune } from './fortune' export { calculateLuckyColor, calculateLuckyNumber, calculateLuckyDirection } from './ziweiAlgorithm' export { determineLuckLevel, calculatePalaceScore } from './ziweiAlgorithm' export type { DailyFortune, ZiweiChart, PalaceFortune } from './types' ``` ## 6. 微信订阅消息模板 ### 6.1 模板申请 在微信小程序管理后台 → 功能 → 订阅消息 → 公共模板库,搜索并选用合适的模板。 ### 6.2 推荐模板字段映射 | 模板参数 | 值 | 说明 | |---------|-----|------| | `date1` | `{{data.date1}}` | 日期,格式:2026年8月14日 | | `thing2` | `{{data.thing2}}` | 综合运势,格式:综合评分85分,等级:吉 | | `thing3` | `{{data.thing3}}` | 各维度运势摘要 | | `thing4` | `{{data.thing4}}` | 幸运信息,格式:幸运色红色 幸运数字7 | ### 6.3 推送内容示例 ``` 📅 2026年8月14日 🌟 综合运势:85分(吉) 📊 事业:今日事业运势吉显,适合处理重要工作事务 财运:财运亨通,可进行投资理财 感情:感情运势良好,适合表达爱意 健康:身体状况良好,精力充沛 🍀 幸运色:红色 幸运数字:7 ``` ## 7. 阶段与里程碑 | 阶段 | 内容 | 预估工时 | 依赖 | |------|------|---------|------| | **M1: 共享算法包** | 抽取算法为独立包,确保云函数可调用 | 2d | 无 | | **M2: 云开发环境** | 开通微信云开发,创建数据库、云函数、定时触发器 | 1d | M1 | | **M3: 订阅功能** | 小程序端订阅入口 + 订阅管理页面 + 云函数 | 2d | M2 | | **M4: 每日推送** | 云函数 dailyPush 实现 + 定时触发器配置 | 1.5d | M2+M3 | | **M5: 测试与验收** | 集成测试 + 推送验证 + 异常处理 | 1.5d | M4 | ## 8. 验收标准 ### 8.1 功能验收 | # | 验收项 | 预期结果 | |---|--------|---------| | 1 | 未输入生辰信息时订阅 | 提示用户先设置生辰信息 | | 2 | 首次订阅流程 | 微信授权弹窗 → 生辰信息上传 → 订阅成功 | | 3 | 每日推送触发 | 用户在配置时间收到服务通知 | | 4 | 推送内容正确性 | 推送内容与小程序内当日运势一致 | | 5 | 推送时间修改 | 修改后下次推送按新时间执行 | | 6 | 取消订阅 | 删除云端记录,不再收到推送 | | 7 | 重复推送防护 | 同一用户每日仅收到一次推送 | | 8 | 订阅消息过期 | 用户重新订阅后恢复正常推送 | ### 8.2 非功能验收 | # | 验收项 | 预期结果 | |---|--------|---------| | 1 | 云函数执行时间 | < 3s/用户(含算法计算) | | 2 | 订阅消息到达率 | 微信官方保障,不做额外要求 | | 3 | 用户数据安全 | 生辰信息仅用于推送计算,不另作他用 | ## 9. 术语表 | 术语 | 定义 | |------|------| | 微信订阅消息 | 微信小程序提供的消息推送能力,用户订阅后可在"服务通知"中收到消息 | | 微信云开发 | 微信生态内的 Serverless 云服务,提供云函数、云数据库、存储等 | | 云函数 | 运行在微信云端的 Node.js 函数 | | 定时触发器 | 云函数的 cron 触发机制 | | 共享算法包 | 从应用中抽取的纯算法模块 | | 服务通知 | 微信内用户接收订阅消息的入口 |