Files
shanshanzhong147 8bc8e81e95
Build docker and publish / build (20.15.1) (push) Has been cancelled
补单逻辑
2026-05-06 05:42:48 -07:00

126 lines
3.2 KiB
Go

package recovery
import (
_ "embed"
"encoding/json"
"fmt"
"strconv"
"strings"
"sync"
)
//go:embed recovery_orders.json
var recoveryOrdersJSON []byte
type Config struct {
Orders []Order `json:"orders"`
}
type Order struct {
OutOrderNo string `json:"out_order_no,omitempty"`
OrderNo string `json:"order_no"`
OrderStatus string `json:"order_status,omitempty"`
SubscribeId int64 `json:"subscribe_id"`
LegacyID string `json:"订阅id,omitempty"`
ExpireAt int64 `json:"expire_at"`
Quantity int64 `json:"quantity,omitempty"`
PaidAt int64 `json:"paid_at,omitempty"`
PaymentOrderNo string `json:"payment_order_no,omitempty"`
OrderMoneyCents int64 `json:"order_money_cents,omitempty"`
Note string `json:"note"`
}
var (
loadOnce sync.Once
orders map[string]Order
loadErr error
)
func FindOrder(orderNo string) (Order, bool, error) {
loadOnce.Do(func() {
orders, loadErr = loadOrders()
})
if loadErr != nil {
return Order{}, false, loadErr
}
item, ok := orders[strings.TrimSpace(orderNo)]
return item, ok, nil
}
func loadOrders() (map[string]Order, error) {
var cfg Config
if err := json.Unmarshal(recoveryOrdersJSON, &cfg); err != nil {
return nil, fmt.Errorf("parse recovery orders json: %w", err)
}
result := make(map[string]Order, len(cfg.Orders))
for i, item := range cfg.Orders {
item.OutOrderNo = strings.TrimSpace(item.OutOrderNo)
item.OrderNo = strings.TrimSpace(item.OrderNo)
item.OrderStatus = strings.ToLower(strings.TrimSpace(item.OrderStatus))
if item.OutOrderNo == "" {
item.OutOrderNo = item.OrderNo
}
if item.OrderNo == "" {
item.OrderNo = item.OutOrderNo
}
if item.OrderStatus == "" {
item.OrderStatus = "success"
}
if item.SubscribeId == 0 && strings.TrimSpace(item.LegacyID) != "" {
id, err := strconv.ParseInt(strings.TrimSpace(item.LegacyID), 10, 64)
if err != nil {
return nil, fmt.Errorf("orders[%d] legacy subscribe id is invalid", i)
}
item.SubscribeId = id
}
if item.OutOrderNo == "" {
return nil, fmt.Errorf("orders[%d] out_order_no is required", i)
}
if item.SubscribeId <= 0 {
return nil, fmt.Errorf("orders[%d] subscribe_id is required", i)
}
if item.ExpireAt <= 0 {
return nil, fmt.Errorf("orders[%d] expire_at is required", i)
}
if item.Quantity <= 0 {
item.Quantity = quantityFromAmount(item.OrderMoneyCents)
}
if item.Quantity <= 0 {
return nil, fmt.Errorf("orders[%d] quantity is required", i)
}
if item.PaidAt < 0 {
return nil, fmt.Errorf("orders[%d] paid_at is invalid", i)
}
if item.OrderMoneyCents < 0 {
return nil, fmt.Errorf("orders[%d] order_money_cents is invalid", i)
}
if _, exists := result[item.OutOrderNo]; exists {
return nil, fmt.Errorf("duplicate recovery out_order_no %s", item.OutOrderNo)
}
result[item.OutOrderNo] = item
if item.OrderNo != "" && item.OrderNo != item.OutOrderNo {
if _, exists := result[item.OrderNo]; exists {
return nil, fmt.Errorf("duplicate recovery order_no %s", item.OrderNo)
}
result[item.OrderNo] = item
}
}
return result, nil
}
func quantityFromAmount(amount int64) int64 {
switch amount {
case 1953:
return 7
case 4193:
return 30
case 9093:
return 90
case 31500:
return 365
default:
return 0
}
}