新跑步结束逻辑

作者:Jsnow

术语定义

  • .fit文件:佳明SDK生成的标准运动数据文件,包含GPS轨迹、时间戳、步数、配速等核心数据
  • 云存储TOKEN:访问云存储的临时授权凭证,有效期60分钟
  • batch_id:单次跑步的唯一标识,用于关联.fit文件、跑步记录、队列任务
  • 有效打卡:满足赛事规则(时段、距离/步数、区域等)的跑步记录

角色与职责

  • APP端:生成fit文件、获取云存储TOKEN、上传文件、调用结束跑步接口、轮询结果
  • PHP后台:接收接口请求、执行业务逻辑(校验/作弊检测/数据插入/同步)
  • 云存储:存储fit文件,提供文件访问接口

执行流程:

  1. 用户跑步完毕后,长按结束跑步:
    (1) 调用佳明SDK生成.fit文件(若生成失败,提示用户“运动数据生成失败,请重试”)
    (2) 调用【获取云存储TOKEN】接口(若TOKEN获取失败,返回异常)
    (3) 上传.fit文件到云存储(若上传失败,保留本地文件,允许用户再次上传;上传成功后,记录文件URL与batch_id关联)
  2. 将接口所需数据发送到后台【结束跑步】接口
  3. 后台接受到数据后,执行完赛队列:
    (1) 验证传参数据:必填字段是否存在且格式合法,不合法则返回错误信息(batch_id/fitUrl/distance/pace/calories/step/step_frequency/time/time_used)
    (2) 验证是否作弊,并增加标识(如配速异常)
    (3) 增加一条日常跑记录
    (4) 未作弊/非生产环境,查找未过期、正在比赛的报名记录
    (5) 根据报名规则,判断比赛状态:有效则生成比赛跑步记录,无效则跳过
    (6) 把日常跑 + 比赛跑步记录插入数据库
    (7) 未作弊,判断是否有APP跑量活动,如果报名了,将记录同步到跑量活动中
    (8) 未作弊,将记录同步到用户的跑团数据中
  4. APP轮询【跑步队列处理结果】接口,返回跑步结束需要的数据;

完赛逻辑:

- 打卡赛

  1. 已经完赛直接跳过;
  2. 若赛事设定省市区:
    • 无district_code或格式错误(非6位数字),跳过该比赛;
    • 有district_code则校验:省→市→区(规则见「区域验证说明」),不匹配则跳过;
  3. 比赛周期校验:
    • is_game_period=1(指定时间):跑步时间需在game_start~game_end之间;
    • is_game_period=2(报名后period_day天):period_day需≥1(否则视为无效规则),跑步时间需在报名时间~报名时间+period_day天内;
  4. 每日时间段校验:
    • 若设定time_start/time_end(如06:00~22:00):
      • 跑步必须在同一天(start_time和end_time日期一致),否则跳过;
      • 跑步时间需完全在time_start~time_end内(如start_time≥06:00且end_time≤22:00),否则跳过;
  5. 单次时长限制:
    • 若设定is_clock_require_hour(如1小时):单次跑步时间需≤该时长(否则视为无效打卡);
  6. 单次目标校验:
    • is_clock_require_select=1(里程):单次跑步距离≥设定值(如5km);
    • is_clock_require_select=2(步数):单次跑步步数≥设定值(如8000步);
  7. 打卡方式:
    • is_clock_way=1(每日):1天内仅1次有效打卡(按created_at日期去重);
    • is_clock_way=2(累积):1天内可多次打卡,次数累计;
  8. 连续打卡规则:
    • continuous_clock=1(开启):本次打卡日期与上次打卡日期需连续(差1天),否则累计次数清零;
    • continuous_clock=0(关闭):累计次数不重置;
  9. 完赛判定:
    • 有效打卡次数≥clock_num(目标次数),且剩余天数≥(clock_num-当前有效次数)→ 完赛;
    • 剩余天数计算:赛事结束日期 - 当前日期(包含当天);
    • 例:赛事8月25日结束,当前8月20日,剩余6天;当前有效次数3次,目标5次 → 6≥2 → 可完赛;若当前有效次数4次,目标5次 → 6≥1 → 可完赛;若当前有效次数1次,目标5次 → 6<4 → 未完赛;

- 目标累计赛/线上赛

  1. 已经完赛直接跳过;
  2. 若赛事设定省市区:
    • 无district_code或格式错误(非6位数字),跳过该比赛;
    • 有district_code则校验:省→市→区(规则见「区域验证说明」),不匹配则跳过;
  3. 比赛周期校验:
    • is_game_period=1(指定时间):跑步时间需在game_start~game_end之间;
    • is_game_period=2(报名后period_day天):period_day需≥1(否则视为无效规则),跑步时间需在报名时间~报名时间+period_day天内;
  4. 每日时间段校验:
    • 若设定time_start/time_end(如06:00~22:00):
      • 跑步必须在同一天(start_time和end_time日期一致),否则跳过;
      • 跑步时间需完全在time_start~time_end内(如start_time≥06:00且end_time≤22:00),否则跳过;
  5. 累计目标:
    • is_challenge_goal=1(里程):累计里程≥设定值(如100km);
    • is_challenge_goal=2(步数):累计步数≥设定值(如1000步);
  6. 次数限制规则:
    • limit_max_num=0(无限次):所有有效记录累加;
    • limit_max_num>0(有限次):
      • 线下赛读取fit文件,获取目标距离的成绩;
      • 线下活动取「有效记录中贡献值最大的N次」累加(贡献值=里程/步数,按降序排列取前N次);
        例:目标10km,limit_max_num=2;用户5次有效记录:5km、4km、5km、3km、6km → 取最大2次(6km+5km=11km≥10km → 完赛);
      • 边界:若有效记录数<limit_max_num → 取全部有效记录累加;

相关接口文档

获取云存储TOKEN
结束跑步
跑步队列处理结果

作者:jianghekun  创建时间:2025-11-20 15:31
最后编辑:jianghekun  更新时间:2025-11-28 15:28