refactor(app): 优化 URL 处理和 JSON 解析逻辑

- 更新应用程序处理程序中的 URL 赋值逻辑,确保静态文件使用原始路径
- 修改缓存数据库的 JSON 解析方法,使用 JsonToObj 函数替代 json.Unmarshal,提升代码可读性和性能
- 在 Map 和 Slice 类型中新增获取四舍五入浮点数的方法,增强数据处理能力
- 在 Obj 类型中添加四舍五入功能,支持精度控制
- 改进数据库查询结果的处理逻辑,确保数据类型的准确性和一致性
- 优化日志格式设置,增强日志信息的可读性
This commit is contained in:
2026-03-10 23:44:41 +08:00
parent bf9bb5807d
commit fab7931d3c
15 changed files with 4116 additions and 147 deletions
+190 -119
View File
@@ -1,6 +1,7 @@
package common
import (
"bytes"
"encoding/json"
"errors"
"math"
@@ -18,31 +19,40 @@ func ObjToMap(obj interface{}, e ...*Error) Map {
v = nil
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
switch val := obj.(type) {
case Map:
v = obj.(Map)
v = val
case map[string]interface{}:
v = obj.(map[string]interface{})
v = Map(val)
case string:
v = Map{}
e := json.Unmarshal([]byte(obj.(string)), &v)
if e != nil {
err = errors.New("没有合适的转换对象!" + e.Error())
result, e2 := JsonToObj(val)
if e2 != nil {
err = errors.New("没有合适的转换对象!" + e2.Error())
v = nil
} else if m, ok := result.(map[string]interface{}); ok {
v = m
} else {
err = errors.New("没有合适的转换对象!")
v = nil
}
default:
data, err := json.Marshal(obj)
var data []byte
data, err = json.Marshal(obj)
if err != nil {
err = errors.New("没有合适的转换对象!" + err.Error())
v = nil
break
}
v = Map{}
e := json.Unmarshal(data, &v)
if e != nil {
err = errors.New("没有合适的转换对象!" + e.Error())
result, e2 := JsonToObj(string(data))
if e2 != nil {
err = errors.New("没有合适的转换对象!" + e2.Error())
v = nil
} else if m, ok := result.(map[string]interface{}); ok {
v = m
} else {
err = errors.New("没有合适的转换对象!")
v = nil
}
}
}
if len(e) != 0 {
@@ -53,7 +63,7 @@ func ObjToMap(obj interface{}, e ...*Error) Map {
func ObjToMapArray(obj interface{}, e ...*Error) []Map {
s := ObjToSlice(obj, e...)
res := []Map{}
res := make([]Map, 0, len(s))
for i := 0; i < len(s); i++ {
res = append(res, s.GetMap(i))
}
@@ -69,25 +79,39 @@ func ObjToSlice(obj interface{}, e ...*Error) Slice {
v = nil
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
switch val := obj.(type) {
case Slice:
v = obj.(Slice)
v = val
case []interface{}:
v = obj.([]interface{})
v = Slice(val)
case []string:
v = Slice{}
for i := 0; i < len(obj.([]string)); i++ {
v = append(v, obj.([]string)[i])
v = make(Slice, len(val))
for i, s := range val {
v[i] = s
}
case string:
v = Slice{}
err = json.Unmarshal([]byte(obj.(string)), &v)
result, e2 := JsonToObj(val)
if e2 != nil {
err = e2
} else if s, ok := result.([]interface{}); ok {
v = s
} else {
err = errors.New("没有合适的转换对象!")
}
default:
v = Slice{}
var data []byte
data, err = json.Marshal(obj)
err = json.Unmarshal(data, &v)
if err != nil {
break
}
result, e2 := JsonToObj(string(data))
if e2 != nil {
err = e2
} else if s, ok := result.([]interface{}); ok {
v = s
} else {
err = errors.New("没有合适的转换对象!")
}
}
}
@@ -104,22 +128,24 @@ func ObjToTime(obj interface{}, e ...*Error) *time.Time {
//字符串类型,只支持标准mysql datetime格式
if tInt == 0 {
tStr := ObjToStr(obj)
timeNewStr := ""
timeNewStrs := strings.Split(tStr, "-")
for _, v := range timeNewStrs {
if v == "" {
continue
}
if len(v) == 1 {
v = "0" + v
}
if timeNewStr == "" {
timeNewStr = v
continue
}
timeNewStr = timeNewStr + "-" + v
// 先分离日期和时间部分,再对日期各段补零,避免时间中的数字被误处理
datePart := tStr
timePart := ""
if idx := strings.Index(tStr, " "); idx > 0 {
datePart = tStr[:idx]
timePart = tStr[idx:] // 含前导空格
}
tStr = timeNewStr
dateSegs := strings.Split(datePart, "-")
for i, seg := range dateSegs {
if seg == "" {
continue
}
if len(seg) == 1 {
dateSegs[i] = "0" + seg
}
}
tStr = strings.Join(dateSegs, "-") + timePart
if len(tStr) > 18 {
t, e := time.Parse("2006-01-02 15:04:05", tStr)
if e == nil {
@@ -146,31 +172,30 @@ func ObjToTime(obj interface{}, e ...*Error) *time.Time {
return &t
}
}
}
// 缓存字符串,避免重复调用
tIntStr := ObjToStr(tInt)
tIntLen := len(tIntStr)
//纳秒级别
if len(ObjToStr(tInt)) > 16 {
//t := time.Time{}.Add(time.Nanosecond * time.Duration(tInt))
if tIntLen > 16 {
t := time.UnixMicro(tInt / 1000)
return &t
//微秒级别
} else if len(ObjToStr(tInt)) > 13 {
//t := time.Time{}.Add(time.Microsecond * time.Duration(tInt))
} else if tIntLen > 13 {
t := time.UnixMicro(tInt)
return &t
//毫秒级别
} else if len(ObjToStr(tInt)) > 10 {
//t := time.Time{}.Add(time.Millisecond * time.Duration(tInt))
} else if tIntLen > 10 {
t := time.UnixMilli(tInt)
return &t
//秒级别
} else if len(ObjToStr(tInt)) > 9 {
//t := time.Time{}.Add(time.Second * time.Duration(tInt))
} else if tIntLen > 9 {
t := time.Unix(tInt, 0)
return &t
} else if len(ObjToStr(tInt)) > 3 {
t, e := time.Parse("2006", ObjToStr(tInt))
} else if tIntLen > 3 {
t, e := time.Parse("2006", tIntStr)
if e == nil {
return &t
}
@@ -184,37 +209,34 @@ func ObjToFloat64(obj interface{}, e ...*Error) float64 {
v := float64(0)
if obj == nil {
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
switch val := obj.(type) {
case int:
v = float64(obj.(int))
v = float64(val)
case int64:
v = float64(obj.(int64))
v = float64(val)
case string:
value, e := strconv.ParseFloat(obj.(string), 64)
if e != nil {
v = float64(0)
err = e
value, e2 := strconv.ParseFloat(val, 64)
if e2 != nil {
err = e2
} else {
v = value
}
case float64:
v = obj.(float64)
v = val
case float32:
v = float64(obj.(float32))
case uint8:
value, e := strconv.ParseFloat(obj.(string), 64)
if e != nil {
v = float64(0)
err = e
// 通过 string 中转避免 float32→float64 精度膨胀(如 float32(1.2) 直接转得 1.200000047...
v, _ = strconv.ParseFloat(strconv.FormatFloat(float64(val), 'f', -1, 32), 64)
case []byte:
// 数据库 driver 有时以 []byte 返回数值字符串
value, e2 := strconv.ParseFloat(string(val), 64)
if e2 != nil {
err = e2
} else {
v = value
}
default:
v = float64(0)
err = errors.New("没有合适的转换对象!")
}
}
@@ -234,25 +256,33 @@ func ObjToFloat64(obj interface{}, e ...*Error) float64 {
return v
}
// ObjToRoundFloat64 将 obj 转为 float64 后四舍五入到 precision 位小数。
// precision < 0 时不做舍入,直接返回原始 float64。
func ObjToRoundFloat64(obj interface{}, precision int, e ...*Error) float64 {
f := ObjToFloat64(obj, e...)
if precision < 0 {
return f
}
pow := math.Pow10(precision)
return math.Round(f*pow) / pow
}
// 向上取整
func ObjToCeilInt64(obj interface{}, e ...*Error) int64 {
f := ObjToCeilFloat64(obj, e...)
return ObjToInt64(math.Ceil(f))
return int64(f)
}
// 向上取整
func ObjToCeilFloat64(obj interface{}, e ...*Error) float64 {
f := ObjToFloat64(obj, e...)
return math.Ceil(f)
}
// 向上取整
func ObjToCeilInt(obj interface{}, e ...*Error) int {
f := ObjToCeilFloat64(obj, e...)
return ObjToInt(f)
}
func ObjToInt64(obj interface{}, e ...*Error) int64 {
@@ -260,36 +290,43 @@ func ObjToInt64(obj interface{}, e ...*Error) int64 {
v := int64(0)
if obj == nil {
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
switch val := obj.(type) {
case int:
v = int64(obj.(int))
v = int64(val)
case int64:
v = obj.(int64)
v = val
case string:
value, e := StrToInt(obj.(string))
if e != nil {
v = int64(0)
err = e
value, e2 := StrToInt(val)
if e2 != nil {
// fallback:处理 "1.20" 这类带小数点的整数字符串
if fv, fe := strconv.ParseFloat(val, 64); fe == nil {
v = int64(fv)
} else {
err = e2
}
} else {
v = int64(value)
}
case uint8:
value, e := StrToInt(obj.(string))
if e != nil {
v = int64(0)
err = e
case []byte:
// 数据库 driver 有时以 []byte 返回整数字符串
value, e2 := StrToInt(string(val))
if e2 != nil {
// fallback:处理 "1.20" 这类带小数点的整数字符串
if fv, fe := strconv.ParseFloat(string(val), 64); fe == nil {
v = int64(fv)
} else {
err = e2
}
} else {
v = int64(value)
}
case float64:
v = int64(obj.(float64))
v = int64(val)
case float32:
v = int64(obj.(float32))
v = int64(val)
default:
v = int64(0)
err = errors.New("没有合适的转换对象!")
}
}
@@ -309,18 +346,19 @@ func ObjToBool(obj interface{}, e ...*Error) bool {
v := false
if obj == nil {
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
switch val := obj.(type) {
case bool:
v = obj.(bool)
v = val
default:
toInt := ObjToInt(obj)
if toInt != 0 {
var intErr Error
toInt := ObjToInt(obj, &intErr)
if intErr.GetError() != nil {
err = errors.New("没有合适的转换对象!")
} else if toInt != 0 {
v = true
}
err = errors.New("没有合适的转换对象!")
}
}
if len(e) != 0 {
@@ -330,55 +368,92 @@ func ObjToBool(obj interface{}, e ...*Error) bool {
}
func ObjToStr(obj interface{}) string {
// fmt.Println(reflect.ValueOf(obj).Type().String() )
str := ""
if obj == nil {
return str
}
switch obj.(type) {
switch val := obj.(type) {
case int:
str = strconv.Itoa(obj.(int))
str = strconv.Itoa(val)
case uint8:
str = obj.(string)
str = strconv.Itoa(int(val))
case int64:
str = strconv.FormatInt(obj.(int64), 10)
str = strconv.FormatInt(val, 10)
case []byte:
str = string(obj.([]byte))
str = string(val)
case string:
str = obj.(string)
str = val
case float64:
str = strconv.FormatFloat(obj.(float64), 'f', -1, 64)
str = strconv.FormatFloat(val, 'f', -1, 64)
case float32:
str = strconv.FormatFloat(float64(val), 'f', -1, 32)
case bool:
str = strconv.FormatBool(val)
default:
strbte, err := json.MarshalIndent(obj, "", "\t")
if err == nil {
str = string(strbte)
}
}
return str
}
// 转换为Map
func StrToMap(string string) Map {
data := Map{}
data.JsonToMap(string)
// JsonToObj 将 JSON 字符串反序列化为 interface{},保留数字原始类型。
// 标准 json.Unmarshal 会把所有 JSON 数字变成 float64,本函数保留整数为 int64、小数为 float64。
//
// JsonToObj(`{"id":2,"price":1.20}`) → map{"id": int64(2), "price": float64(1.2)}
// JsonToObj(`[1, 2.5, "a"]`) → []interface{}{int64(1), float64(2.5), "a"}
func JsonToObj(jsonStr string) (interface{}, error) {
dec := json.NewDecoder(bytes.NewReader([]byte(jsonStr)))
dec.UseNumber()
var result interface{}
if err := dec.Decode(&result); err != nil {
return nil, err
}
return fixJsonNumbers(result), nil
}
// fixJsonNumbers 递归将 json.Number 转为 int64 或 float64
func fixJsonNumbers(v interface{}) interface{} {
switch val := v.(type) {
case json.Number:
if n, err := val.Int64(); err == nil {
return n
}
if f, err := val.Float64(); err == nil {
return f
}
return string(val)
case map[string]interface{}:
for k, item := range val {
val[k] = fixJsonNumbers(item)
}
return val
case []interface{}:
for i, item := range val {
val[i] = fixJsonNumbers(item)
}
return val
default:
return val
}
}
// 转换为Map
func StrToMap(s string) Map {
data := Map{}
data.JsonToMap(s)
return data
}
// 转换为Slice
func StrToSlice(string string) Slice {
data := ObjToSlice(string)
return data
func StrToSlice(s string) Slice {
return ObjToSlice(s)
}
// 字符串数组: a1,a2,a3转["a1","a2","a3"]
func StrArrayToJsonStr(a string) string {
if len(a) > 2 {
if a[0] == ',' {
a = Substr(a, 1, len(a)-1)
@@ -386,7 +461,6 @@ func StrArrayToJsonStr(a string) string {
if a[len(a)-1] == ',' {
a = Substr(a, 0, len(a)-1)
}
//a = strings.Replace(a, ",", `,`, -1)
a = `[` + a + `]`
} else {
a = "[]"
@@ -394,13 +468,11 @@ func StrArrayToJsonStr(a string) string {
return a
}
// 字符串数组: a1,a2,a3转["a1","a2","a3"]
// 字符串数组: ["a1","a2","a3"]转,a1,a2,a3,
func JsonStrToStrArray(a string) string {
//a = strings.Replace(a, `"`, "", -1)
if len(a) != 0 {
a = Substr(a, 1, len(a)-2)
}
return "," + a + ","
}
@@ -408,5 +480,4 @@ func JsonStrToStrArray(a string) string {
func StrToInt(s string) (int, error) {
i, err := strconv.Atoi(s)
return i, err
}