package dwbg import ( "fmt" "math" "strconv" "strings" "time" "tyapi-server/internal/domains/api/services/processors/jrzq" ) func xypString(m map[string]interface{}, key string) string { if m == nil { return "" } val, ok := m[key] if !ok || val == nil { return "" } switch v := val.(type) { case string: return strings.TrimSpace(v) case float64: if math.IsNaN(v) || math.IsInf(v, 0) { return "" } if v == float64(int64(v)) { return strconv.FormatInt(int64(v), 10) } return strconv.FormatFloat(v, 'f', -1, 64) case int: return strconv.Itoa(v) case int64: return strconv.FormatInt(v, 10) default: return fmt.Sprint(v) } } func decodeXypInt(m map[string]interface{}, key string) int { code := xypString(m, key) if code == "" || code == "0" { return 0 } return jrzq.DecodeIntervalMidpoint(key, code) } func formatXypInterval(m map[string]interface{}, key string) string { code := xypString(m, key) if code == "" || code == "0" { return "0" } if conv := xypIntervalConverter(key); conv != nil { return conv(code) } return jrzq.FormatLoanRiskInterval(key, code) } func xypIntervalConverter(key string) func(string) string { switch key { case "xyp_t01aazzzc": return convertXypT01aazzzcToInterval case "xyp_cpl0068": return convertXypCpl0068ToInterval case "xyp_cpl0001": return convertXypCpl0001ToInterval case "xyp_cpl0002": return convertXypCpl0002ToInterval case "xyp_cpl0071": return convertXypCpl0071ToInterval case "xyp_cpl0072": return convertXypCpl0072ToInterval case "xyp_cpl0018", "xyp_cpl0019", "xyp_cpl0020", "xyp_cpl0021", "xyp_cpl0022", "xyp_cpl0023", "xyp_cpl0024", "xyp_cpl0025", "xyp_cpl0026": return func(code string) string { return callCplCountConverter(key, code) } case "xyp_cpl0034", "xyp_cpl0035", "xyp_cpl0036", "xyp_cpl0037", "xyp_cpl0038", "xyp_cpl0039", "xyp_cpl0040", "xyp_cpl0041", "xyp_cpl0042": return func(code string) string { return callCplAmountConverter(key, code) } default: return nil } } func callCplCountConverter(key, code string) string { switch key { case "xyp_cpl0018": return convertXypCpl0018ToInterval(code) case "xyp_cpl0019": return convertXypCpl0019ToInterval(code) case "xyp_cpl0020": return convertXypCpl0020ToInterval(code) case "xyp_cpl0021": return convertXypCpl0021ToInterval(code) case "xyp_cpl0022": return convertXypCpl0022ToInterval(code) case "xyp_cpl0023": return convertXypCpl0023ToInterval(code) case "xyp_cpl0024": return convertXypCpl0024ToInterval(code) case "xyp_cpl0025": return convertXypCpl0025ToInterval(code) case "xyp_cpl0026": return convertXypCpl0026ToInterval(code) default: return jrzq.FormatLoanRiskInterval(key, code) } } func callCplAmountConverter(key, code string) string { switch key { case "xyp_cpl0034": return convertXypCpl0034ToInterval(code) case "xyp_cpl0035": return convertXypCpl0035ToInterval(code) case "xyp_cpl0036": return convertXypCpl0036ToInterval(code) case "xyp_cpl0037": return convertXypCpl0037ToInterval(code) case "xyp_cpl0038": return convertXypCpl0038ToInterval(code) case "xyp_cpl0039": return convertXypCpl0039ToInterval(code) case "xyp_cpl0040": return convertXypCpl0040ToInterval(code) case "xyp_cpl0041": return convertXypCpl0041ToInterval(code) case "xyp_cpl0042": return convertXypCpl0042ToInterval(code) default: return jrzq.FormatLoanRiskInterval(key, code) } } func formatXypNumericString(m map[string]interface{}, key string) string { mid := decodeXypInt(m, key) if mid <= 0 { return "0" } return strconv.Itoa(mid) } func formatOverdueAmountHyphen(m map[string]interface{}, key string) string { interval := formatXypInterval(m, key) if interval == "0" || interval == "-" { return "0" } return intervalToHyphen(interval) } func intervalToHyphen(interval string) string { interval = strings.TrimSpace(interval) if interval == "0" || interval == "-" { return interval } inner := strings.TrimPrefix(strings.TrimPrefix(interval, "("), "[") inner = strings.TrimSuffix(strings.TrimSuffix(inner, ")"), "]") parts := strings.SplitN(inner, ",", 2) if len(parts) != 2 { return interval } left := strings.TrimSpace(parts[0]) right := strings.TrimSpace(parts[1]) right = strings.TrimSuffix(right, "+)") right = strings.TrimSuffix(right, "+") if left == "" || right == "" { return interval } return left + "-" + right } func reverseYYYYMMFromCpl0046(m map[string]interface{}) string { days := decodeXypInt(m, "xyp_cpl0046") if days <= 0 { return "-" } return time.Now().AddDate(0, 0, -days).Format("2006-01") } func formatNormalRepaymentRatio(m map[string]interface{}) string { raw := xypString(m, "xyp_cpl0074") if raw == "" || raw == "0" || raw == "-1" { return "0" } if val, err := strconv.ParseFloat(raw, 64); err == nil { if val <= 1 && val >= 0 { return fmt.Sprintf("%.0f%%", val*100) } if val > 1 && val <= 100 { return fmt.Sprintf("%.0f%%", val) } } mid := decodeXypInt(m, "xyp_cpl0074") if mid <= 0 { return "0" } return fmt.Sprintf("%d%%", mid) } func parseIntValue(val interface{}) int { switch v := val.(type) { case int: return v case int64: return int(v) case float64: return int(v) case string: if v == "" { return 0 } if n, err := strconv.Atoi(v); err == nil { return n } } return 0 } func mergeInto(base map[string]interface{}, key string, patch map[string]interface{}) { if patch == nil { return } existing, ok := base[key].(map[string]interface{}) if !ok { base[key] = patch return } for k, v := range patch { existing[k] = v } }