2026-05-22 14:03:24 +08:00

142 lines
2.7 KiB
Go

package dashboard
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/shopspring/decimal"
)
type Row map[string]interface{}
func (r Row) String(name string) string {
value, ok := r[name]
if !ok || value == nil {
return ""
}
switch typed := value.(type) {
case []byte:
return string(typed)
case string:
return typed
default:
return fmt.Sprint(typed)
}
}
func (r Row) Int64(name string) int64 {
value, ok := r[name]
if !ok || value == nil {
return 0
}
switch typed := value.(type) {
case int:
return int64(typed)
case int8:
return int64(typed)
case int16:
return int64(typed)
case int32:
return int64(typed)
case int64:
return typed
case uint:
return int64(typed)
case uint8:
return int64(typed)
case uint16:
return int64(typed)
case uint32:
return int64(typed)
case uint64:
return int64(typed)
case []byte:
parsed, _ := strconv.ParseInt(string(typed), 10, 64)
return parsed
case string:
parsed, _ := strconv.ParseInt(typed, 10, 64)
return parsed
default:
parsed, _ := strconv.ParseInt(fmt.Sprint(typed), 10, 64)
return parsed
}
}
func (r Row) Bool(name string) bool {
return r.Int64(name) != 0
}
func (r Row) Decimal(name string) decimal.Decimal {
value, ok := r[name]
if !ok || value == nil {
return decimal.Zero
}
switch typed := value.(type) {
case decimal.Decimal:
return typed
case float32:
return decimal.NewFromFloat32(typed)
case float64:
return decimal.NewFromFloat(typed)
case int64:
return decimal.NewFromInt(typed)
case int:
return decimal.NewFromInt(int64(typed))
case []byte:
parsed, _ := decimal.NewFromString(string(typed))
return parsed
case string:
parsed, _ := decimal.NewFromString(typed)
return parsed
default:
parsed, _ := decimal.NewFromString(fmt.Sprint(typed))
return parsed
}
}
func (r Row) Time(name string) time.Time {
value, ok := r[name]
if !ok || value == nil {
return time.Time{}
}
switch typed := value.(type) {
case time.Time:
return typed
case []byte:
return parseTimeString(string(typed))
case string:
return parseTimeString(typed)
default:
return parseTimeString(fmt.Sprint(typed))
}
}
func (r Row) MillisTime(name string) time.Time {
millis := r.Int64(name)
if millis <= 0 {
return time.Time{}
}
return time.UnixMilli(millis)
}
func parseTimeString(value string) time.Time {
text := strings.TrimSpace(value)
if text == "" || strings.EqualFold(text, "<nil>") {
return time.Time{}
}
for _, layout := range []string{
time.RFC3339Nano,
"2006-01-02 15:04:05.999999",
"2006-01-02 15:04:05",
"2006-01-02",
} {
parsed, err := time.ParseInLocation(layout, text, time.Local)
if err == nil {
return parsed
}
}
return time.Time{}
}