This commit is contained in:
@@ -24,12 +24,13 @@ type OrderListRequest struct {
|
||||
PaymentStatus *int `json:"payment_status" query:"payment_status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"支付状态 (1:待支付, 2:已支付, 3:已取消, 4:已退款)"`
|
||||
PaymentMethod string `json:"payment_method" query:"payment_method" validate:"omitempty,oneof=wallet wechat alipay offline" description:"支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付, offline:线下支付)"`
|
||||
OrderType string `json:"order_type" query:"order_type" validate:"omitempty,oneof=single_card device" description:"订单类型 (single_card:单卡购买, device:设备购买)"`
|
||||
SellerShopID *uint `json:"seller_shop_id" query:"seller_shop_id" validate:"omitempty,min=1" minimum:"1" description:"所属代理商ID(销售来源店铺ID)"`
|
||||
OrderNo string `json:"order_no" query:"order_no" validate:"omitempty,max=30" maxLength:"30" description:"订单号(精确查询)"`
|
||||
PurchaseRole string `json:"purchase_role" query:"purchase_role" validate:"omitempty,oneof=self_purchase purchased_by_parent purchased_by_platform purchase_for_subordinate" description:"订单角色 (self_purchase:自己购买, purchased_by_parent:上级代理购买, purchased_by_platform:平台代购, purchase_for_subordinate:给下级购买)"`
|
||||
StartTime *time.Time `json:"start_time" query:"start_time" description:"创建时间起始"`
|
||||
EndTime *time.Time `json:"end_time" query:"end_time" description:"创建时间结束"`
|
||||
IsExpired *bool `json:"is_expired" query:"is_expired" description:"是否已过期 (true:已过期, false:未过期)"`
|
||||
Identifier string `json:"identifier" query:"identifier" validate:"omitempty,max=100" maxLength:"100" description:"资产标识符(ICCID 或 VirtualNo)精确查询"`
|
||||
Identifier string `json:"identifier" query:"identifier" validate:"omitempty,max=100" maxLength:"100" description:"资产标识符(支持 ICCID/VirtualNo/IMEI/SN/MSISDN,按资产解析后查询对应订单)"`
|
||||
BuyerPhone string `json:"buyer_phone" query:"buyer_phone" validate:"omitempty,max=20" maxLength:"20" description:"买家手机号精确查询"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1087,6 +1087,9 @@ func (s *Service) List(ctx context.Context, req *dto.OrderListRequest, buyerType
|
||||
if req.PurchaseRole != "" {
|
||||
filters["purchase_role"] = req.PurchaseRole
|
||||
}
|
||||
if req.SellerShopID != nil {
|
||||
filters["seller_shop_id"] = *req.SellerShopID
|
||||
}
|
||||
if req.StartTime != nil {
|
||||
filters["start_time"] = req.StartTime
|
||||
}
|
||||
@@ -1094,7 +1097,18 @@ func (s *Service) List(ctx context.Context, req *dto.OrderListRequest, buyerType
|
||||
filters["end_time"] = req.EndTime
|
||||
}
|
||||
if req.Identifier != "" {
|
||||
resolvedIotCardID, resolvedDeviceID, err := s.resolveOrderListAssetIdentifier(ctx, req.Identifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 保留快照标识匹配,并叠加资产 ID 匹配(由 Store 层统一按 OR 组合)
|
||||
filters["identifier"] = req.Identifier
|
||||
if resolvedIotCardID != nil {
|
||||
filters["iot_card_id"] = *resolvedIotCardID
|
||||
}
|
||||
if resolvedDeviceID != nil {
|
||||
filters["device_id"] = *resolvedDeviceID
|
||||
}
|
||||
}
|
||||
if req.BuyerPhone != "" {
|
||||
filters["buyer_phone"] = req.BuyerPhone
|
||||
@@ -1134,6 +1148,75 @@ func (s *Service) List(ctx context.Context, req *dto.OrderListRequest, buyerType
|
||||
}, nil
|
||||
}
|
||||
|
||||
// resolveOrderListAssetIdentifier 将订单列表的统一资产标识解析为卡或设备 ID
|
||||
// 支持 ICCID、VirtualNo、IMEI、SN、MSISDN,与资产解析接口的识别口径保持一致。
|
||||
func (s *Service) resolveOrderListAssetIdentifier(ctx context.Context, identifier string) (*uint, *uint, error) {
|
||||
if identifier == "" {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
if s.assetIdentifierStore != nil {
|
||||
regRecord, regErr := s.assetIdentifierStore.FindByIdentifier(ctx, identifier)
|
||||
if regErr != nil {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, regErr, "查询资产标识符失败")
|
||||
}
|
||||
if regRecord != nil {
|
||||
switch regRecord.AssetType {
|
||||
case model.AssetTypeIotCard:
|
||||
card, cardErr := s.iotCardStore.GetByID(ctx, regRecord.AssetID)
|
||||
if cardErr == nil && card != nil {
|
||||
cardID := card.ID
|
||||
return &cardID, nil, nil
|
||||
}
|
||||
if cardErr != nil && cardErr != gorm.ErrRecordNotFound {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, cardErr, "查询物联网卡失败")
|
||||
}
|
||||
case model.AssetTypeDevice:
|
||||
device, deviceErr := s.deviceStore.GetByID(ctx, regRecord.AssetID)
|
||||
if deviceErr == nil && device != nil {
|
||||
deviceID := device.ID
|
||||
return nil, &deviceID, nil
|
||||
}
|
||||
if deviceErr != nil && deviceErr != gorm.ErrRecordNotFound {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, deviceErr, "查询设备失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
device, deviceErr := s.deviceStore.GetByIdentifier(ctx, identifier)
|
||||
if deviceErr == nil && device != nil {
|
||||
deviceID := device.ID
|
||||
return nil, &deviceID, nil
|
||||
}
|
||||
if deviceErr != nil && deviceErr != gorm.ErrRecordNotFound {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, deviceErr, "查询设备失败")
|
||||
}
|
||||
|
||||
var card model.IotCard
|
||||
query := s.db.WithContext(ctx).Model(&model.IotCard{})
|
||||
query = middleware.ApplyShopFilter(ctx, query)
|
||||
|
||||
conditions := []string{"virtual_no = ?", "msisdn = ?", "iccid = ?"}
|
||||
args := []any{identifier, identifier, identifier}
|
||||
if len(identifier) == 19 {
|
||||
conditions = append(conditions, "iccid_19 = ?")
|
||||
args = append(args, identifier)
|
||||
} else if len(identifier) == 20 {
|
||||
conditions = append(conditions, "iccid_20 = ?")
|
||||
args = append(args, identifier)
|
||||
}
|
||||
|
||||
if err := query.Where(strings.Join(conditions, " OR "), args...).First(&card).Error; err == nil {
|
||||
cardID := card.ID
|
||||
return &cardID, nil, nil
|
||||
} else if err != gorm.ErrRecordNotFound {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, err, "查询物联网卡失败")
|
||||
}
|
||||
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (s *Service) Cancel(ctx context.Context, id uint, buyerType string, buyerID uint) error {
|
||||
order, err := s.orderStore.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
|
||||
@@ -124,11 +124,35 @@ func (s *OrderStore) List(ctx context.Context, opts *store.QueryOptions, filters
|
||||
if v, ok := filters["purchase_role"]; ok {
|
||||
query = query.Where("purchase_role = ?", v)
|
||||
}
|
||||
if v, ok := filters["iot_card_id"]; ok {
|
||||
query = query.Where("iot_card_id = ?", v)
|
||||
identifierValue, hasIdentifier := filters["identifier"]
|
||||
iotCardIDValue, hasIotCardID := filters["iot_card_id"]
|
||||
deviceIDValue, hasDeviceID := filters["device_id"]
|
||||
if hasIdentifier || hasIotCardID || hasDeviceID {
|
||||
assetQuery := s.db
|
||||
hasAnyAssetCondition := false
|
||||
if hasIdentifier {
|
||||
assetQuery = assetQuery.Where("asset_identifier = ?", identifierValue)
|
||||
hasAnyAssetCondition = true
|
||||
}
|
||||
if hasIotCardID {
|
||||
if hasAnyAssetCondition {
|
||||
assetQuery = assetQuery.Or("iot_card_id = ?", iotCardIDValue)
|
||||
} else {
|
||||
assetQuery = assetQuery.Where("iot_card_id = ?", iotCardIDValue)
|
||||
hasAnyAssetCondition = true
|
||||
}
|
||||
}
|
||||
if hasDeviceID {
|
||||
if hasAnyAssetCondition {
|
||||
assetQuery = assetQuery.Or("device_id = ?", deviceIDValue)
|
||||
} else {
|
||||
assetQuery = assetQuery.Where("device_id = ?", deviceIDValue)
|
||||
}
|
||||
}
|
||||
query = query.Where(assetQuery)
|
||||
}
|
||||
if v, ok := filters["device_id"]; ok {
|
||||
query = query.Where("device_id = ?", v)
|
||||
if v, ok := filters["seller_shop_id"]; ok {
|
||||
query = query.Where("seller_shop_id = ?", v)
|
||||
}
|
||||
if v, ok := filters["start_time"]; ok {
|
||||
query = query.Where("created_at >= ?", v)
|
||||
@@ -136,9 +160,6 @@ func (s *OrderStore) List(ctx context.Context, opts *store.QueryOptions, filters
|
||||
if v, ok := filters["end_time"]; ok {
|
||||
query = query.Where("created_at <= ?", v)
|
||||
}
|
||||
if v, ok := filters["identifier"]; ok {
|
||||
query = query.Where("asset_identifier = ?", v)
|
||||
}
|
||||
if v, ok := filters["buyer_phone"]; ok {
|
||||
query = query.Where("buyer_phone = ?", v)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user