恢复测试订单创建
This commit is contained in:
@@ -39,6 +39,15 @@ type CreateFulfillmentOrderResult struct {
|
||||
Idempotent bool `json:"idempotent"`
|
||||
}
|
||||
|
||||
type CreateTestOrderInput struct {
|
||||
MerchantID uint
|
||||
ActorUserID uint
|
||||
SKU string
|
||||
BuyerReference string
|
||||
Note string
|
||||
FulfillmentStatus string
|
||||
}
|
||||
|
||||
func (s *FulfillmentService) CreateOrder(in CreateFulfillmentOrderInput) (*CreateFulfillmentOrderResult, error) {
|
||||
in.ClientOrderNo = strings.TrimSpace(in.ClientOrderNo)
|
||||
in.SKU = strings.TrimSpace(in.SKU)
|
||||
@@ -203,6 +212,113 @@ func (s *FulfillmentService) CreateOrder(in CreateFulfillmentOrderInput) (*Creat
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateTestOrder 创建后台联调订单:不扣钱包、不占库存,只用于上游按订单号查询与发货回传。
|
||||
func (s *FulfillmentService) CreateTestOrder(in CreateTestOrderInput) (*model.FulfillmentOrder, error) {
|
||||
in.SKU = strings.TrimSpace(in.SKU)
|
||||
in.BuyerReference = strings.TrimSpace(in.BuyerReference)
|
||||
in.Note = strings.TrimSpace(in.Note)
|
||||
if in.MerchantID == 0 {
|
||||
return nil, errors.New("无效的商户")
|
||||
}
|
||||
if in.SKU == "" {
|
||||
return nil, errors.New("sku 不能为空")
|
||||
}
|
||||
if in.BuyerReference == "" {
|
||||
in.BuyerReference = "测试买家"
|
||||
}
|
||||
if len(in.BuyerReference) > 128 {
|
||||
return nil, errors.New("买家标识最长 128 位")
|
||||
}
|
||||
if len(in.Note) > 512 {
|
||||
return nil, errors.New("备注最长 512 位")
|
||||
}
|
||||
if in.FulfillmentStatus == "" {
|
||||
in.FulfillmentStatus = model.FulfillmentStatusPending
|
||||
}
|
||||
switch in.FulfillmentStatus {
|
||||
case model.FulfillmentStatusPending, model.FulfillmentStatusFailed:
|
||||
default:
|
||||
return nil, errors.New("测试订单仅支持待履约或发货失败状态")
|
||||
}
|
||||
|
||||
requestData := map[string]interface{}{
|
||||
"source": "merchant_test_order",
|
||||
}
|
||||
if in.Note != "" {
|
||||
requestData["note"] = in.Note
|
||||
}
|
||||
rawRequestData, err := json.Marshal(requestData)
|
||||
if err != nil {
|
||||
return nil, errors.New("订单请求数据无法序列化")
|
||||
}
|
||||
|
||||
var out model.FulfillmentOrder
|
||||
err = s.db.Transaction(func(tx *gorm.DB) error {
|
||||
var merchant model.Merchant
|
||||
if err := tx.Where("id = ? AND status = ?", in.MerchantID, model.MerchantStatusActive).First(&merchant).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("商户不存在或已禁用")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var product model.MerchantProduct
|
||||
if err := tx.Preload("Product").
|
||||
Where("merchant_id = ? AND sku = ? AND status = ?", in.MerchantID, in.SKU, model.ProductStatusActive).
|
||||
First(&product).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("商品不存在或已下架")
|
||||
}
|
||||
return err
|
||||
}
|
||||
if product.Product == nil || product.Product.Status != model.ProductStatusActive {
|
||||
return errors.New("商品目录已下架")
|
||||
}
|
||||
|
||||
orderNo := newTestFulfillmentOrderNo()
|
||||
order := &model.FulfillmentOrder{
|
||||
MerchantID: in.MerchantID,
|
||||
OrderNo: orderNo,
|
||||
ClientOrderNo: "TEST-" + orderNo,
|
||||
MerchantProductID: product.ID,
|
||||
ProductSKU: product.SKU,
|
||||
ProductName: fallbackName(product.DisplayName, product.Product.Name),
|
||||
Quantity: 1,
|
||||
BaseAmount: 0,
|
||||
FeeType: merchant.FeeType,
|
||||
FeeRateBP: merchant.FeeRateBP,
|
||||
FeeFixedAmount: merchant.FeeFixedAmount,
|
||||
ServiceFeeAmount: 0,
|
||||
Amount: 0,
|
||||
Currency: product.Currency,
|
||||
PaymentStatus: model.PaymentStatusPaid,
|
||||
FulfillmentStatus: in.FulfillmentStatus,
|
||||
BuyerReference: in.BuyerReference,
|
||||
RequestData: string(rawRequestData),
|
||||
}
|
||||
if in.FulfillmentStatus == model.FulfillmentStatusFailed {
|
||||
order.FailureReason = fallbackName(in.Note, "联调测试订单初始化为发货失败,可重新发货")
|
||||
}
|
||||
if err := tx.Create(order).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeAudit(tx, &in.MerchantID, &in.ActorUserID, nil, "merchant_test_order.create", "fulfillment_order", order.OrderNo, map[string]interface{}{
|
||||
"sku": in.SKU,
|
||||
"fulfillment_status": in.FulfillmentStatus,
|
||||
"can_ship": true,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
out = *order
|
||||
out.MerchantProduct = &product
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (s *FulfillmentService) GetOrder(merchantID uint, orderNo string) (*model.FulfillmentOrder, error) {
|
||||
var order model.FulfillmentOrder
|
||||
err := s.db.Preload("MerchantProduct.Product").
|
||||
@@ -513,6 +629,10 @@ func newFulfillmentOrderNo() string {
|
||||
return "FO" + time.Now().UTC().Format("20060102150405") + strings.ReplaceAll(uuid.NewString()[:12], "-", "")
|
||||
}
|
||||
|
||||
func newTestFulfillmentOrderNo() string {
|
||||
return "O" + time.Now().UTC().Format("20060102150405") + strings.ReplaceAll(uuid.NewString()[:12], "-", "")
|
||||
}
|
||||
|
||||
// calculateServiceFee 按"百分比或固定"二选一计算手续费:
|
||||
// - feeType=rate:按 baseAmount * feeRateBP / 10000 计算
|
||||
// - feeType=fixed:直接取 feeFixedAmount
|
||||
@@ -567,7 +687,7 @@ func orderCallbackData(order *model.FulfillmentOrder) map[string]interface{} {
|
||||
"fee_type": order.FeeType,
|
||||
"service_fee_amount": order.ServiceFeeAmount,
|
||||
"amount": order.Amount,
|
||||
"currency": order.Currency,
|
||||
"currency": order.Currency,
|
||||
"payment_status": order.PaymentStatus,
|
||||
"fulfillment_status": order.FulfillmentStatus,
|
||||
"can_fulfill": canFulfill,
|
||||
|
||||
Reference in New Issue
Block a user