Files
affiliate_dash/backend/internal/service/fulfillment_data.go
T

172 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"encoding/json"
"strconv"
"strings"
"time"
"affiliate_dash/internal/pkg/timeutil"
)
// buildShipNotifyResultData 把推送结果与游戏字段合并进 ResultData JSON。
func buildShipNotifyResultData(existing string, in ShipNotifyInput, shippedAt *time.Time) string {
m := map[string]interface{}{}
if existing != "" && json.Valid([]byte(existing)) {
_ = json.Unmarshal([]byte(existing), &m)
}
m["ship_status"] = in.ShipStatus
if in.ProviderOrderNo != "" {
m["provider_order_no"] = in.ProviderOrderNo
}
if in.ShipStatus == "success" {
delete(m, "fail_reason")
} else if in.FailReason != "" {
m["fail_reason"] = in.FailReason
}
if shippedAt != nil {
m["shipped_at"] = timeutil.FormatAPITime(*shippedAt)
}
if in.GameChannel != nil {
m["game_channel"] = *in.GameChannel
}
if in.GameUID != nil {
m["game_uid"] = *in.GameUID
}
if in.RoleName != nil {
m["role_name"] = *in.RoleName
}
if in.PayScore != nil {
m["pay_score"] = *in.PayScore
}
raw, err := json.Marshal(m)
if err != nil {
return existing
}
return string(raw)
}
// mergeResultData 保留已有 JSON 字段,仅覆盖或新增 patch 中的字段,避免各发货阶段互相清空上下文。
func mergeResultData(existing string, patch map[string]interface{}) string {
if len(patch) == 0 {
return existing
}
m := resultDataMap(existing)
for k, v := range patch {
m[k] = v
}
raw, err := json.Marshal(m)
if err != nil {
return existing
}
return string(raw)
}
func resultDataMap(raw string) map[string]interface{} {
m := map[string]interface{}{}
if raw == "" {
return m
}
if err := json.Unmarshal([]byte(raw), &m); err != nil {
// 容错:如果 raw 被双重序列化为 string(如 "\"{\\\"provider\\\":...}\"")
var inner string
if json.Unmarshal([]byte(raw), &inner) == nil && inner != "" {
_ = json.Unmarshal([]byte(inner), &m)
}
}
return m
}
// requestDataMap 解析下单透传的 data(RequestData),非法或为空时返回空 map。
func requestDataMap(raw string) map[string]interface{} {
m := map[string]interface{}{}
if raw == "" {
return m
}
if err := json.Unmarshal([]byte(raw), &m); err != nil {
var inner string
if json.Unmarshal([]byte(raw), &inner) == nil && inner != "" {
_ = json.Unmarshal([]byte(inner), &m)
}
}
return m
}
// requestDataString 读取下单透传 data 中的字符串字段。
func requestDataString(raw, key string) string {
if v, ok := requestDataMap(raw)[key].(string); ok {
return strings.TrimSpace(v)
}
return ""
}
func resultDataString(raw, key string) string {
if v, ok := resultDataMap(raw)[key].(string); ok {
return v
}
return ""
}
func resultDataNumber(raw, key string) int64 {
switch v := resultDataMap(raw)[key].(type) {
case float64:
return int64(v)
case int64:
return v
case int:
return int64(v)
case string:
if n, err := strconv.ParseInt(v, 10, 64); err == nil {
return n
}
}
return 0
}
// extractGameFields 从 JSON 文本中还原游戏相关字段(仅填充当前为空的字段)。
func extractGameFields(raw string, out *OpenOrderQuery) {
if raw == "" || !json.Valid([]byte(raw)) {
return
}
var m map[string]interface{}
if err := json.Unmarshal([]byte(raw), &m); err != nil {
return
}
if out.GameChannel == "" {
if v, ok := m["game_channel"].(string); ok {
out.GameChannel = v
}
}
if out.GameUID == "" {
if v, ok := m["game_uid"].(string); ok && v != "" {
out.GameUID = v
} else if v, ok := m["game_account"].(string); ok && v != "" {
out.GameUID = v
}
}
if out.RoleName == "" {
if v, ok := m["role_name"].(string); ok && v != "" {
out.RoleName = v
} else if v, ok := m["game_account_role_name"].(string); ok && v != "" {
out.RoleName = v
}
}
if out.PayScore == 0 {
if v, ok := toInt(m["pay_score"]); ok {
out.PayScore = v
}
}
}
func toInt(v interface{}) (int, bool) {
switch n := v.(type) {
case float64:
return int(n), true
case int:
return n, true
case int64:
return int(n), true
}
return 0, false
}