From 86c11fc31d97ad5e15414da6d0d9547d45645933 Mon Sep 17 00:00:00 2001 From: Havoc412 <2993167370@qq.com> Date: Fri, 18 Oct 2024 10:04:01 +0800 Subject: [PATCH] add mew curd wat by GORM --- .../controller/web/encounter_controller.go | 20 ++--- app/model/encounter.go | 22 ++++++ app/service/encounter/curd/encounter_curd.go | 5 -- app/utils/data_bind/formdata_to_model.go | 78 +++++++++++++++++++ 4 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 app/utils/data_bind/formdata_to_model.go diff --git a/app/http/controller/web/encounter_controller.go b/app/http/controller/web/encounter_controller.go index a3e583f..6be5e2d 100644 --- a/app/http/controller/web/encounter_controller.go +++ b/app/http/controller/web/encounter_controller.go @@ -2,7 +2,7 @@ package web import ( "catface/app/global/consts" - "catface/app/service/encounter/curd" + "catface/app/model" "catface/app/utils/response" "github.com/gin-gonic/gin" @@ -11,19 +11,13 @@ import ( type Encounters struct { } -func (e *Encounters) Store(context *gin.Context) { - userId := context.GetFloat64(consts.ValidatorPrefix + "user_id") - animalsID := context.GetString(consts.ValidatorPrefix + "animals_id") - title := context.GetString(consts.ValidatorPrefix + "title") - context := context.GetString(consts.ValidatorPrefix + "content") - photos := context.GetString(consts.ValidatorPrefix + "photos") - laitude := context.GetFloat64(consts.ValidatorPrefix + "latitude") - longitude := context.GetFloat64(consts.ValidatorPrefix + "longitude") +func (e *Encounters) Create(context *gin.Context) { + // TODO 处理 Photos 文件,然后处理出 Avatar,并获取压缩后的 宽高,以及文件的存储路径。 - encounters := curd.CreateEncounterCurdFactory().Create() - if encounters == nil { - response.Success(context, consts.CurdStatusOkMsg, encounters) + // Real Insert + if model.CreateEncounterFactory("").InsertDate(context) { + response.Success(context, consts.CurdStatusOkMsg, "") } else { - response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg, "") + response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg+",新增错误", "") } } diff --git a/app/model/encounter.go b/app/model/encounter.go index 3c50351..5b4a6fb 100644 --- a/app/model/encounter.go +++ b/app/model/encounter.go @@ -1,5 +1,13 @@ package model +import ( + "catface/app/global/variable" + "catface/app/utils/data_bind" + + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + func CreateEncounterFactory(sqlType string) *Encounter { return &Encounter{BaseModel: BaseModel{DB: UseDbConn(sqlType)}} } @@ -29,3 +37,17 @@ type Encounter struct { // Encounter 或者称为 post,指的就是 Human 单 func (e *Encounter) TableName() string { return "encounters" } + +func (e *Encounter) InsertDate(c *gin.Context) bool { + var tmp Encounter + if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil { + if res := e.Create(&tmp); res.Error == nil { + return true + } else { + variable.ZapLog.Error("Encounter 数据新增出错", zap.Error(res.Error)) + } + } else { + variable.ZapLog.Error("Encounter 数据绑定出错", zap.Error(err)) + } + return false +} diff --git a/app/service/encounter/curd/encounter_curd.go b/app/service/encounter/curd/encounter_curd.go index a6ce2f7..c87bd00 100644 --- a/app/service/encounter/curd/encounter_curd.go +++ b/app/service/encounter/curd/encounter_curd.go @@ -9,8 +9,3 @@ func CreateEncounterCurdFactory() *EncounterCurd { type EncounterCurd struct { encounter *model.Encounter } - -func (e *EncounterCurd) Store(encounter *model.Encounter) bool { - - return model.CreateEncounterFactory() -} diff --git a/app/utils/data_bind/formdata_to_model.go b/app/utils/data_bind/formdata_to_model.go new file mode 100644 index 0000000..8d925af --- /dev/null +++ b/app/utils/data_bind/formdata_to_model.go @@ -0,0 +1,78 @@ +package data_bind + +import ( + "catface/app/global/consts" + "errors" + "reflect" + + "github.com/gin-gonic/gin" +) + +const ( + modelStructMustPtr = "modelStruct 必须传递一个指针" +) + +// 绑定form表单验证器已经验证完成的参数到 model 结构体, +// mode 结构体支持匿名嵌套 +// 数据绑定原则: +// 1.表单参数验证器中的结构体字段 json 标签必须和 model 结构体定义的 json 标签一致 +// 2.model 中的数据类型与表单参数验证器数据类型保持一致: +// 例如:model 中的 user_name 是 string 那么表单参数验证器中的 user_name 也必须是 string,bool 类型同理,日期时间字段在 ginskeleton 中请按照 string 处理 +// 3.但是 model 中的字段如果是数字类型(int、int8、int16、int64、float32、float64等)都可以绑定表单参数验证中的 float64 类型,程序会自动将原始的 float64 转换为 model 的定义的数字类型 + +func ShouldBindFormDataToModel(c *gin.Context, modelStruct interface{}) error { + mTypeOf := reflect.TypeOf(modelStruct) + if mTypeOf.Kind() != reflect.Ptr { + return errors.New(modelStructMustPtr) + } + mValueOf := reflect.ValueOf(modelStruct) + + //分析 modelStruct 字段 + mValueOfEle := mValueOf.Elem() + mtf := mValueOf.Elem().Type() + fieldNum := mtf.NumField() + for i := 0; i < fieldNum; i++ { + if !mtf.Field(i).Anonymous && mtf.Field(i).Type.Kind() != reflect.Struct { + fieldSetValue(c, mValueOfEle, mtf, i) + } else if mtf.Field(i).Type.Kind() == reflect.Struct { + //处理结构体(有名+匿名) + mValueOfEle.Field(i).Set(analysisAnonymousStruct(c, mValueOfEle.Field(i))) + } + } + return nil +} + +// 分析匿名结构体,并且获取匿名结构体的值 +func analysisAnonymousStruct(c *gin.Context, value reflect.Value) reflect.Value { + + typeOf := value.Type() + fieldNum := typeOf.NumField() + newStruct := reflect.New(typeOf) + newStructElem := newStruct.Elem() + for i := 0; i < fieldNum; i++ { + fieldSetValue(c, newStructElem, typeOf, i) + } + return newStructElem +} + +// 为结构体字段赋值 +func fieldSetValue(c *gin.Context, valueOf reflect.Value, typeOf reflect.Type, colIndex int) { + relaKey := typeOf.Field(colIndex).Tag.Get("json") + if relaKey != "-" { + relaKey = consts.ValidatorPrefix + typeOf.Field(colIndex).Tag.Get("json") + switch typeOf.Field(colIndex).Type.Kind() { + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + valueOf.Field(colIndex).SetInt(int64(c.GetFloat64(relaKey))) + case reflect.Float32, reflect.Float64: + valueOf.Field(colIndex).SetFloat(c.GetFloat64(relaKey)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + valueOf.Field(colIndex).SetUint(uint64(c.GetFloat64(relaKey))) + case reflect.String: + valueOf.Field(colIndex).SetString(c.GetString(relaKey)) + case reflect.Bool: + valueOf.Field(colIndex).SetBool(c.GetBool(relaKey)) + default: + // model 如果有日期时间字段,请统一设置为字符串即可 + } + } +}