All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m42s
- getStatusLogic 类型断言修复(*user.User) - restoreLogic 事务拆分为单条处理 + appAccountToken 解析 - attachTransactionLogic 提取 ParseProductIdDuration 共享函数 - 新增 config_helper.go 统一 Apple API 配置加载 - reconcileLogic 补充 BundleID 配置读取 - activateOrderLogic 邀请赠送天数逻辑完善 Co-Authored-By: claude-flow <ruv@ruv.net>
83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
package apple
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type ProductMapping struct {
|
|
DurationDays int64 `json:"durationDays"`
|
|
Tier string `json:"tier"`
|
|
Description string `json:"description"`
|
|
PriceText string `json:"priceText"`
|
|
SubscribeId int64 `json:"subscribeId"`
|
|
}
|
|
|
|
type ProductMap struct {
|
|
Items map[string]ProductMapping `json:"iapProductMap"`
|
|
}
|
|
|
|
func ParseProductMap(customData string) (*ProductMap, error) {
|
|
if customData == "" {
|
|
return &ProductMap{Items: map[string]ProductMapping{}}, nil
|
|
}
|
|
var obj ProductMap
|
|
if err := json.Unmarshal([]byte(customData), &obj); err != nil {
|
|
return &ProductMap{Items: map[string]ProductMapping{}}, nil
|
|
}
|
|
if obj.Items == nil {
|
|
obj.Items = map[string]ProductMapping{}
|
|
}
|
|
return &obj, nil
|
|
}
|
|
|
|
func CalcExpire(start time.Time, days int64) time.Time {
|
|
if days <= 0 {
|
|
return time.UnixMilli(0)
|
|
}
|
|
return start.Add(time.Duration(days) * 24 * time.Hour)
|
|
}
|
|
|
|
// ParsedProduct holds the result of parsing an Apple product ID.
|
|
type ParsedProduct struct {
|
|
Unit string // "Day", "Month", "Year"
|
|
Quantity int64
|
|
}
|
|
|
|
// ParseProductIdDuration extracts time unit and quantity from Apple product IDs.
|
|
// e.g. "com.app.vip.day30" -> {Unit: "Day", Quantity: 30}
|
|
func ParseProductIdDuration(productId string) *ParsedProduct {
|
|
pid := strings.ToLower(productId)
|
|
parts := strings.Split(pid, ".")
|
|
for i := len(parts) - 1; i >= 0; i-- {
|
|
p := parts[i]
|
|
var unit string
|
|
switch {
|
|
case strings.HasPrefix(p, "day"):
|
|
unit = "Day"
|
|
p = p[len("day"):]
|
|
case strings.HasPrefix(p, "month"):
|
|
unit = "Month"
|
|
p = p[len("month"):]
|
|
case strings.HasPrefix(p, "year"):
|
|
unit = "Year"
|
|
p = p[len("year"):]
|
|
default:
|
|
continue
|
|
}
|
|
digits := p
|
|
for j := 0; j < len(digits); j++ {
|
|
if digits[j] < '0' || digits[j] > '9' {
|
|
digits = digits[:j]
|
|
break
|
|
}
|
|
}
|
|
if q, e := strconv.ParseInt(digits, 10, 64); e == nil && q > 0 {
|
|
return &ParsedProduct{Unit: unit, Quantity: q}
|
|
}
|
|
}
|
|
return nil
|
|
}
|