From 656bcf7239e73cf5d81bdac17730f223c364a9ad Mon Sep 17 00:00:00 2001 From: Havoc412 <2993167370@qq.com> Date: Wed, 13 Nov 2024 19:43:26 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20finish=20half=20animal=20ES?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/http/controller/web/animal_controller.go | 13 +++- app/model/animal.go | 33 +++++---- app/model/encounter.go | 2 +- app/model_es/animal.go | 71 ++++++++++++++++++++ app/service/encounter/curd/encounter_curd.go | 7 +- 5 files changed, 101 insertions(+), 25 deletions(-) diff --git a/app/http/controller/web/animal_controller.go b/app/http/controller/web/animal_controller.go index cdfe6e8..179084a 100644 --- a/app/http/controller/web/animal_controller.go +++ b/app/http/controller/web/animal_controller.go @@ -6,6 +6,7 @@ import ( "catface/app/global/variable" "catface/app/http/validator/core/data_transfer" "catface/app/model" + "catface/app/model_es" "catface/app/service/animals/curd" "catface/app/service/upload_file" "catface/app/utils/query_handler" @@ -190,6 +191,7 @@ func (a *Animals) Create(context *gin.Context) { 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_list", nickNames) context.Set(consts.ValidatorPrefix+"nick_names", nickNames) context.Set(consts.ValidatorPrefix+"tags", tags) // UPDATE 有点冗余,但是不用复杂代码; } @@ -213,16 +215,21 @@ func (a *Animals) Create(context *gin.Context) { return } // STAGE-3 - if anm_id, ok := model.CreateAnimalFactory("").InsertDate(context); ok { + if animal, ok := model.CreateAnimalFactory("").InsertDate(context); ok { // 转移 photos 到 anm;采用 rename dir 的方式 oldName := filepath.Join(variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsPhotos", "hum_"+userId) - newName := filepath.Join(variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsPhotos", "anm_"+strconv.FormatInt(anm_id, 10)) + newName := filepath.Join(variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath"), "catsPhotos", "anm_"+strconv.FormatInt(animal.Id, 10)) err := os.Rename(oldName, newName) if err != nil { // TODO 特殊返回,成功了一半?或者需要清空原有的操作?不过感觉这一步几乎不会出错。 + // TODO 或许直接采用 go 会比较好呢? } + + // 2. 将部分数据插入 ES; + go model_es.CreateAnimalESFactory(&animal).InsertDocument() + response.Success(context, consts.CurdStatusOkMsg, gin.H{ - "anm_id": anm_id, + "anm_id": animal.Id, }) } else { response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg+",新增错误", "") diff --git a/app/model/animal.go b/app/model/animal.go index 114878f..0e0860b 100644 --- a/app/model/animal.go +++ b/app/model/animal.go @@ -15,18 +15,19 @@ func CreateAnimalFactory(sqlType string) *Animal { type Animal struct { // UPDATE 或者这里都应该采取外键连接? - BaseModel // 假设 BaseModel 中不需要添加 omitempty 标签 - Name string `gorm:"type:varchar(20)" json:"name,omitempty"` // 名称 - Birthday string `gorm:"size:10" json:"birthday,omitempty"` // 生日;就简单存string就好 - Gender uint8 `gorm:"default:1" json:"gender,omitempty"` // 性别 - Breed uint8 `gorm:"default:1" json:"breed,omitempty"` // 品种 - Sterilization uint8 `gorm:"default:1" json:"sterilization,omitempty"` // 1 不明 2 未绝育 3 已绝育 - Vaccination uint8 `gorm:"default:1" json:"vaccination,omitempty"` // 免疫状态 - Deworming uint8 `gorm:"default:1" json:"deworming,omitempty"` // 驱虫状态 - NickNames string `gorm:"type:varchar(31)" json:"nick_names,omitempty"` // 别称,辅助查询;存储上采取 , 间隔符的方式; VARCHAR 会比较合适 - Status uint8 `gorm:"default:1" json:"status,omitempty"` // 状态 - Description string `gorm:"column:description;type:varchar(255)" json:"description,omitempty"` // 简明介绍 - Tags string `json:"tags,omitempty"` + BaseModel // 假设 BaseModel 中不需要添加 omitempty 标签 + Name string `gorm:"type:varchar(20)" json:"name,omitempty"` // 名称 + Birthday string `gorm:"size:10" json:"birthday,omitempty"` // 生日;就简单存string就好 + Gender uint8 `gorm:"default:1" json:"gender,omitempty"` // 性别 + Breed uint8 `gorm:"default:1" json:"breed,omitempty"` // 品种 + Sterilization uint8 `gorm:"default:1" json:"sterilization,omitempty"` // 1 不明 2 未绝育 3 已绝育 + Vaccination uint8 `gorm:"default:1" json:"vaccination,omitempty"` // 免疫状态 + Deworming uint8 `gorm:"default:1" json:"deworming,omitempty"` // 驱虫状态 + NickNames string `gorm:"type:varchar(31)" json:"nick_names,omitempty"` // 别称,辅助查询;存储上采取 , 间隔符的方式; VARCHAR 会比较合适 + NickNamesList []string `gorm:"-" json:"nick_names_list,omitempty"` + Status uint8 `gorm:"default:1" json:"status,omitempty"` // 状态 + Description string `gorm:"column:description;type:varchar(255)" json:"description,omitempty"` // 简明介绍 + Tags string `json:"tags,omitempty"` // TAG imaegs Avatar string `gorm:"type:varchar(50)" json:"avatar,omitempty"` // 缩略图 url,为 Go 获取 Photo 之后压缩处理后的图像,单独存储。 AvatarHeight uint16 `json:"avatar_height,omitempty"` // 为了方便前端在加载图像前的骨架图 & 瀑布流展示。 // INFO 暂时没用到 @@ -119,18 +120,16 @@ func (a *Animal) ShowByName(name string, attrs ...string) (temp []Animal) { return } -func (a *Animal) InsertDate(c *gin.Context) (int64, bool) { - var tmp Animal +func (a *Animal) InsertDate(c *gin.Context) (tmp Animal, ok bool) { if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil { if res := a.Create(&tmp); res.Error == nil { // 获取插入的 ID - insertedID := tmp.Id - return insertedID, true + return tmp, true } else { variable.ZapLog.Error("Animal 数据新增出错", zap.Error(res.Error)) } } else { variable.ZapLog.Error("Animal 数据绑定出错", zap.Error(err)) } - return 0, false + return tmp, false } diff --git a/app/model/encounter.go b/app/model/encounter.go index d95919c..b1e5ce4 100644 --- a/app/model/encounter.go +++ b/app/model/encounter.go @@ -33,7 +33,7 @@ type Encounter struct { // Encounter 或者称为 post,指的就是 Human 单 AvatarHeight uint16 `json:"avatar_height,omitempty"` // 为了方便前端在加载图像前的骨架图 & 瀑布流展示。 AvatarWidth uint16 `json:"avatar_width,omitempty"` Photos string `gorm:"type:varchar(100)" json:"photos,omitempty"` // 图片数组 - PhotosSlice []string `gorm:"-" json:"photos_list,omitempty"` // TIP GORM 忽略 + PhotosList []string `gorm:"-" json:"photos_list,omitempty"` // TIP GORM 忽略 // POI Latitude float64 `json:"latitude,omitempty"` // POI 位置相关 Longitude float64 `json:"longitude,omitempty"` diff --git a/app/model_es/animal.go b/app/model_es/animal.go index d37a815..14b1dbf 100644 --- a/app/model_es/animal.go +++ b/app/model_es/animal.go @@ -1 +1,72 @@ package model_es + +import ( + "bytes" + "catface/app/global/variable" + "catface/app/model" + "context" + "encoding/json" + "fmt" + + "github.com/elastic/go-elasticsearch/v8/esapi" +) + +func CreateAnimalESFactory(animal *model.Animal) *Animal { + if animal == nil { + return &Animal{} + } + return &Animal{ + Id: animal.Id, + Name: animal.Name, + NickNames: animal.NickNamesList, + Description: animal.Description, + } +} + +type Animal struct { + Id int64 `json:"id"` + Name string `json:"name"` + NickNames []string `json:"nick_names"` + Description string `json:"description"` +} + +func (a *Animal) IndexName() string { + return "catface_animals" +} + +func (a *Animal) InsertDocument() error { + ctx := context.Background() + + data, err := json.Marshal(a) + if err != nil { + return err + } + + req := esapi.IndexRequest{ + Index: a.IndexName(), + // DocumentID: fmt.Sprintf("%d", a.Id), + Body: bytes.NewReader(data), + Refresh: "true", + } + + res, err := req.Do(ctx, variable.ElasticClient) + if err != nil { + return err + } + defer res.Body.Close() + + if res.IsError() { + var e map[string]interface{} + if err := json.NewDecoder(res.Body).Decode(&e); err != nil { + return fmt.Errorf("error parsing the response body: %s", err) + } else { + return fmt.Errorf("[%s] %s: %s", + res.Status(), + e["error"].(map[string]interface{})["type"], + e["error"].(map[string]interface{})["reason"], + ) + } + } + + return nil +} diff --git a/app/service/encounter/curd/encounter_curd.go b/app/service/encounter/curd/encounter_curd.go index 2825ef7..e09ad0f 100644 --- a/app/service/encounter/curd/encounter_curd.go +++ b/app/service/encounter/curd/encounter_curd.go @@ -4,7 +4,6 @@ import ( "catface/app/model" "catface/app/utils/query_handler" "strconv" - ) func CreateEncounterCurdFactory() *EncounterCurd { @@ -22,8 +21,8 @@ func (e *EncounterCurd) List(num, skip, user_id int, mode string) (result []mode var likedAnimalIds []int switch mode { - case "liked": - likedAnimalIds = model.CreateAnimalLikeFactory("").LikedCats(user_id) + case "liked": + likedAnimalIds = model.CreateAnimalLikeFactory("").LikedCats(user_id) } result = model.CreateEncounterFactory("").Show(num, skip, user_id, likedAnimalIds) return @@ -43,7 +42,7 @@ func (e *EncounterCurd) Detail(id string) *model.EncounterDetail { } // 1.1 处理 Photos 为 []string,同时忽略原本的 Photos 字段。 - encounter.PhotosSlice = query_handler.StringToStringArray(encounter.Photos) + encounter.PhotosList = query_handler.StringToStringArray(encounter.Photos) encounter.Photos = "" // 清空。 // 2. user data