From 121c7281fa671c6c2f1dff4031df0b24ab244af2 Mon Sep 17 00:00:00 2001 From: Havoc412 <2993167370@qq.com> Date: Wed, 30 Oct 2024 17:21:09 +0800 Subject: [PATCH] finish Add animal API #1 --- app/http/controller/web/animal_controller.go | 86 +++++++++++++++++++- app/http/validator/web/animal/create.go | 15 ++-- app/model/animal.go | 24 +++++- main.go | 1 + 4 files changed, 113 insertions(+), 13 deletions(-) diff --git a/app/http/controller/web/animal_controller.go b/app/http/controller/web/animal_controller.go index 0af0d0e..316b8cc 100644 --- a/app/http/controller/web/animal_controller.go +++ b/app/http/controller/web/animal_controller.go @@ -3,8 +3,15 @@ package web import ( "catface/app/global/consts" "catface/app/global/errcode" + "catface/app/global/variable" + "catface/app/http/validator/core/data_transfer" + "catface/app/model" "catface/app/service/animals/curd" + "catface/app/service/upload_file" "catface/app/utils/response" + "os" + "path/filepath" + "strconv" "github.com/gin-gonic/gin" ) @@ -57,7 +64,82 @@ func (a *Animals) Detail(context *gin.Context) { } } func (a *Animals) Create(context *gin.Context) { + userId := strconv.Itoa(int(context.GetFloat64(consts.ValidatorPrefix + "user_id"))) + // STAGE-1 Get Params + photos := data_transfer.GetStringSlice(context, "photos") + if len(photos) > 0 { + avatar := photos[0] + avatarWidth := variable.ConfigYml.GetFloat64("FileUploadSetting.AvatarWidth") + + srcPath := filepath.Join(variable.BasePath, variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsPhotos", "hum_"+userId, avatar) + dstPath := filepath.Join(variable.BasePath, variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsAvatar", avatar) + avatarHeight, err := upload_file.ResizeImage(srcPath, dstPath, int(avatarWidth)) + if err != nil { + response.Fail(context, consts.FilesUploadFailCode, consts.FilesUploadFailMsg, "") + return + } + context.Set(consts.ValidatorPrefix+"avatar", avatar) + context.Set(consts.ValidatorPrefix+"avatar_height", float64(avatarHeight)) + context.Set(consts.ValidatorPrefix+"avatar_width", float64(avatarWidth)) + } poi := context.GetStringMap(consts.ValidatorPrefix + "poi") - // TODO 感觉这里就是获取信息之后,然后解析后再存储,方便后续 Model 直接绑定到数据。 - _ = poi + if poi != nil { + // 感觉这里就是获取信息之后,然后解析后再存储,方便后续 Model 直接绑定到数据。 + latitude := poi["latitude"].(float64) + longitude := poi["longitude"].(float64) + context.Set(consts.ValidatorPrefix+"latitude", latitude) + context.Set(consts.ValidatorPrefix+"longitude", longitude) + } + health := context.GetStringMap(consts.ValidatorPrefix + "health") + if health != nil { + sterilization := health["sterilization"].(float64) + vaccination := health["vaccination"].(float64) + deworming := health["deworming"].(float64) + context.Set(consts.ValidatorPrefix+"sterilization", uint8(sterilization)) + context.Set(consts.ValidatorPrefix+"vaccination", uint8(vaccination)) + context.Set(consts.ValidatorPrefix+"deworming", uint8(deworming)) + } + extra := context.GetStringMap(consts.ValidatorPrefix + "extra") + var nickNames []string + var tags []string + if extra != nil { + context.Set(consts.ValidatorPrefix+"nick_names", extra["nick_names"]) + context.Set(consts.ValidatorPrefix+"tags", extra["tags"]) + nickNames = data_transfer.GetStringSlice(context, "nick_names") + tags = data_transfer.GetStringSlice(context, "tags") + context.Set(consts.ValidatorPrefix+"nick_names", nickNames) + context.Set(consts.ValidatorPrefix+"tags", tags) // UPDATE 有点冗余,但是不用复杂代码; + } + // STAGE-2 + if res, err := data_transfer.ConvertSliceToString(photos); err == nil { + context.Set(consts.ValidatorPrefix+"photos", res) + } else { + response.Fail(context, consts.ValidatorParamsCheckFailCode, consts.ValidatorParamsCheckFailMsg, "") + return + } + if res, err := data_transfer.ConvertSliceToString(nickNames); err == nil { + context.Set(consts.ValidatorPrefix+"nick_names", res) + } else { + response.Fail(context, consts.ValidatorParamsCheckFailCode, consts.ValidatorParamsCheckFailMsg, "") + return + } + if res, err := data_transfer.ConvertSliceToString(tags); err == nil { + context.Set(consts.ValidatorPrefix+"tags", res) + } else { + response.Fail(context, consts.ValidatorParamsCheckFailCode, consts.ValidatorParamsCheckFailMsg, "") + return + } + // STAGE-3 + if anm_id, ok := model.CreateAnimalFactory("").InsertDate(context); ok { + // 转移 photos 到 anm;采用 rename dir 的方式 + oldName := filepath.Join(variable.BasePath, variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsPhotos", "hum_"+userId) + newName := filepath.Join(variable.BasePath, variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsPhotos", "anm_"+strconv.FormatInt(anm_id, 10)) + err := os.Rename(oldName, newName) + if err != nil { + // TODO 特殊返回,成功了一半?或者需要清空原有的操作?不过感觉这一步几乎不会出错。 + } + response.Success(context, consts.CurdStatusOkMsg, "") + } else { + response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg+",新增错误", "") + } } diff --git a/app/http/validator/web/animal/create.go b/app/http/validator/web/animal/create.go index 32a59ac..37d7fdb 100644 --- a/app/http/validator/web/animal/create.go +++ b/app/http/validator/web/animal/create.go @@ -6,7 +6,6 @@ import ( "catface/app/http/validator/common/location" "catface/app/http/validator/core/data_transfer" "catface/app/utils/response" - "time" "github.com/gin-gonic/gin" ) @@ -23,13 +22,13 @@ type Health struct { } type Create struct { - Name string `form:"name" json:"name" binding:"required"` - Breed uint8 `form:"breed" json:"breed" binding:"required"` - Gender uint8 `form:"gender" json:"gender" binding:"required"` - Status uint8 `form:"status" json:"status" binding:"required"` - Description string `form:"description" json:"description"` - Birthday *time.Time `form:"birthday" json:"birthday" binding:"required"` // TODO 如何定义不明? - Photos []string `form:"photos" json:"photos"` + Name string `form:"name" json:"name" binding:"required"` + Breed uint8 `form:"breed" json:"breed" binding:"required"` + Gender uint8 `form:"gender" json:"gender" binding:"required"` + Status uint8 `form:"status" json:"status" binding:"required"` + Description string `form:"description" json:"description"` + Birthday string `form:"birthday" json:"birthday"` + Photos []string `form:"photos" json:"photos"` Health Health `form:"health" json:"health"` UserId int `form:"user_id" json:"user_id" binding:"required,numeric"` diff --git a/app/model/animal.go b/app/model/animal.go index 31e5248..f99879a 100644 --- a/app/model/animal.go +++ b/app/model/animal.go @@ -2,8 +2,10 @@ package model import ( "catface/app/global/variable" + "catface/app/utils/data_bind" "catface/app/utils/gorm_v2" + "github.com/gin-gonic/gin" "go.uber.org/zap" ) @@ -14,7 +16,7 @@ func CreateAnimalFactory(sqlType string) *Animal { type Animal struct { BaseModel // 假设 BaseModel 中不需要添加 omitempty 标签 Name string `gorm:"type:varchar(20)" json:"name,omitempty"` // 名称 - Birthday string `json:"birthday,omitempty"` // 生日 + Birthday string `gorm:"size:10" json:"birthday,omitempty"` // 生日;就简单存string就好 Gender uint8 `json:"gender,omitempty"` // 性别 Breed uint8 `json:"breed,omitempty"` // 品种 Sterilization uint8 `json:"sterilization,omitempty"` // 1 不明 2 未绝育 3 已绝育 @@ -25,10 +27,10 @@ type Animal struct { Description string `gorm:"column:description;type:varchar(255)" json:"description,omitempty"` // 简明介绍 Tags string `json:"tags,omitempty"` // TAG imaegs - Avatar string `gorm:"type:varchar(10)" json:"avatar,omitempty"` // 缩略图 url,为 Go 获取 Photo 之后压缩处理后的图像,单独存储。 + Avatar string `gorm:"type:varchar(50)" json:"avatar,omitempty"` // 缩略图 url,为 Go 获取 Photo 之后压缩处理后的图像,单独存储。 AvatarHeight uint16 `json:"avatar_height,omitempty"` // 为了方便前端在加载图像前的骨架图 & 瀑布流展示。 // INFO 暂时没用到 AvatarWidth uint16 `json:"avatar_width,omitempty"` // 为了方便前端在加载图像前的骨架图 & 瀑布流展示。 - HeadImg string `gorm:"type:varchar(10)" json:"head_img,omitempty"` // Head 默认处理为正方形。 + HeadImg string `gorm:"type:varchar(50)" json:"head_img,omitempty"` // Head 默认处理为正方形。 Photos string `gorm:"type:varchar(255)" json:"photos,omitempty"` // 图片数组 // TAG POI Latitude float64 `json:"latitude,omitempty"` // POI 位置相关 @@ -89,3 +91,19 @@ func (a *Animal) ShowByIDs(ids []int64, attrs ...string) (temp []Animal) { } return } + +func (a *Animal) InsertDate(c *gin.Context) (int64, bool) { + var tmp Animal + if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil { + if res := a.Create(&tmp); res.Error == nil { + // 获取插入的 ID + insertedID := tmp.Id + return insertedID, true + } else { + variable.ZapLog.Error("Animal 数据新增出错", zap.Error(res.Error)) + } + } else { + variable.ZapLog.Error("Animal 数据绑定出错", zap.Error(err)) + } + return 0, false +} diff --git a/main.go b/main.go index b0899c0..31fc9be 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "catface/app/global/variable" _ "catface/bootstrap" "catface/routers" + ) // 这里可以存放后端路由(例如后台管理系统)