拆分 service 与前端大文件,修复 CORS 配置与格式问题
- 后端 internal/service 按职责拆分: fulfillment.go(1397→527)拆出 wallet/timeout/data/order/query/dashboard/shipnotify delivery.go(1124→801)拆出 upstream/link/state/helpers merchant.go(855→251)拆出 member/product/api_client/catalog/helpers - 前端 MerchantCenter.tsx(1327→606)拆出 merchantCenterTabs/merchantCenterUtils - docker-compose backend 透传 CORS_ALLOWED_ORIGINS - CORS 白名单实现(config/router/README/.env.example 配套) - 修复 gofmt 与文件尾部多余空行
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"affiliate_dash/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (s *FulfillmentService) GetOrder(merchantID uint, orderNo string) (*model.FulfillmentOrder, error) {
|
||||
var order model.FulfillmentOrder
|
||||
err := s.db.Preload("MerchantProduct.Product").
|
||||
Where("merchant_id = ? AND order_no = ?", merchantID, orderNo).
|
||||
First(&order).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("订单不存在")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &order, nil
|
||||
}
|
||||
|
||||
func (s *FulfillmentService) ListOrders(merchantID uint, page, size int, orderStatus string) ([]model.FulfillmentOrder, int64, error) {
|
||||
page, size = normalizePage(page, size)
|
||||
tx := s.db.Model(&model.FulfillmentOrder{}).Where("merchant_id = ?", merchantID)
|
||||
if orderStatus != "" {
|
||||
tx = tx.Where("order_status = ?", orderStatus)
|
||||
}
|
||||
var total int64
|
||||
if err := tx.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var orders []model.FulfillmentOrder
|
||||
err := tx.Preload("MerchantProduct.Product").Order("id DESC").Offset((page - 1) * size).Limit(size).Find(&orders).Error
|
||||
return orders, total, err
|
||||
}
|
||||
|
||||
type OpenOrderQuery struct {
|
||||
OrderNo string `json:"order_no"`
|
||||
Status string `json:"status"`
|
||||
CanShip bool `json:"can_ship"`
|
||||
CannotShipReason string `json:"cannot_ship_reason,omitempty"`
|
||||
Product *OpenOrderProduct `json:"product,omitempty"`
|
||||
BuyerName string `json:"buyer_name"`
|
||||
Amount int64 `json:"amount"`
|
||||
ProviderOrderNo string `json:"provider_order_no,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ShippedAt *time.Time `json:"shipped_at"`
|
||||
ShipFailReason string `json:"ship_fail_reason,omitempty"`
|
||||
GameChannel string `json:"game_channel,omitempty"`
|
||||
GameUID string `json:"game_uid,omitempty"`
|
||||
RoleName string `json:"role_name,omitempty"`
|
||||
PayScore int `json:"pay_score,omitempty"`
|
||||
}
|
||||
|
||||
// OpenOrderProduct 开放接口返回的商品快照。
|
||||
type OpenOrderProduct struct {
|
||||
Name string `json:"name"`
|
||||
SKU string `json:"sku"`
|
||||
Game string `json:"game"`
|
||||
}
|
||||
|
||||
// GetByOrderNo 按订单号查询(不限定商户,供上游 SourceOpen 使用)。
|
||||
func (s *FulfillmentService) GetByOrderNo(orderNo string) (*model.FulfillmentOrder, error) {
|
||||
var order model.FulfillmentOrder
|
||||
err := s.db.Preload("MerchantProduct.Product").Where("order_no = ?", orderNo).First(&order).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("订单不存在")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &order, nil
|
||||
}
|
||||
|
||||
// QueryOpenOrder 供上游查询:商品信息 + 是否可发货。
|
||||
func (s *FulfillmentService) QueryOpenOrder(orderNo string) (*OpenOrderQuery, error) {
|
||||
if orderNo == "" {
|
||||
return nil, errors.New("订单号不能为空")
|
||||
}
|
||||
order, err := s.GetByOrderNo(orderNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
canShip, reason := CanFulfill(order)
|
||||
out := &OpenOrderQuery{
|
||||
OrderNo: order.OrderNo,
|
||||
Status: normalizeOrderStatus(order),
|
||||
CanShip: canShip,
|
||||
CannotShipReason: reason,
|
||||
BuyerName: order.BuyerReference,
|
||||
Amount: order.Amount,
|
||||
ProviderOrderNo: order.ProviderOrderNo,
|
||||
CreatedAt: order.CreatedAt,
|
||||
ShippedAt: order.DeliveredAt,
|
||||
ShipFailReason: order.FailureReason,
|
||||
}
|
||||
if order.MerchantProduct != nil {
|
||||
game := ""
|
||||
if order.MerchantProduct.Product != nil {
|
||||
game = order.MerchantProduct.Product.Category
|
||||
}
|
||||
out.Product = &OpenOrderProduct{
|
||||
Name: order.ProductName,
|
||||
SKU: order.ProductSKU,
|
||||
Game: game,
|
||||
}
|
||||
}
|
||||
// 新模型无独立的游戏字段列,从 RequestData / ResultData JSON 中还原。
|
||||
extractGameFields(order.RequestData, out)
|
||||
extractGameFields(order.ResultData, out)
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user