TICKET_DURATION_REPAIR_API.md 4.4 KB

半年付车票时长修复 API

固定处理规格 772、774。沿用后台登录凭证,要求 validAccount:addTime 权限。 修改已开通车票的到期时间,不修改规格默认月份、开始时间或订单金额。

1. 预览

GET /manage/group/relation/duration-repair/preview?afterId=0&limit=100

可以传可选参数 userId,先只查看一个用户的车票,例如:

GET /manage/group/relation/duration-repair/preview?userId=12345&afterId=0&limit=100

将 12345 替换为要核对的用户 ID。传入后只查询 groups_relation.user_id 为该用户、 当前规格为 772/774 的车票;不会扩展到关联账号。不传则保留按这两个规格预览所有用户的行为。 userId 必须大于 0。预览仅查询,不执行扣减。

沿用项目 Result 响应包装,业务数据含 userId、items、hasMore、nextAfterId。 hasMore=true 时,将 nextAfterId 作为下次 afterId,同时保留相同的 userId;每页最多 200 张。

每条记录包括:

字段 含义
relationId / groupsId / skuId / userId 车票、车队、规格、当前用户
startTime / expiryTime / updateTime 当前开始、到期、更新时间,均为毫秒时间戳
newExpiryTime 候选车票预计的新到期时间,原到期减 6 个自然月
yearDifferenceMillis 原到期与开始加 12 个月的毫秒差
orderCount 当前车票用户关联的有效订单数,已按订单去重
decision / reason 筛选结果与原因
expiredAfterRepair 候选车票扣减后是否已到期

decision:

  • candidate:起止完整、精确 12 个自然月,当前有用户且为有效/额外车位;普通购买、非 VIP、 无冻结、恢复、保留天数或补时,且只关联一笔同规格普通订单。可提交执行。
  • review:有秒差、续费、多订单、补时、冻结等情况;不自动扣减。
  • skipped:未设置时间、已经半年或其他不符合条件的时长。

月份运算使用项目原有 DateUtil.offsetMonth;不按 180 天、不用完整月份数取整判断。 例如开始为 2024-02-29、原到期 2025-02-28,扣减后为 2024-08-28。 候选筛查无法证明所有历史修改原因,提交前仍需核对预览是否属于本次误设范围。

2. 执行

POST /manage/group/relation/duration-repair/execute
Content-Type: application/json

将预览中需要处理的 candidate 行的以下快照字段原样回传,时间必须用预览返回值:

{
  "remark": "半年付套餐误设一年,扣回多发的半年时长",
  "items": [
    {
      "relationId": 123,
      "groupsId": 456,
      "skuId": 772,
      "userId": 789,
      "startTime": 1767225600000,
      "expiryTime": 1798761600000,
      "updateTime": 1767225600000
    }
  ]
}

上面的 ID 和时间只是请求格式示例。updateTime 若在预览中为 null,也传 null。 remark 是可选的自定义备注,有内容时原样写入本批每张车票的 incr_expiry_time_record.remark, 不会追加默认说明;不传、空字符串或纯空白时,使用默认修复说明(包含新旧到期时间)。 每批 1 至 200 张,不能包含重复车票;不接受任意规格、任意扣减月份或强制跳过校验。

执行时锁定车票、再次查询订单和补时历史,对比身份及起止/更新时间,整批验证后扣减。 任一车票已经变化、不满足条件、更新失败或审计记录保存失败,整批事务回滚。 成功返回每张车票的修改前后时间,decision=updated。 再次提交同一快照会因旧到期时间不一致被拒绝,避免重复扣减。

每张修复车票写入现有 incr_expiry_time_record:旧到期时间、实际扣减天数(负数)、 操作人及备注;未提供自定义备注时,备注记录扣减 6 个自然月的说明及新旧到期时间。 后台同时记录 API 操作日志。 如果扣减后已经到期,接口仍保存该到期时间,不在本次事务内清票或调用外部服务, 预览和执行响应中的 expiredAfterRepair 会标明这种情况。

验证

mvn -pl netflix-service -am '-Dtest=TicketDurationRepairServiceImplTest' '-Dsurefire.failIfNoSpecifiedTests=false' test
mvn -pl netflix-web -am '-DskipTests' compile

测试使用 Mockito,不连接业务数据库。部署后使用现有后台会话调用以上接口。