开发验证 · 上禾体重目标

上禾自动体重目标实现与验证

2026-09-08 · 本地实现与隔离验证完成;ai_api、store、ai_app 已提交并推送 develop_haerbin,尚未部署。

已实现手机号匹配、扫码认领及同会话后续补传自动设置体重目标。实际体重使用 weight,目标体重使用 idealWeight(结构化指标 weight_target),速度默认 0.5 kg/周。自动与手动调用同一完整保存业务;同企业用户只有一条有效目标,同一报告只成功自动保存一次。

1. 已实现行为

场景行为
手机号匹配确定本人后,检测两项体重齐全即设置目标
扫码认领本人认领成功后,两项体重齐全即设置目标
分阶段上传先体重后理想体重、先理想体重后体重均支持;从同一会话结构化指标取值,不依赖最后一份数据包
未关联或缺项未归属本人不设置;缺项等待补传,不删除当前目标或排课
保存规则自动与手动共用初始/目标体重校验、方向、速度枚举、结束日期计算、旧目标及课程软删除、新目标写入、setWeight、积分及原同步业务
默认速度自动增减重写 adjust_speed=2,代表 0.5 kg/周;相等体重沿用保持状态,速度和结束日期均为 0
每人一条有效目标两入口在应用库事务中锁定同一 user 行,再替换该企业用户的有效目标;已有异常多条有效记录也在该次保存中一并退役
同报告去重目标表保存 shanghe_session_id;成功目标以后被替换、软删除,仍保留同报告成功凭据,不能再触发重设
新报告不同有效报告按实际保存顺序分别重设;手动和设备来源没有永久优先级
无设备手动设置原请求、返回、速度选择、保存与后续使用不要求设备表、检测记录或新增来源字段;不需要设备额外配置即可手动保存
自动失败返回内部 FAILED 状态,不伪造目标成功;已提交的检测/认领保留,重扫、重复上传或修复命令可重试
失败修复不设置自动生成功能开关;shangheClaimRepair 同时报告目标状态,目标失败时不再仅凭体重同步成功返回全部完成

2. 实际改动文件

仓库/文件改动
ai_api/app/api/service/user/UserWeight.php原 weightManage 手动入口保留;新增受信任的显式用户入口,抽取完整保存方法;用户行锁保护目标替换和每日体重/积分并发;报告来源与目标同事务保存
ai_api/app/api/service/ShangheWeightGoal.php校验用户/企业/设备/报告归属,读取同报告两项指标,默认速度 2,调用完整保存业务
ai_api/app/api/service/ShangheV306.phpsyncClaimWeight 的目标处理独立于体重 raw 水位,覆盖手机号、扫码及后续补传;返回目标状态供修复命令判断
ai_api/app/command/ShangheClaimRepair.php将目标失败计入重试结果,输出 SAVED、WAITING_DATA、FAILED 或 UNAVAILABLE
ai_api/tests/ShangheWeightGoalTest.php隔离 MySQL 的手动基线、自动等价、双入口、事务/并发、排课与营养计算验证
store/db/v2/v2.35.17.sql现有目标表增加一个可空来源字段及唯一索引,无新增业务表

ai_app 未修改,原设置页及公共请求保持原状。现存登录修改保留,未拉取覆盖、暂存、提交或推送它们。方案中配套目标卡/完整回显属于另行评审的展示建议,本轮没有将这些 UI 改进混入目标保存功能。

3. 数据库迁移

在应用库 aizhct_haerbin 执行 store/db/v2/v2.35.17.sql,不是在健康库 zhct_haerbin 执行。

对象定义/作用
yoshop_user_weight_status.shanghe_session_idBIGINT NULL DEFAULT NULL;NULL 代表普通手动目标
uk_weight_goal_shanghe唯一索引 (shanghe_session_id, store_id),不包含 delete_flag,保留跨软删除的报告幂等
现有手动历史保留全部目标及历史数据;允许多条 NULL 来源的手动历史
单有效目标由手动/自动公共入口的用户行锁及替换事务保证,不能通过直接绕过服务写库破坏此约束

正式 SQL 已在专用本地 MySQL 5.6 测试库实际执行,并回读确认字段可空、唯一索引及列顺序。业务数据库尚未执行。迁移后发布新代码并刷新 PHP 常驻进程/数据库字段缓存;代码额外核验报告来源确已写入,避免旧字段缓存静默丢弃来源却返回成功。

4. 验证结果

验证结果与范围
改动前手动基线在没有设备表和没有 shanghe_session_id 列的测试库运行原手动保存,增重/减重/保持、三种速度、日期、替换、课程范围、体重及积分通过
RED 证据原手动基线通过后,首次自动用例因 ShangheWeightGoal 尚不存在失败;实现后通过
自动/手动等价相同用户初始数据与表单参数,比较目标、实际体重、积分、人员档案和出站调用;结果一致,显式报告用户不受另一人的登录缓存影响
双入口真实 ShangheV306.receive 与 ShangheClaim.bind 服务链路通过;手机号晚到 idealWeight、扫码先 idealWeight 后 weight、重复扫码/上传通过
幂等及替换同报告重复不换目标、不删新课、不重复副作用;新报告替换当前目标;手动介入后重扫已成功旧报告不再覆盖
有效目标并发本地 PHP pcntl_fork 验证同报告、两个不同报告、手动与自动三类并发;每个预期成功写入者均成功,最终只有一条有效目标,同日体重/积分仅一份
故障回滚注入体重写入故障,目标及课表软删除回滚、原每日体重保留、无成功报告来源;撤销故障后成功一次
数据/权限零、负数、非数值、非 kg、删除用户、错误用户、跨企业被拒绝;满足条件直接自动生成,之后手动仍正常
同日与跨日新报告按保存顺序处理,结果与相同输入手动保存一致;不额外添加未获确认的仅当日/旧目标保护规则
页面所需数据真实 UserWeight.info/status 回读比较通过;没有实际手机 UI 操作验证
真实按需排课UserCourse.getTodayPlan 验证增重/减重/保持、四周上限、短目标结束日、课程热量、手动自动等价、替换及重复读取
推荐计算真实 StaffPower.getWeightConsumePower/getRatio 验证目标方向与速度计算、手动自动比例相同、手动营养目标优先
原有 MySQL 集成使用原 ShangheClaimIntegrationTest 的专用库副本回归真实 UserWeight、两侧人员同步测试替身、下游拒绝、重复上传修复、手机号补偿、历史体重保护;通过
原有协议与契约二维码、旧入口兼容、V3.06 映射、协议、控制器契约、体重门控、附件存储七组测试全部通过
语法与差异改动 PHP 使用本地 Docker PHP 7.4 lint;ai_api/store 的 git diff --check 通过
独立审查只读审查确认双入口、完整共用、租户校验、锁及来源幂等,无本次新增阻塞性缺陷

详细新增测试输出:evidence/mysql-weight-goal-tests.log。测试连接仅指向本机 Docker MySQL、专用 codex_shanghe_goal_test 与 codex_shanghe_goal_regression;未加载或查询生产数据库。测试替换出站 UserApi/Serve,因此“出站行为一致”不等于真实生产餐厅或队列已联调完成。临时数据库和测试账号在验证后清理。

5. 发布与现场验收

  1. 审阅 ai_api 和 store 当前 develop_haerbin 的本地差异,按团队流程提交/发布业务代码。
  2. 先对应用库执行 v2.35.17.sql,一次性添加来源字段/索引;不要重复执行,也不要修改健康库目标之外的表。
  3. 部署 ai_api 并刷新字段缓存/常驻 PHP 进程;不需要因本功能重新发布小程序。
  4. 用一个测试用户先手动设置目标,再分别测试手机号上传与扫码认领;核对新目标、旧目标及课表软删除、实际体重、每日积分和推荐结果。
  5. 同报告重复上传/扫码、新报告重新检测、理想体重晚到各验证一次;用户目标查询应始终只有一条有效记录。
  6. 用未接设备用户验证原手动设置和三种速度;确认目标、推荐与课程继续正常使用。

本功能不新增开关;关联本人且两项指标齐全后直接按保存逻辑处理。需要版本回退时按正式发布流程处理代码,不自动还原旧目标/课程,以免覆盖用户后续操作。

6. 兼容边界与执行记录

老项目兼容性复核:普通手动设置不进入上禾入口,也不读取新增报告字段;此场景已在无设备表、无新增字段的本地MySQL基线验证。其他厂商仅沿用公共体重保存,并增加同用户串行保护。使用本版代码的上禾项目会在满足条件时启用自动目标,须先执行新SQL;未迁移时自动目标失败被捕获,已提交的检测上传和认领保留,但自动目标不会生成。不能把公共路径测试等同于所有历史项目现网已经逐个验收。

按照已确认方案,完整自动保存与手动保存保持同一业务语义。原手动方法在数据库提交前投递推荐并调用外部人员同步,这个时序未在本次重构;数据库回滚不能撤销已经发送的外部请求,不宣称跨系统原子回滚。实际生产队列消费时序、餐厅接口和手机真机仍需现场联调。

已有完成判定、到期处理和课程最多四周等逻辑保留;未顺手修改。不同报告按实际保存顺序替换;单独设备实际体重同步仍保留旧水位逻辑,而“自动设置目标”的完整保存效果与同参数手动操作一致。

业务基线:ai_api develop_haerbin/0cc1c822;store develop_haerbin/73be78c90。两仓开始前均快进拉取,未切分支、未覆盖他人文件。实现阶段未执行 commit/push/deploy;后续用户已提交并推送 ai_api 19b031d0、store 60304829b。ai_app 本地与远端登录修复已合并为 246892ba 并推送。三仓本地与远端 SHA 已核对一致,尚未部署。

组织方式:执行模式路由命中复杂集成;本机无可用 Ruflo 运行时且未提供安全隔离根,降级常规 Codex,由一个生产代码写入者、一名独立测试编写者和一名只读审查者完成。不初始化用户级配置,不把角色登记当作执行证据。本次无可用精确 Token 或完整准备时长统计,不提供估算数。