126 lines
3.2 KiB
Go
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
|
|
}
|
|
}
|