Skip to content

支持买家取消未接单的跑腿需求订单 #59

Description

@Serein207

Feature Description

ErrandDemandService 增加买家取消未接单跑腿需求的能力。

买家只能取消状态为 ERRAND_DEMAND_STATUS_OPEN 的需求订单;需求被团长全部或部分接单后,已经拆分并进入采购流程的 demand 不允许由买家取消。部分接单场景下,买家只能取消原 demand 中仍未接单的剩余商品行。

PRD:https://njupt-sast.feishu.cn/wiki/TQAcwn0yTixmEBkhGhPcHyT3n3c

Background

当前 Proto 中 ErrandDemandService 只有:

  • CreateErrandDemand
  • GetDemandList
  • GetDemandDetail

前端可以展示未接单订单,但缺少取消 RPC,因此无法安全实现取消入口。前端不能仅在本地修改状态,否则跑腿大厅仍会展示该需求,也无法处理所有权校验和并发接单冲突。

部分接单后,已接单商品行会拆分到新的采购中 demand;原 demand 仅保留未接单商品行并保持 OPEN。取消操作应只作用于这个仍为 OPEN 的原 demand,不影响任何已经关联 task 的 demand。

Proposed Solution

建议在 errand_demand_service.proto 增加:

message CancelErrandDemandRequest {
  // 待取消的买家视角跑腿需求订单 ID
  int64 errand_demand_id = 1;
  // 乐观锁版本,必须与服务端当前 updated_at 一致
  google.protobuf.Timestamp updated_at = 2;
}

message CancelErrandDemandResponse {}

service ErrandDemandService {
  // ...existing RPCs
  rpc CancelErrandDemand(CancelErrandDemandRequest) returns (CancelErrandDemandResponse);
}

实现要求:

  1. RPC 必须走登录鉴权,并校验 demand 属于当前买家。
  2. 仅允许 OPEN -> CANCELLEDSHOPPING 及后续状态拒绝取消。
  3. 使用 updated_at 做乐观并发控制。若取消与团长接单并发发生,只允许其中一个事务成功,不能出现已接单商品同时被取消。
  4. 取消应在单个数据库事务中更新 demand;其剩余 demand_item 不再出现在跑腿大厅的列表或详情中。
  5. 部分接单后的取消只影响原 demand 中仍未接单的剩余商品行,不得修改已经拆分并关联 task 的 demand/task。
  6. 对不存在、非本人、状态不允许、版本冲突等情况返回明确且可区分的业务错误。
  7. 为 Proto 字段补充 Protovalidate 约束,并补齐 handler/service/repository 测试。

前端接入条件:Proto 发布后,前端在买家跑腿订单状态为 OPEN 时展示二次确认的“取消需求”入口;成功后刷新订单列表与详情,其他状态不展示该入口。

Acceptance Criteria

  • 当前买家可以取消本人状态为 OPEN 的 demand,状态变为 CANCELLED
  • 非本人无法取消
  • 已接单或后续状态无法由买家取消
  • 部分接单后,只取消仍未接单的原 demand,不影响已拆分订单和 task
  • 取消与接单并发时不会同时成功
  • 取消后需求立即从团长跑腿大厅消失
  • BuyerErrandOrder 列表/详情能返回取消后的状态和更新时间
  • Proto、业务逻辑和并发场景测试通过
  • make proto-format && make proto-lint && make proto && make build && make lint 通过

Scope

  • Requires proto changes (API change)
  • Requires new migration (database change)
  • Affects multiple services

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions