From 4353b0f053733452f8bdbe001d26aeaa72ec9af3 Mon Sep 17 00:00:00 2001 From: Zuncle <34310384@qq.com> Date: Tue, 31 Mar 2026 21:04:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(shipping):=20=E5=8F=8D=E8=BD=AC=E8=BF=90?= =?UTF-8?q?=E8=B4=B9=E8=A7=84=E5=88=99=E4=B8=BA=E4=B8=8D=E6=BB=A15?= =?UTF-8?q?=E4=BB=B6=E6=94=B6=E8=BF=90=E8=B4=B9=EF=BC=8C=E6=BB=A15?= =?UTF-8?q?=E4=BB=B6=E5=8C=85=E9=82=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 运费预下单接口:< 5 件允许创建运费订单,>= 5 件拒绝 - 批量发货接口:< 5 件时强制校验已支付运费订单 - 单件发货接口:同样强制校验已支付运费订单 - 运费订单 remark 存入 inventory_ids JSON 用于关联 --- internal/api/user/request_shipping_app.go | 15 ++++++++++++++- internal/api/user/request_shipping_batch_app.go | 17 ++++++++++++++++- internal/api/user/shipping_fee_preorder_app.go | 12 ++++++++---- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/internal/api/user/request_shipping_app.go b/internal/api/user/request_shipping_app.go index 0706077..e4f02fa 100755 --- a/internal/api/user/request_shipping_app.go +++ b/internal/api/user/request_shipping_app.go @@ -17,7 +17,7 @@ type requestShippingResponse struct { // RequestShipping 申请发货(使用默认地址) // @Summary 申请发货 -// @Description 用户已有默认地址时,申请对指定资产发货;幂等校验已存在发货记录时返回已处理 +// @Description 用户已有默认地址时,申请对指定资产发货;单件发货需先支付运费;幂等校验已存在发货记录时返回已处理 // @Tags APP端.用户 // @Accept json // @Produce json @@ -36,6 +36,19 @@ func (h *handler) RequestShipping() core.HandlerFunc { return } userID := int64(ctx.SessionUserInfo().Id) + + // 运费校验:单件发货一定 < 5 件,须已支付运费订单 + paid, _ := h.readDB.Orders.WithContext(ctx.RequestContext()). + Where( + h.readDB.Orders.UserID.Eq(userID), + h.readDB.Orders.SourceType.Eq(shippingFeeSourceType), + h.readDB.Orders.Status.Eq(2), + ).Count() + if paid == 0 { + ctx.AbortWithError(core.Error(http.StatusBadRequest, 150003, "不满5件需先支付运费")) + return + } + addrID, err := h.user.RequestShipping(ctx.RequestContext(), userID, req.InventoryID) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10022, err.Error())) diff --git a/internal/api/user/request_shipping_batch_app.go b/internal/api/user/request_shipping_batch_app.go index 9267d12..db625e7 100755 --- a/internal/api/user/request_shipping_batch_app.go +++ b/internal/api/user/request_shipping_batch_app.go @@ -22,7 +22,7 @@ type requestShippingBatchResponse struct { // RequestShippingBatch 批量申请发货(使用默认地址或指定地址) // @Summary 批量申请发货 -// @Description 为多个资产申请发货,校验所有权与状态;幂等:已申请的资产跳过 +// @Description 为多个资产申请发货,校验所有权与状态;不满 5 件需先支付运费;幂等:已申请的资产跳过 // @Tags APP端.用户 // @Accept json // @Produce json @@ -45,6 +45,21 @@ func (h *handler) RequestShippingBatch() core.HandlerFunc { return } userID := int64(ctx.SessionUserInfo().Id) + + // 运费校验:不满 5 件须已支付运费订单 + if len(req.InventoryIDs) < shippingFeeThreshold { + paid, _ := h.readDB.Orders.WithContext(ctx.RequestContext()). + Where( + h.readDB.Orders.UserID.Eq(userID), + h.readDB.Orders.SourceType.Eq(shippingFeeSourceType), + h.readDB.Orders.Status.Eq(2), + ).Count() + if paid == 0 { + ctx.AbortWithError(core.Error(http.StatusBadRequest, 150003, "不满5件需先支付运费")) + return + } + } + addrID, batchNo, success, skipped, failed, err := h.user.RequestShippings(ctx.RequestContext(), userID, req.InventoryIDs, req.AddressID) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10023, err.Error())) diff --git a/internal/api/user/shipping_fee_preorder_app.go b/internal/api/user/shipping_fee_preorder_app.go index 9a11f9c..0efda10 100644 --- a/internal/api/user/shipping_fee_preorder_app.go +++ b/internal/api/user/shipping_fee_preorder_app.go @@ -1,6 +1,7 @@ package app import ( + "encoding/json" "fmt" "net/http" "time" @@ -12,7 +13,7 @@ import ( ) const ( - shippingFeeThreshold = 5 // 超过此件数收运费 + shippingFeeThreshold = 5 // 低于此件数收运费 shippingFeeCents = 1000 // 运费金额(分),10 元 shippingFeeSourceType = int32(5) // orders.source_type: 5 = 运费订单 ) @@ -27,7 +28,7 @@ type shippingFeePreorderResponse struct { // ShippingFeePreorder 创建运费订单 // @Summary 创建运费订单 -// @Description 选中件数超过 5 件时,创建 10 元运费订单并返回 order_no;前端再调用 /pay/wechat/jsapi/preorder 发起支付 +// @Description 选中件数不满 5 件时,创建 10 元运费订单并返回 order_no;前端再调用 /pay/wechat/jsapi/preorder 发起支付;满 5 件包邮无需调用 // @Tags APP端.用户 // @Accept json // @Produce json @@ -49,13 +50,15 @@ func (h *handler) ShippingFeePreorder() core.HandlerFunc { ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "inventory_ids 不能为空")) return } - if len(req.InventoryIDs) <= shippingFeeThreshold { - ctx.AbortWithError(core.Error(http.StatusBadRequest, 150001, fmt.Sprintf("件数不超过 %d 件,无需支付运费", shippingFeeThreshold))) + if len(req.InventoryIDs) >= shippingFeeThreshold { + ctx.AbortWithError(core.Error(http.StatusBadRequest, 150001, fmt.Sprintf("件数满 %d 件,无需支付运费", shippingFeeThreshold))) return } userID := int64(ctx.SessionUserInfo().Id) + remarkBytes, _ := json.Marshal(req.InventoryIDs) + // 生成运费订单号(SF + 时间戳 + 用户ID后6位,保证唯一) now := time.Now() orderNo := fmt.Sprintf("SF%s%06d", now.Format("20060102150405"), userID%1000000) @@ -71,6 +74,7 @@ func (h *handler) ShippingFeePreorder() core.HandlerFunc { ActualAmount: shippingFeeCents, Status: 1, IsConsumed: 0, + Remark: string(remarkBytes), } if err := h.writeDB.Orders.WithContext(ctx.RequestContext()). Omit(h.writeDB.Orders.PaidAt, h.writeDB.Orders.CancelledAt).