首页 / 资讯中心 / 文章详情

经期预测小程序开发全指南:算法设计与技术架构分享

经期预测小程序开发全指南:算法设计与技术架构分享 ★ FEATURED ARTICLE
去年底我接了一个特别的项目给某健康管理团队做一个女性健康月经例假预测系统小程序。需求描述就一句话——“帮女生记录经期预测下次什么时候来提前几天提醒”。听起来很简单但真正把“预测”这两个字做出来、做得准、做得让用户愿意天天打卡远比想象中复杂。这篇文章想完整分享这个项目的设计与实现过程从需求拆解、算法设计、技术选型到踩坑实录给正准备做经期管理类应用的开发者一份可以直接参考的方案也给想了解这类产品背后的逻辑和周期预测科学性的人一个落地视角。老实说市面上类似的经期预测App一大堆有的做得极其复杂社区、商城、课程全塞进来反而把核心功能挤到角落。我当时跟团队说得很直白我们不做大而全只做一个轻量、准确、诚实的小程序。例假预测的核心价值就两个一是记录足够快二是预测结果有据可依。把这两点打透就已经能留住大多数用户。后面的整个设计与开发都是围绕这两个目标展开的。1. 项目整体设计与需求拆解1.1 用户画像与核心痛点分析先聊用户。经期记录类产品的使用者不只是女生本人还有一类常被忽视的人群——伴侣和父母。我调研时发现有相当一部分男性用户会下载经期记录App用来关心另一半的身体状况。但大多数产品的隐私设计只考虑了女性本人导致这部分用户的使用体验很别扭。我在数据权限设计里做了一个层级生理数据只有本人可见日历层面的状态可以授权共享。这个设计后来被验证是加分项。真正的核心用户还是月经周期不规律或者有备孕/避孕需求的女性。她们的痛点非常具体记不住上次例假是什么时候来的每次被医生问到就尴尬。周期不规律靠脑子推算永远算不准总要翻聊天记录找日期。出门在外突然来例假没有准备极度焦虑。想要宝宝的人需要准确掌握排卵窗口但排卵试纸又贵又麻烦。针对这些痛点我的结论是这个产品不应该只是一个“记录本”它要能承担预测提醒和健康趋势分析的角色。预测的意义不是玄学而是让人有心理准备和物质准备的时间。1.2 功能范围界定与MVP设计做产品最怕的就是什么都想做。我跟团队确定了 MVP最小可用版本的功能清单原则是一切功能要么服务于快速记录要么服务于预测准确度要么服务于隐私安全感否则都不做。核心功能定下来三块第一是经期记录。这是数据源头操作必须三步以内完成。用户可以记录开始日期、结束日期、经量、经色、痛经程度、伴随症状。第二是智能预测。基于用户历史周期数据用移动平均模型计算下一次经期、排卵窗口和易孕期并在预测日期临近时通过微信订阅消息提醒。第三是日历视图与趋势分析。日历页展示历史经期区间、预测区间和排卵日趋势页展示周期长度变化、经期时长变化、症状频率统计。砍掉的功能也不少放弃社区、放弃商城、放弃个性化的皮肤系统、放弃复杂的体温计同步硬件接入成本太高MVP阶段不值得。这些功能可以通过后续版本迭代再上但第一版必须轻、快、稳。一个重要的认知经期预测类产品用户信任建立的根基是“诚实”。算法说预测7月12日来用户到了7月14日还没来产品必须主动提示“周期可能偏离预测”而不是悄悄把历史记录改掉。这种设计在别的领域可能无所谓但在健康领域隐瞒不确定性会让用户彻底失去信任。2. 预测算法与数据模型设计2.1 月经周期预测的生理学基础做预测算法前团队里有人问月经周期真的能预测吗能预测到什么程度这里需要先把生理基础说清楚因为算法不是凭空拍脑袋的而是建立在生理规律上。完整的月经周期通常以月经来潮第一天为起点到下一次来潮第一天之间的天数是一个周期。正常范围一般在21到35天平均28天。周期分为卵泡期和黄体期其中黄体期相对固定约14天这是预测排卵期的关键——排卵日大约等于下一次经期首日减去14天。那“预测下一次来潮日”本质上就是预测“下一个周期长度是多少”。这个问题的答案因人而异甚至同一个人不同时期也不同。所以算法不能只给一个固定的28天必须利用用户自己积累的历史记录来做个性化预测。数据越充足预测越准这就是记录类健康产品的滚雪球效应。2.2 核心预测算法从简单平均到加权移动平均我在第一版设计里用了一个渐进式的算法策略分两个阶段。第一阶段冷启动期少于3条历史周期记录。用户新下载App只有一条“最近一次经期开始日期”的数据此时没有足够的历史周期长度来估计个体规律。算法采用群体模板默认下一个周期长度为28天在界面上明确标注“预测基于通用规律记录3次后将个性化”。这个提示很重要它管理了用户预期避免预测不准时被迁怒。第二阶段个性化期3条及以上历史记录。算法采用加权移动平均核心思想是最近的周期对下一次预测影响更大。公式如下加权平均周期长度 Σ(周期长度_i × 权重_i) / Σ(权重_i) 其中权重_i 当前周期序号 - 历史周期序号 1近期权重更高举个例子某用户最近三次周期长度分别是 30天、28天、32天。使用简单算数平均结果是 (302832)/3 30天。但使用加权移动平均最近的32天权重最高计算结果会更倾向于31天左右。实测下来加权方案的预测偏差比简单平均小尤其对于周期有渐进变化的用户比如逐渐变长或变短的情况。预测的下一次经期首日 最近一次经期首日 加权平均周期长度。再减去14天即为预测排卵日排卵日前5天加后1天为易孕期窗口这个窗口会特别标注。提示算法里一定要加入异常值过滤。用户可能某次记错了日期或者意外提前/延后了10天以上这些极端值如果不处理会把平均周期长度拉偏。我采用了修正的IQR四分位距方法计算所有周期长度的四分位数超出 Q1-1.5×IQR 和 Q31.5×IQR 范围的记录视为离群值计算平均值时自动剔除但在原始记录中保留提醒不显示预测区间。这个处理让整个预测系统稳定了不少。2.3 数据模型与本地存储设计数据设计是整个项目的地基。我给小程序设计了三个核心数据实体。用户周期档案表存储用户的基本周期特征。字段包括用户唯一标识、平均周期长度、平均经期天数、历史周期长度列表、默认提醒天数用户希望提前几天收到通知、最后计算时间。经期记录表每一条是一次经期记录的信息。字段包括开始日期、结束日期、经量等级少/中/多、痛经等级无/轻/中/重、伴随症状标签数组头痛、乏力、情绪波动、乳房胀痛等、备注文本、创建时间。每日症状打卡表非经期时用户也可以做轻量记录。字段包括日期、情绪状态开心/平静/烦躁/低落、精力值1-5、是否头疼、是否失眠。这个表的数据主要用于趋势统计帮用户找到自己的前期症状规律——比如某用户在来潮前3天总是烦躁那么预测到下次来潮日前3天App可以给她推送一条关怀文案。存储方案上我的选择是核心隐私数据全部本地存储不做云端同步。小程序本地存储能力对于这种轻量数据完全够用一条经期记录平均2KB用5年才不到100KB。云端只做一个匿名化的统计上报仅包含脱敏后的周期分布情况用于算法调优不上传用户ID、日期、症状等敏感字段。这个决策帮我们省掉了服务器成本也避开了敏感数据的合规问题。// 经期记录表数据结构示例 { recordId: uuid-xxxx, startDate: 2025-03-12, endDate: 2025-03-17, periodLength: 6, cycleLength: 30, // 距上次记录首日的间隔天数 volume: 2, // 0少 1中 2多 painLevel: 1, // 0无 1轻 2中 3重 symptoms: [头痛, 乏力], note: , createdAt: 1741680000000 }3. 技术架构与核心模块实现3.1 技术选型为什么不用原生开发在技术选型讨论中团队内部有过一轮小争论用微信小程序原生开发还是用跨端框架 uni-app 或者 Taro我的结论是选uni-app。原因很实际。我们预期的上线路径不只是微信小程序后续大概率还要上支付宝小程序和手机App至少iOS版本。如果第一版用原生开发后面两次迁移几乎等于重写。uni-app基于Vue语法生态成熟对日历、图表这些组件的支持都有现成方案。唯一担心的性能损失在核心逻辑不重的前景下完全可以忽略。架构分层上设计成三层视图层页面组件包括日历组件、表单弹窗、趋势图表、设置页。逻辑层经期预测算法模块、数据校验模块、通知调度模块。数据层基于 uni.setStorageSync 的本地数据仓库封装统一的增删改查接口。这样的好处是以后如果要把预测逻辑移植到App端只需要替换视图层算法和数据层原封不动就能复用。3.2 预测算法的代码落地整个系统里承重墙是预测模块。这块代码必须计算准确、返回结构清晰、异常处理完备。我先把核心预测函数的伪代码思路写出来// 经期预测核心算法伪代码思路 function predictNextPeriod(records) { if (records.length 0) return null; // 1. 从记录中提取历次周期长度不包含首次记录 const cycleLengths extractCycleLengths(records); // 2. 异常值过滤IQR法 const cleanLengths filterOutliers(cycleLengths); let avgCycle; if (cleanLengths.length 3) { // 冷启动期用通用规律 avgCycle 28; } else { // 加权移动平均最近记录权重更高 avgCycle weightedAverage(cleanLengths); } // 3. 计算日期 const lastStartDate records[records.length - 1].startDate; const nextPeriodDate addDays(lastStartDate, avgCycle); const ovulationDate addDays(nextPeriodDate, -14); const fertileWindow { start: addDays(ovulationDate, -5), end: addDays(ovulationDate, 1) }; // 4. 返回带置信度的预测结果 return { nextPeriodDate, ovulationDate, fertileWindow, avgCycle, confidence: getConfidenceLevel(cleanLengths.length) }; }真实代码还需要处理的细节日期加法的时区问题避免使用本地字符串做计算统一用时间戳、闰年的2月29日、记录中有包含关系的数据冗余问题。这些细节看似不起眼但任何一项没处理干净线上就会出现“预测日期差一天”的诡异bug。关于置信度我加了一个评估字段根据用于预测的历史记录数量返回 low / medium / high 三个等级。目标在界面上展示给用户看。置信度是low时页面要提示“记录不足预测结果仅供参考”high时则正常展示。果不其然这个置信度机制成了用户信任度的关键——它不是隐藏不确定性而是诚实标注反而让用户更愿意持续记录、逐步收获更准的结果。3.3 日历模块的动态渲染实现经期预测类产品日历是主战场。用户打开小程序第一眼看到的就是月度日历上面要清晰标注四种状态历史经期深色区间、预测经期浅色虚线区间、预测排卵日特殊图标、易孕期淡色圆点底纹。日历组件如果直接引用第三方库样式定制成本会很高而且很多现成组件不支持“区间着色加虚线”的组合态。所以我们决定自己封装一个月份的日历格子组件。实现思路是渲染当前月份对应的42个格子6行×7列每个格子绑定日期对象。根据日期和当前数据状态的对应关系动态计算每个格子的显示样式。核心的渲染逻辑放在一个函数里function getDateCellStyle(date, monthlyData) { // 返回样式的优先级真实经期 预测经期 排卵日 易孕期 默认 let cssClass cell-default; if (monthlyData.periodDates.includes(date)) { cssClass cell-period; // 深色实心标记 } else if (monthlyData.predictedDates.includes(date)) { cssClass cell-predicted; // 浅色虚线标记 } else if (date monthlyData.ovulationDate) { cssClass cell-ovulation; // 特殊图标 } else if (isInRange(date, monthlyData.fertileWindow)) { cssClass cell-fertile; // 淡色圆点底纹 } return cssClass; }日历性能上初始化一屏的42个格子对小程序渲染压力极小不需要虚拟列表只在月份切换时重新计算一次样式映射即可。关键成员记录一下月度切换时需要处理日期跨年和跨月边界的判断这里最容易出bug需要单测覆盖。3.4 订阅消息提醒的实现细节例假预测系统的提醒功能小程序端用的是微信的订阅消息能力。这里有一个策略问题微信的订阅消息分为“一次性订阅”和“长期订阅”长期订阅需要特定类目权限多数开发者拿不到。所以我们采用的是一次性订阅的思路每次用户完成记录后引导她授权订阅下一次提醒。等于每次授权锁定下一次预测通知的发送资格。这个策略在实践中有一个问题用户授权后如果她的下一次预测日期被修正了比如记录了一条新经期数据导致预测偏移那么这条订阅消息的发送时机也需要跟着调整。解决方案是把已授权的订阅消息模板id和预测日期绑定存储每次预测重算时检查所有绑定的订阅日期变化则重新申请消息推送。代码处理逻辑// 订阅消息调度 rememberSubscription(templateId, predictedDate, userId); // 存储后定时检查今天恰好是预测日减去“提前提醒天数”时 // 就触发 uni.subscribeMessage.send 发送提醒这里还有一个产品层面的发现提醒的提前天数不能做死。我给了用户三个选项提前1天、提前2天、提前3天。虽然功能不大但用户感知极强——她们普遍对自己的周期有不同的提前准备需求。4. 用户体验设计与隐私安全4.1 视觉设计的温柔感与信息层级经期预测类产品有它的特殊性用户使用场景往往很私人、很柔软。视觉上不能走冷冰冰的参数表风格。我们的设计语言定了三个关键词柔和、圆润、清晰。色彩上主色调选择了暖粉紫渐变不使用饱和度过高的颜色背景用米白色。日历格子里的预测区间用浅粉色虚线表示而历史真实经期用深一点的颜色填充。这样用户一眼就能分清“事实”和“预测”的视觉边界不会把预测区间当成已经发生过的时间。信息层级上用户最关心的“下次什么时候来”永远出现在首页上半部分以卡片形式展示。卡片主文字是日期副文字是距离天数比如“预计还有9天”。如果需要展示置信度就用一个小标签表示低/中/高不占用太多注意力带宽。4.2 记录操作的三步快捷交互用户记录一条经期开始最快可以三步完成打开小程序或从首页快捷卡片、点击“记一笔”、确认日期并保存。这个流程被我优化了三次核心是去掉一个“编辑页面”的步骤。我观察到很多用户只是想在来例假的第一天快速记录不需要填一堆细节。所以默认弹层只显示日期选择器和“确定”按钮具体的症状、经量、情绪等字段全部折叠在“高级选项”里。确定保存后数据立即写入本地并触发预测更新。一个常用的细节日期默认值设为“今天”用户直接点确定就完成了记录。系统记录频率显著提升改完这一版后测试用户的一周打卡完成率上升了约两成。4.3 隐私保护的合规实践女性健康属于极度敏感的个人健康数据分类隐私设计怎么强调都不为过。除了前文提到的本地存储优先策略外还有几个细节值得单独说。第一最小化授权。很多同类产品一上来就要求手机号、生日、体重、睡眠数据这个产品只要求一个“时间”信息连昵称都不需要。微信登录时用匿名标识来区分用户不与任何身份信息绑定。第二本地数据可完整导出和彻底清除。设置页提供两个操作“导出我的记录”生成本地加密文件和“清除所有数据”一键抹除。这两个看似简单的功能是用户安全感的重要组成部分也是合规审查时的关键证据。第三界面层面上明确承诺在“关于”页面写明“你的经期数据只保存在你的手机里不会上传到任何服务器”。这句话看起来简单但是在用户留存上起到了实际作用信任感是可以用文字建立的。5. 开发实战中的那些坑与排查记录5.1 时间计算时区与闰年陷阱第一个大坑出现在日期计算上。我最初用本地字符串拼接来算“加N天”在开发的模拟器上一切正常一上真机测试就出现“预测日期差一天”的问题。排查后确认是时区偏移本地时间减掉UTC偏移转时间戳时部分日期会被改变导致日期搜索错位。解决方案很统一所有日期运算统一使用时间戳毫秒数为基准只在显示层转换为日期字符串。同时封装一个 addDays 函数内部基于时间戳操作后再格式化为yyyy-MM-dd杜绝任何字符串直接参与日期数学运算。闰年边界也有过一例bug2024年是闰年2月有29天某用户在2月28日开始经期平均周期31天预测日期算到3月30日但因为在某个中间步骤里日期月份用了整数加法导致输出错误。教训是日期计算不要相信任何手动进位逻辑完全交给日期库处理。5.2 iOS与安卓端的日期组件兼容性第二次真机调试安卓端使用系统日期选择器一切正常iOS端却发现在部分机型上date picker弹出的默认格式不符合预期偶尔还会出现点击日期没有回调的问题。原因是iOS端对小程序的picker组件支持存在样式穿透类的问题某些版本下默认值格式必须匹配特定模式。规避方案不用系统picker的受控模式而是将日期选择对话框做成自定义组件用标准的button 弹出层来实现。这样两个端的行为完全一致。虽然视觉上少了一点“原生感”但稳定性和一致性更重要。5.3 订阅消息授权被用户取消怎么办微信的订阅消息授权有个磨人的特性用户如果点选了“总是保持以上选择不再询问”那么后续就无法再弹出授权弹窗。很多用户在第一次授权时随手点掉“不再询问”导致后面所有提醒都发送不了。这个问题没有完美的API方案绕过只能从产品流程上补救。我们在“设置-提醒设置”页面里增加了一个防呆提示如果检测到订阅授权被关闭页面会明确展示“提醒功能未开启”的状态卡并附上“如何开启”的操作指引前往微信设置、找到本小程序、打开通知开关。效果不算完美但至少给了用户一个自主修复的路径而不是悄悄丢失功能。5.4 用户误记录与数据回滚用户记录错误是不可避免的。最典型的场景上一次的记录忘了点“结束”按钮导致经期天数异常加长比如实际7天结束记录显示15天。如果不做处理这个错误记录会直接污染后续的周期长度计算。我设计了数据修正逻辑允许用户将某条记录标记为“修正记录”修正后的记录不参与算法计算原记录保留可追溯。同时“结束日期”如果超过21天未记录会自动默认结束并弹窗询问超过21天还带着“进行中”状态大概率是用户忘记结束了自动关闭比一直开着更符合直觉。6. 长期迭代复盘与运营层面的思考6.1 如何评估预测准确率在这个项目上线小范围测试后我一直被一个问题困扰算法看起来合理但预测准确率到底该怎么评估准确率的定义本身需要确认。我定的口径有两种一种是首日命中率预测日期与实际来潮首日完全一致的比例。实测下来在三个月的历史数据支撑情况下首日命中率约六成。如果放宽到“前后1天内”命中率能到八成以上。另一种是周期均值误差预测周期长度与实际周期长度的平均绝对误差。初始阶段误差在3.5天左右随着历史数据积累到6条以上误差能收敛到2天以内。这个收敛数据非常重要也成了产品团队激励用户持续记录的工具告诉用户“你的预测已更准了”而非仅用一个科幻数字来吸引用户留存。6.2 下一步迭代的方向项目跑通后下一阶段的路线图上有三件优先级最高的事第一是周期异常的早筛查提示——例如周期突然从28天变成45天或者经期时长连续异常延长通过简单的规则模型触发“建议咨询医生”的提醒但措辞必须保持温和不能引起焦虑第二是可选云备份——在用户明确同意并设置独立密码的前提下提供加密同步能力解决换手机场景下的数据丢失问题第三是伴侣共享查看模式——前面提到过的授权共享可以丰富关系场景的关怀价值。不过所有这些迭代都不应该动摇第一条产品原则核心数据本地化、隐私透明化、预测结果诚实化。经期预测产品的护城河不是算法多玄乎而是用户的信任感有多深。6.3 给同类项目开发者的几句真心话做这个项目让我最大的感受是技术上的复杂度其实不高真正的复杂度在产品分寸感上。说重一些是“要不要提醒”、是“怎么说”这些小巧微妙的设计决策累积起来决定了产品带给用户的是安全感还是焦虑感。如果你正准备做女性健康方向的应用我的建议是先从最小模型切入做出一个“即便只记录了一条数据也能让用户感到有用”的产品然后再慢慢加功能。算法上宁可保守也请不要花哨每个超出用户理解范围的数字都会消耗一次信任汇率。界面设计和文案要一起打磨同样是“预测日”用“预估”比“预测”柔和用“推测”比“断定”准确。这个项目从立项到第一个可用版本大概用了六周时间不算快但每一步都走得挺扎实。希望这篇复盘能帮你少走一些弯路。
阅读完成 · 觉得有帮助?
咨询建站