mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-12-24 08:12:55 +08:00
156 lines
3.1 KiB
Go
156 lines
3.1 KiB
Go
package core
|
||
|
||
import (
|
||
"database/sql/driver"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"strconv"
|
||
"x_admin/util/convert_util"
|
||
)
|
||
|
||
// 支持前端传递null,int,string类型和不传值
|
||
// 前端传1,“1”都可以,都转换为int64类型: NullInt{Int: 1, Exist: true}
|
||
// 前端null值: NullInt{Int: nil, Exist: true}
|
||
// 前端没传值: NullInt{Int: nil, Exist: false}
|
||
|
||
type NullInt struct {
|
||
Val *int64 // 整数或者null
|
||
Exist bool // 是否有值
|
||
}
|
||
|
||
func DecodeInt(value any) (any, error) {
|
||
switch v := value.(type) {
|
||
case nil:
|
||
return NullInt{Val: nil, Exist: false}, nil
|
||
case NullInt:
|
||
return v, nil
|
||
default:
|
||
result, err := convert_util.ToInt64(value)
|
||
if err != nil {
|
||
return NullInt{Val: nil, Exist: false}, err
|
||
}
|
||
return NullInt{Val: &result, Exist: true}, nil
|
||
}
|
||
|
||
}
|
||
|
||
// gorm实现Scanner
|
||
func (i *NullInt) Scan(value interface{}) error {
|
||
// 判断int64、string类型
|
||
switch v := value.(type) {
|
||
case nil:
|
||
i.Exist = true
|
||
return nil
|
||
case int64:
|
||
i.Val, i.Exist = &v, true
|
||
return nil
|
||
case string:
|
||
num, err := strconv.ParseInt(v, 10, 64)
|
||
if err == nil {
|
||
i.Val = &num
|
||
i.Exist = true
|
||
} else {
|
||
i.Exist = false
|
||
}
|
||
return err
|
||
default:
|
||
return fmt.Errorf("不能将类型 %T 转换为 int64", v)
|
||
}
|
||
}
|
||
|
||
// gorm实现 Valuer
|
||
func (i NullInt) Value() (driver.Value, error) {
|
||
if !i.Exist {
|
||
return nil, nil
|
||
}
|
||
v := i.Val
|
||
if v == nil {
|
||
return nil, nil
|
||
}
|
||
return *v, nil
|
||
}
|
||
func (i NullInt) String() string {
|
||
if i.Exist {
|
||
return strconv.FormatInt(*i.Val, 10)
|
||
} else {
|
||
return ""
|
||
}
|
||
}
|
||
|
||
// 实现json序列化接口
|
||
func (i NullInt) MarshalJSON() ([]byte, error) {
|
||
if i.Exist {
|
||
return json.Marshal(i.Val)
|
||
} else {
|
||
return json.Marshal(nil)
|
||
}
|
||
}
|
||
func (i *NullInt) UnmarshalText(text []byte) error {
|
||
return i.Scan(string(text))
|
||
}
|
||
|
||
// 实现gin框架的参数绑定接口
|
||
func (i *NullInt) UnmarshalParam(param string) error {
|
||
return i.Scan(param)
|
||
}
|
||
|
||
// 实现json反序列化接口,支持 int64, string,null类型,对于float64类型,判断转换前后是否相等,防止精度丢失
|
||
func (i *NullInt) UnmarshalJSON(data []byte) error {
|
||
var x any
|
||
if err := json.Unmarshal(data, &x); err != nil {
|
||
return err
|
||
}
|
||
switch v := x.(type) {
|
||
case nil:
|
||
i.Exist = true
|
||
return nil
|
||
case int64:
|
||
i.Val = &v
|
||
i.Exist = true
|
||
return nil
|
||
case float64:
|
||
i64 := int64(v)
|
||
// 判断转换前后是否相等,防止精度丢失
|
||
if float64(i64) != v {
|
||
i.Exist = false
|
||
return errors.New("int64转换失败," + fmt.Sprintf("%f", v) + "精度丢失")
|
||
}
|
||
i.Val = &i64
|
||
i.Exist = true
|
||
return nil
|
||
case string:
|
||
if v == "" {
|
||
i.Val = nil
|
||
i.Exist = true
|
||
return nil
|
||
}
|
||
num, err := strconv.ParseInt(v, 10, 64)
|
||
if err == nil {
|
||
i.Val = &num
|
||
i.Exist = true
|
||
} else {
|
||
i.Exist = false
|
||
}
|
||
return err
|
||
|
||
default:
|
||
return fmt.Errorf("不能将类型 %T 转换为 int64, 值为 %v", v, v)
|
||
}
|
||
|
||
}
|
||
func (i *NullInt) SetValue(value int64) {
|
||
i.Val = &value
|
||
i.Exist = true
|
||
}
|
||
func (i *NullInt) SetNull() {
|
||
i.Val = nil
|
||
i.Exist = true
|
||
}
|
||
func (i *NullInt) IsExists() bool {
|
||
return i.Exist
|
||
}
|
||
func (i *NullInt) GetValue() *int64 {
|
||
return i.Val
|
||
}
|