文件
hl-api-changelog/changelogs-v2/2026-09/07_7196_团期流团改为申请与审批-修改接口-管理后台.md
T

20 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 7196 团期流团改为申请与审批 admin jw(GIT) 修改接口 deployed verified verified mmg 20905206 2026-09-08 流团由「点完就退款、不可撤销」改为「先申请、批准后才执行」。发起流团端点语义变更且理由改必填,新增审批中心列表/详情/同意/拒绝四端点+权限校验+出行后阶段限制。后端已部署 TEST 实测 R1-R10 全过。前端已识别为待接入项(团期运营域),按「先完成任务清单」排在 #7067 U2-U7 与上一批团期增量(#7188/7189/7190/7210 等)之后,本条保持 pending。 2026-09-07 dev-v3

团期流团:改为「申请 + 审批」,批准后才退定金

影响范围:管理后台「团期详情 → 发起流团」与「订单管理 → 审批中心」。 当前状态:后端已部署 TEST 并实测;前端待接入(发起流团端点语义已变更)。

⚠️ 关键变化

  1. 流团不再是点完就执行。原先点一下就把团期置为已取消、批量退各户定金、释放配车占用, 不可撤销;现在只提交一条待审批的申请,团期、子订单、名额、钱四项零变动, 批准后才真正执行。
  2. 发起流团端点语义变更:POST .../disband 由「立即流团」改为「提交流团申请」, 且流团理由由可空改为必填(原先允许不带请求体直接流团)。
  3. 新增四个端点:审批中心列表、申请详情、同意、拒绝(拒绝原因必填)。
  4. 新增权限校验:发起流团需要团期运营写权限(此前该接口无任何权限校验)。
  5. 新增阶段限制:出行后不可发起流团。

一、背景

流团意味着整期解散并退还各户定金,是不可逆的重动作,此前却没有任何审批与权限把关, 点一下就生效。原型明确要求走公司管理审批:团期管理员发起 → 抄送定制师知会 → 负责人确认,批准后才自动原路退定金。本次把这条链路补齐。

二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 发起流团申请 POST /v3/admin/order/group-batch/{groupBatchId}/disband 修改接口 由「立即流团」改为「提交申请」;理由改为必填;新增权限与阶段限制
2 审批中心列表 GET /v3/admin/order/group-batch/approvals/page 新增接口 流团与退单户两类共用,可按类型筛选
3 流团申请详情 GET /v3/admin/order/group-batch/disband/{approvalId} 新增接口 审批链、快照、批复信息
4 同意流团 POST /v3/admin/order/group-batch/disband/{approvalId}/approve 新增接口 批准后才真正执行流团
5 拒绝流团 POST /v3/admin/order/group-batch/disband/{approvalId}/reject 新增接口 只改申请单状态,团期继续正常招募

三、接口详情

1. 发起流团申请 POST /v3/admin/order/group-batch/{groupBatchId}/disband

VO: DisbandSubmitReqVO

使用场景

团期管理员在团期详情点「发起流团(走审批)」,填写流团理由后提交。 提交只建一条待审批的申请单,团期状态、子订单、名额、钱一律不动,等审批结果。

入参

字段 位置 类型 必填 约束 说明
groupBatchId path Long 是 正整数 团期 ID
reason body String 是 非空白,最长 512 字 流团理由。本次由可空改为必填

出参

字段 类型 说明
approvalId String 审批单 ID
approvalStatus String 固定 PENDING
affectedOrderCount Integer 影响子订单户数(提交时快照)
estimatedRefundAmount BigDecimal 退还定金合计(提交时快照,仅供展示)
applicantName String 发起人姓名
ccUserNames String[] 抄送定制师姓名列表(去重)

请求示例

{
  "reason": "临近出团仍未达最低成团数(6 户)"
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "approvalId": "2096779558547087362",
    "groupBatchId": "2096779382436651009",
    "batchNo": "GT-26-0004",
    "approvalStatus": "PENDING",
    "reason": "临近出团仍未达最低成团数(6 户)",
    "affectedOrderCount": 3,
    "estimatedRefundAmount": 32900.00,
    "applicantName": "卜丽颖",
    "ccUserNames": ["李雯", "王浩"]
  },
  "success": true
}

空数据 / 降级响应

本期尚无子订单时也可发起:影响户数为 0、退还定金为 0、抄送名单为空数组,属正常情况。

错误响应

{
  "code": 589543,
  "message": "该团期已有流团申请在审批中,请勿重复提交",
  "data": null,
  "success": false
}

业务边界

  • 提交零副作用:团期状态、子订单、名额、钱四项均不变动。
  • 同期至多一条在途申请,重复提交返回 589543。
  • 出行后不可发起,返回 589544;可发起的阶段为招募中、资源准备中、物料准备中、待出发。
  • 需要团期运营写权限,无权限返回 589507。
  • 五秒内重复点击会先被幂等窗口拦下,返回提交中提示,属预期。

2. 审批中心列表 GET /v3/admin/order/group-batch/approvals/page

VO: GroupBatchApprovalItemRespVO

使用场景

审批中心页面加载时调用,一次拿到流团与退单户两类申请,可按类型与状态筛选。

入参

字段 位置 类型 必填 约束 说明
bizType query String 否 DISBAND / WITHDRAW 业务类型;不传表示两类都要
approvalStatus query String 否 PENDING / APPROVED / REJECTED 审批状态;不传表示全部
groupBatchId query Long 否 正整数 按团期筛选
pageNum query Integer 否 从 1 开始 页码,默认 1
pageSize query Integer 否 1-100 每页条数,默认 20

出参

字段 类型 说明
bizType String DISBAND 流团 / WITHDRAW 退单户
bizTypeText String 类型中文名,服务端给出
approvalStatus String 审批状态
batchNo String 团期号
orderId String 被退子订单 ID;流团为 null
affectedOrderCount Integer 影响户数;退单户为 null
estimatedRefundAmount BigDecimal 预计退款额
applicantName String 发起人
approvedByName String 批复人;未批复为 null

请求示例

GET /v3/admin/order/group-batch/approvals/page?bizType=DISBAND&approvalStatus=PENDING&pageNum=1&pageSize=20
Authorization: Bearer <token>

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "list": [
      {
        "approvalId": "2096779558547087362",
        "bizType": "DISBAND",
        "bizTypeText": "流团",
        "batchNo": "GT-26-0004",
        "approvalStatus": "PENDING",
        "orderId": null,
        "affectedOrderCount": 3,
        "estimatedRefundAmount": 32900.00,
        "applicantName": "卜丽颖",
        "approvedByName": null
      }
    ],
    "total": 4,
    "page": 1,
    "pageSize": 20
  },
  "success": true
}

空数据 / 降级响应

无待办时返回空列表且 total 为 0,页面展示「暂无审批事项」。

错误响应

{
  "code": 589507,
  "message": "无操作权限",
  "data": null,
  "success": false
}

业务边界

  • 两类申请共用一套列表;差异只在 orderId(退单户有值)与 affectedOrderCount(流团有值)。
  • 按提交时间倒序;每页最多 100 条。

3. 流团申请详情 GET /v3/admin/order/group-batch/disband/{approvalId}

VO: DisbandApprovalRespVO

使用场景

审批人在审批中心点开一条流团申请,或团期详情的「流团审批中 / 已被驳回」横幅取详情。

入参

字段 位置 类型 必填 约束 说明
approvalId path Long 是 正整数 审批单 ID

出参

字段 类型 说明
approvalStatus String PENDING / APPROVED / REJECTED
reason String 流团理由
affectedOrderCount Integer 影响户数(提交时快照)
estimatedRefundAmount BigDecimal 退还定金合计(提交时快照)
actualRefundAmount BigDecimal 实际退款合计,批准执行后按真实取消结果回填
applicantName String 发起人
ccUserNames String[] 抄送定制师
approvedByName String 批复人
approveRemark String 批复备注 / 拒绝原因

请求示例

GET /v3/admin/order/group-batch/disband/2096779558547087362
Authorization: Bearer <token>

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "approvalId": "2096779558547087362",
    "approvalStatus": "APPROVED",
    "reason": "临近出团仍未达最低成团数(6 户)",
    "affectedOrderCount": 3,
    "estimatedRefundAmount": 32900.00,
    "actualRefundAmount": 32900.00,
    "applicantName": "卜丽颖",
    "ccUserNames": ["李雯", "王浩"],
    "approvedByName": "刘涛",
    "approveRemark": "确认无法成团,同意流团"
  },
  "success": true
}

空数据 / 降级响应

未批复时 approvedByName / approveRemark / actualRefundAmount 均为 null,前端按「审批中」渲染。

错误响应

{
  "code": 589545,
  "message": "流团申请不存在",
  "data": null,
  "success": false
}

业务边界

  • 只认流团类申请;拿退单户的单号来查会返回 589545,两类端点互不串用。

4. 同意流团 POST /v3/admin/order/group-batch/disband/{approvalId}/approve

VO: ApproveDisbandReqVO

使用场景

审批人在审批中心点「同意」。只有走到这一步,流团才真正执行: 团期置为已取消、按规则退各户定金、释放配车占用。

入参

字段 位置 类型 必填 约束 说明
approvalId path Long 是 正整数 审批单 ID
remark body String 否 最长 512 字 批复备注,可选

出参

字段 类型 说明
approvalStatus String 变为 APPROVED
actualRefundAmount BigDecimal 实际退款合计,按执行后的真实取消结果回填
approvedByName String 批复人姓名
approveRemark String 批复备注

请求示例

{
  "remark": "确认无法成团,同意流团"
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "approvalId": "2096779558547087362",
    "approvalStatus": "APPROVED",
    "actualRefundAmount": 32900.00,
    "approvedByName": "刘涛",
    "approveRemark": "确认无法成团,同意流团"
  },
  "success": true
}

空数据 / 降级响应

本期无有效子订单时实际退款合计为 0,流团照常完成。

错误响应

{
  "code": 589546,
  "message": "该流团申请已处理,不可重复操作",
  "data": null,
  "success": false
}

业务边界

  • 只有待审批的申请可被处理;已同意 / 已拒绝的再点返回 589546。
  • 并发下只有一人成功:两名审批人同时点,另一人拿 589546,且绝不会重复执行流团。
  • 需要管理员角色,否则返回 589547。
  • 实际退款合计按执行后的真实取消结果统计,不等于提交时的预计金额, 两者不一致的常见原因见「不影响范围」的说明。

5. 拒绝流团 POST /v3/admin/order/group-batch/disband/{approvalId}/reject

VO: RejectDisbandReqVO

使用场景

审批人认为该期还能继续招募,点「拒绝」并写明原因。

入参

字段 位置 类型 必填 约束 说明
approvalId path Long 是 正整数 审批单 ID
remark body String 是 非空白,最长 512 字 拒绝原因必填

出参

字段 类型 说明
approvalStatus String 变为 REJECTED
approvedByName String 批复人姓名
approveRemark String 拒绝原因

请求示例

{
  "remark": "已有两户确认报名,继续招募"
}

响应示例

{
  "code": 200,
  "message": "成功",
  "data": {
    "approvalId": "2096779558547087362",
    "approvalStatus": "REJECTED",
    "approvedByName": "刘涛",
    "approveRemark": "已有两户确认报名,继续招募"
  },
  "success": true
}

空数据 / 降级响应

拒绝不产生任何业务数据,响应中与执行相关的字段(实际退款合计)保持为空。

错误响应

{
  "code": 400,
  "message": "拒绝原因不能为空",
  "data": null,
  "success": false
}

业务边界

  • 拒绝只改申请单状态:团期、子订单、名额、钱四项一律不动,团期继续正常招募。
  • 拒绝后可以再次发起流团申请。
  • 拒绝原因会同时写进团期操作记录,在团期详情里可直接看到。

四、契约约束与正确调用方式

  • 发起流团必须带理由。原先允许不带请求体直接流团的调用方式已失效,会返回参数校验错误。
  • 提交 ≠ 已流团。提交后团期仍在原状态,前端应把按钮切成「流团审批中」并置灰, 同时展示「去审批中心」的入口;不要在提交成功后就把团期显示成已取消。
  • 同意与拒绝是两个端点:同意的备注可选,拒绝的原因必填,前端拒绝弹窗需做必填校验。
  • 审批中心一个列表拿两类,用 bizType 区分与筛选,不需要分别请求再合并。
  • 五秒幂等窗口:连点会先返回「提交中,请勿重复提交」,这不是业务错误,前端做防抖即可。
  • 展示金额时请区分两个字段:estimatedRefundAmount 是提交时的预计值(用于弹窗展示), actualRefundAmount 是批准执行后的实际结果(用于结果页与对账)。

五、数据库行为

  • 发起流团只新增一条待审批的申请单,记录理由、影响户数、退还定金合计、 发起人与抄送定制师名单;不改团期、不改子订单、不动名额与钱。
  • 同意时先把申请单落为已通过,再执行流团;若该单已被他人处理,则整笔拒绝且不执行流团。
  • 执行流团后回读实际取消结果再回填实际退款合计——不拿「预计金额」冒充实退。 若存在已付款但未被取消的户,服务端会打出告警日志,便于人工捞出处理。
  • 拒绝只改申请单状态与批复信息,另写一条团期操作记录(含拒绝原因)。
  • 发起、拒绝、以及流团执行本身各写一条团期操作记录,均可查到操作人与时间。
  • 被拒绝或被拒收的请求(重复提交、阶段不允许、已处理、无权限)一律零写入。

六、边界行为

  • 同期至多一条在途申请;驳回后可重新发起,判重只拦在审批中的那条。
  • 出行后不可发起流团;已流团的团期再次发起同样被拦。
  • 并发审批由串行锁与状态校验双重保证,同一条申请只会被处理一次,流团只会执行一次。
  • 本期无有效子订单时也可发起与批准,影响户数与金额均为 0。

六.6、修改前后对比

项 修改前 修改后
发起流团的效果 点完即执行:团期取消、批量退定金、释放配车,不可撤销 只建申请单,四项零变动,批准后才执行
流团理由 可空,甚至可以不带请求体 必填,为空拒绝
权限 无任何校验 需要团期运营写权限
阶段限制 只要不是已结算 / 已取消都能流 出行后不可发起
审批 无 同意 / 拒绝两个操作,拒绝原因必填
审批可见性 无 审批中心可见,流团与退单户两类共用列表
返回值 空 返回申请单快照(含影响户数、退还定金、抄送名单)

六.7、影响评估

  • 发起流团端点不兼容:语义由「立即执行」变为「提交申请」,且理由必填。 前端必须同步改造:提交后不能再当作已流团处理,需展示审批中状态; 看板上旧的「确认流团」二次确认入口(文案写「点完即退款、不可撤销」)应下线或改走同一条流, 否则与审批语义冲突。
  • 权限是行为变更:此前任何登录管理员都能流团,现在需要团期运营写权限; 该权限已在既有工单中建立并授予管理员与超级管理员,无需额外配置。
  • 阶段限制是行为收紧:出行后不再允许流团。
  • 新增四个端点均为增量,不影响任何既有接口。
  • 审批人范围:本期由管理员审批。原型里写的「部门负责人」角色目前系统中不存在, 待该角色落地后可再收窄。

七、不影响范围

  • 退单户(单户退团)的申请与审批流程完全不变,仅新增了一个可同时查看两类的列表。
  • 团期成团、调整满团名额、需求审核等其他动作不受影响。
  • 小程序端不受影响,改动全部在管理后台侧。
  • 本次不改动退款的执行口径。需要特别说明一个既有限制: 流团执行时,只有尚未付款的户会被取消,已付定金的户会被跳过、既不取消也不退款, 与「自动原路退定金」的承诺不符。这是本次改造之前就存在的问题,本单未修, 但已让实际退款合计如实反映真实结果、并对被跳过的已付款户打出告警,便于人工兜底。 该问题建议单独排期修复。
  • 批准后的客户通知(公众号 / 短信)本期不做,仍需人工通知客户;抄送定制师目前只记录名单、不推送消息。

八、测试环境已验证

TEST 环境已部署订单服务并实测通过:

  • 发起流团申请成功,返回影响户数与退还定金快照,团期状态保持不变。
  • 流团理由为空被拒绝。
  • 重复发起被拒绝(同期至多一条在途)。
  • 拒绝时原因为空被拒绝;正常拒绝后团期状态不变,可再次发起。
  • 已处理的申请再次同意或拒绝均被拒绝。
  • 同意后团期才变为已取消,未付款子订单同步取消,实际退款合计按真实结果回填。
  • 已流团的团期再次发起被阶段限制拦下。
  • 审批中心列表返回两类共 7 条,按类型筛选分别为流团 4 条、退单户 3 条,类型中文名正确。
  • 申请详情回读齐全:快照、抄送名单、批复人与批复备注。

十、相关文档

  • 工单:HL#7196
  • 合并:HL PR#7201(已合入 dev-v3)
  • 关联:HL#7100(团期退单户审批)——本单复用其审批单模型与审批范式; HL#7158 / HL#7178——复用其建立的团期运营写权限与阶段限制写法

关联 / 联系人

  • 后端:jw
  • 前端待接:发起流团弹窗(必填理由、审批链展示、提交后切「审批中」)、 团期详情的审批中与已驳回两条横幅、审批中心列表与同意/拒绝操作(拒绝原因必填)、 看板旧「确认流团」入口下线或改走审批流