第一种方法 改成字符串类型
在全局返回方法中将bigint转成string
package controller
import (
"encoding/json"
beego "github.com/beego/beego/v2/server/web"
"github.com/gookit/validate"
"regexp"
"strconv"
"strings"
)
var (
SUCCESS_CODE = 20000
FAIL_CODE = 40001
SUCCESS_MSG = "success"
FAIL_MSG = "fail"
VALIDATOR_MAP = map[string]string{"code": "701", "msg": "属性验证有误"}
BINDING_PAMATERS_MAP = map[string]string{"code": "702", "msg": "参数绑定有误"}
)
/*父控制器 -- 继承beego.Controller*/
type BaseController struct {
beego.Controller
}
/*统一返回*/
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
func (web BaseController) Ok(data any) {
data = web.TransferData(data)
web.Data["json"] = &Response{Code: SUCCESS_CODE, Message: SUCCESS_MSG, Data: data}
web.ServeJSON()
}
/**
* @desc 对param参数进行转换
*/
func (web *BaseController) ParseParamUint64(key string, def ...uint64) (uint64, error) {
strv := web.Ctx.Input.Param(":" + key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.ParseUint(strv, 10, 64)
}
/**
* @desc 对param参数进行转换
*/
func (web *BaseController) ParseParamInt64(key string, def ...int64) (int64, error) {
strv := web.Ctx.Input.Param(":" + key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.ParseInt(strv, 10, 64)
}
/**
* @desc json参数的绑定
*/
func (web *BaseController) BindJSONToStruct(obj interface{}) error {
return json.Unmarshal(web.Ctx.Input.RequestBody, obj)
}
/*
*
- 获取用户IP地址
- @desc
由于前端使用了 nginx 做反向代理,所以通过 beego 框架内 提供的方法
Input.IP()获取到的IP是内网IP。不满足需求
nginx 代理中已经设置
location / {
proxy_set_header X-real-ip $remote_addr;
proxy_pass http://upstream/;
}
*/
func (web *BaseController) GetIpAddr() string {
header := web.Ctx.Request.Header
ip := header.Get("x-forwarded-for")
if ip == "" || len(ip) == 0 || "unknown" == ip {
ip = header.Get("Proxy-Client-IP")
}
if ip == "" || len(ip) == 0 || "unknown" == ip {
ip = header.Get("X-Forwarded-For")
}
if ip == "" || len(ip) == 0 || "unknown" == ip {
ip = header.Get("WL-Proxy-Client-IP")
}
if ip == "" || len(ip) == 0 || "unknown" == ip {
ip = header.Get("X-Real-IP")
}
if ip == "" || len(ip) == 0 || "unknown" == ip {
ip = web.Ctx.Input.IP()
}
if "0:0:0:0:0:0:0:1" == ip || strings.Contains(ip, "::1") {
return "127.0.0.1"
} else {
return ip
}
}
/**
* @desc 解决精度丢失的问题
*/
func (web BaseController) TransferData(data any) any {
j, _ := json.Marshal(data)
reg := regexp.MustCompile(`id":(\d{16,20}),"`)
l := len(reg.FindAllString(string(j), -1)) //正则匹配16-20位的数字,如果找到了就开始正则替换并解析
if l != 0 {
var mapResult map[string]interface{}
str := reg.ReplaceAllString(string(j), `id": "${1}","`)
json.Unmarshal([]byte(str), &mapResult)
data = &mapResult
}
return data
}
原因web.ServeJSON()中并未对int64处理 所以需要使用TransferData 将int转成字符串
第二种方法 自定数据类型
1:自定义数据类型
package lib
import (
"encoding/json"
"fmt"
"strconv"
"strings"
)
type BigInt struct {
Data string
}
/**
* @desc 序列号方法
*/
func (t *BigInt) MarshalJSON() ([]byte, error) {
stamp := fmt.Sprintf(""%s"", t.Data)
return []byte(stamp), nil
}
/**
* @desc 反序列化
*/
func (t *BigInt) UnmarshalJSON(data []byte) error {
t.Data = strings.ReplaceAll(string(data), """, "")
return nil
}
// String 重写String方法
func (t *BigInt) String() string {
data, _ := json.Marshal(t)
return string(data)
}
/**
* @desc 获取具体的数值
*/
func (t *BigInt) Uint64() uint64 {
value, _ := strconv.ParseUint(t.Data, 10, 64)
return value
}
2: 使用
定义结构体
/**
* @desc 用于文章列表查询分页
*/
type CommentContext struct {
ID lib.BigInt `validate:"required" json:"id"` //评论ID
Opid lib.BigInt `validate:"required" json:"opid"` //文章ID
ParentId lib.BigInt `validate:"required" json:"parentId"` //回复的父ID
Uuid string `json:"uuid"` //用户UUID
UserId uint64 `json:"userId"` //用户ID
}
在方法中使用
var ctx context.CommentContext
ctx.ParentId.Uint64()