refactor(utils): 修复密码哈希比较逻辑错误 feat(user): 新增按状态筛选优惠券接口 docs: 添加虚拟发货与任务中心相关文档 fix(wechat): 修正Code2Session上下文传递问题 test: 补充订单折扣与积分转换测试用例 build: 更新配置文件与构建脚本 style: 清理多余的空行与注释
4.0 KiB
4.0 KiB
目标
- 将现有单件发货接口扩展为批量接口,支持一次提交多个资产 ID(如:{"inventory_ids":[52,53,...]})。
- 复用现有发货能力(默认地址、资产状态迁移、备注标记),保证幂等与错误可追踪。
现状
- 单件接口:
POST /api/app/users/{user_id}/inventory/request-shipping,请求体{ inventory_id } - 处理器位置:internal/api/user/request_shipping_app.go:30-47
- 服务层:
RequestShipping(ctx, userID, inventoryID)设置资产状态为已申请发货并记录备注- 代码位置:internal/service/user/address_share.go:120-126(
UPDATE user_inventory SET status=3, ... remark+='|shipping_requested' WHERE status=1)
- 代码位置:internal/service/user/address_share.go:120-126(
接口设计
- 新增:
POST /api/app/users/{user_id}/inventory/request-shipping-batch - 请求体:
inventory_ids数组,必填,长度 1–100,去重后处理address_id可选;若不提供则使用用户默认地址
- 返回体:
address_id实际使用的地址 IDsuccess_ids已成功提交的资产 ID 列表skipped数组:[{ id, reason }](如 not_found、not_owned、invalid_status、already_requested)failed数组:[{ id, reason }](如 DB 错误等)
行为与规则
- 地址选择
- 若提供
address_id:校验属于该用户且有效;否则返回 400 - 若未提供:读取默认地址;不存在则返回 400(沿用现有单件逻辑)
- 若提供
- 资产校验(逐个)
- 必须属于该用户
status=1(可发货)才处理;status=3(已申请)则标记为already_requested并 skip(幂等)- 不存在或不属于该用户 →
skipped.not_owned/not_found
- 幂等性
- 若 remark 已包含
shipping_requested或状态为 3,则视为已处理;加入skipped并不报错
- 若 remark 已包含
- 原子性
- 批量以“逐条子事务”处理(每条调用服务层更新),确保单条失败不影响其他条目;最终返回成功/跳过/失败三类列表
- 审计
- 在
user_points_ledger无需记录(该流程与积分无关);如需审计可在后续增加user_operations表留痕
- 在
服务层扩展
- 新增:
RequestShippings(ctx, userID int64, inventoryIDs []int64, addressID *int64) (addrID int64, success []int64, skipped []struct{id int64; reason string}, failed []struct{id int64; reason string}, err error)- 内部:
- 若
addressID==nil,读取默认地址(沿用单件方法) - 循环:校验→调用现有
RequestShipping(ctx, userID, inventoryID);捕获错误进行分流
- 若
- 可选优化:对同一用户的多件,合并一次地址校验;对 DB 更新使用独立事务(已在现有方法内处理)
- 内部:
处理器实现
- 新增处理器:
RequestShippingBatch():- 位置:internal/api/user/request_shipping_app.go(或新文件
request_shipping_batch_app.go) - 解析
inventory_ids(去重、长度限制);解析可选address_id - 调用服务层批量方法,组装响应
- 统一错误码:参数错误
code.ParamBindError,无地址10021(沿用或新增),其他子项错误填入failed字段
- 位置:internal/api/user/request_shipping_app.go(或新文件
错误码与返回示例
- 400 参数错误:
{"code":10023,"message":"invalid inventory_ids"} - 200 成功+部分跳过:
{
"address_id": 888,
"success_ids": [52, 53],
"skipped": [{"id": 54, "reason": "already_requested"}],
"failed": []
}
测试用例
- 有默认地址,提交 1、N 个有效资产 → 全成功
- 混合:包含非本用户、已申请、不存在 → 分别进
skipped - 指定 address_id 非本用户 → 400
- 无默认地址且未指定 address → 400
- 幂等:重复提交相同资产 → 均进入
already_requested
兼容性
- 不改动现有单件接口;前端可增设批量勾选后调用新接口
- DB 无结构变化;仍依赖
user_inventory.status与remark标记
交付内容
- 新增批量处理器与服务方法
- Swagger 注释与接口文档
- 单元测试:服务层批量逻辑、处理器参数校验
请确认按此方案实施,我将立即落地代码、接口与测试。