🎨 better model code
This commit is contained in:
parent
eaf4bb4ad8
commit
9b24a1f645
@ -2,8 +2,10 @@ package errcode
|
||||
|
||||
const (
|
||||
ErrAnimalSqlFind = iota + ErrAnimal
|
||||
AnimalNoFind
|
||||
)
|
||||
|
||||
func AnimalMsgInit(m msg) {
|
||||
m[ErrAnimalSqlFind] = "Animals 表单查询失败"
|
||||
m[AnimalNoFind] = "Animals 没有查询到符合条件的目标"
|
||||
}
|
||||
|
@ -3,122 +3,56 @@ package web
|
||||
import (
|
||||
"catface/app/global/consts"
|
||||
"catface/app/global/errcode"
|
||||
"catface/app/global/variable"
|
||||
"catface/app/model"
|
||||
"catface/app/utils/model_handler"
|
||||
"catface/app/utils/query_handler"
|
||||
"catface/app/service/animals/curd"
|
||||
"catface/app/utils/response"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Animals struct { // INFO 起到一个标记的作用,这样 web.xxx 的时候不同模块就不会命名冲突了。
|
||||
}
|
||||
|
||||
func buildSelectAttrs(db *gorm.DB, attrs string) *gorm.DB {
|
||||
if len(attrs) > 0 {
|
||||
// 1. 获取空 Field
|
||||
fieldMap := model_handler.GetModelField(model.Animal{})
|
||||
|
||||
// 2. 开始检查请求字段
|
||||
attrsArray := query_handler.StringToStringArray(attrs)
|
||||
for _, attr := range attrsArray {
|
||||
if attr == "*" { // 不需要过滤,直接返回
|
||||
return db
|
||||
} else if attr == "avatar" {
|
||||
fieldMap["avatar_height"] = true
|
||||
fieldMap["avatar_width"] = true
|
||||
}
|
||||
// 过滤 无效 的请求字段
|
||||
if _, ok := fieldMap[attr]; ok {
|
||||
fieldMap[attr] = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 装填字段,并 Select
|
||||
var validSelectedFields []string
|
||||
for key, value := range fieldMap {
|
||||
if value {
|
||||
validSelectedFields = append(validSelectedFields, key)
|
||||
}
|
||||
}
|
||||
db = db.Select(validSelectedFields)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 通过检查字段的方式构建 Where 函数。
|
||||
* @param {*gorm.DB} db
|
||||
* @param {map[string][]uint8} conditions
|
||||
* @return {*}
|
||||
*/
|
||||
func buildQuery(db *gorm.DB, conditions map[string][]uint8) *gorm.DB {
|
||||
for field, values := range conditions {
|
||||
if len(values) == 0 || len(values) == 1 && values[0] == 0 {
|
||||
continue
|
||||
}
|
||||
db = db.Where(field+" in (?)", values)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func (a *Animals) List(context *gin.Context) {
|
||||
// 1. Get Params
|
||||
attrs := context.GetString(consts.ValidatorPrefix + "attrs")
|
||||
gender := query_handler.StringToUint8Array(context.GetString(consts.ValidatorPrefix + "gender"))
|
||||
breed := query_handler.StringToUint8Array(context.GetString(consts.ValidatorPrefix + "breed"))
|
||||
sterilzation := query_handler.StringToUint8Array(context.GetString(consts.ValidatorPrefix + "sterilzation"))
|
||||
status := query_handler.StringToUint8Array(context.GetString(consts.ValidatorPrefix + "status"))
|
||||
gender := context.GetString(consts.ValidatorPrefix + "gender")
|
||||
breed := context.GetString(consts.ValidatorPrefix + "breed")
|
||||
sterilzation := context.GetString(consts.ValidatorPrefix + "sterilzation")
|
||||
status := context.GetString(consts.ValidatorPrefix + "status")
|
||||
num := context.GetFloat64(consts.ValidatorPrefix + "num")
|
||||
skip := context.GetFloat64(consts.ValidatorPrefix + "skip")
|
||||
|
||||
// 创建条件映射
|
||||
conditions := map[string][]uint8{
|
||||
"gender": gender,
|
||||
"breed": breed,
|
||||
"sterilization": sterilzation,
|
||||
"status": status,
|
||||
}
|
||||
|
||||
// 2. Select & Filter
|
||||
if num == 0 {
|
||||
num = 10
|
||||
}
|
||||
db := variable.GormDbMysql.Table("animals").Limit(int(num)).Offset(int(skip))
|
||||
db = buildSelectAttrs(db, attrs)
|
||||
db = buildQuery(db, conditions)
|
||||
|
||||
// 3. Find
|
||||
var animals []model.Animal
|
||||
err := db.Find(&animals).Error
|
||||
if err != nil {
|
||||
response.Fail(context, errcode.ErrAnimalSqlFind, errcode.ErrMsg[errcode.ErrAnimalSqlFind], err) // UPDATE consts ?
|
||||
} else {
|
||||
animals := curd.CreateUserCurdFactory().List(attrs, gender, breed, sterilzation, status, int(num), int(skip))
|
||||
if animals != nil {
|
||||
response.Success(context, consts.CurdStatusOkMsg, animals)
|
||||
} else {
|
||||
response.Fail(context, errcode.AnimalNoFind, errcode.ErrMsg[errcode.AnimalNoFind], "")
|
||||
}
|
||||
}
|
||||
|
||||
// v1
|
||||
// func (a *Animals) Detail(context *gin.Context) {
|
||||
// // 1. Get Params
|
||||
// anmId, err := strconv.Atoi(context.Param("anm_id"))
|
||||
|
||||
// // 2. Select & Filter
|
||||
// var animal model.Animal
|
||||
// err = variable.GormDbMysql.Table("animals").Model(&animal).Where("id = ?", anmId).Scan(&animal).Error // TIP GORM.First 采取默认的
|
||||
// if err != nil {
|
||||
// response.Fail(context, errcode.ErrAnimalSqlFind, errcode.ErrMsg[errcode.ErrAnimalSqlFind], err) // UPDATE consts ?
|
||||
// } else {
|
||||
// response.Success(context, consts.CurdStatusOkMsg, animal)
|
||||
// }
|
||||
// }
|
||||
|
||||
func (a *Animals) Detail(context *gin.Context) {
|
||||
// 1. Get Params
|
||||
anmId, err := strconv.Atoi(context.Param("anm_id"))
|
||||
if err != nil {
|
||||
response.Fail(context, errcode.ErrAnimalSqlFind, errcode.ErrMsg[errcode.ErrAnimalSqlFind], err)
|
||||
return
|
||||
}
|
||||
fmt.Println("anmId:", anmId)
|
||||
anmId := context.Param("anm_id")
|
||||
|
||||
// 2. Select & Filter
|
||||
var animal model.Animal
|
||||
err = variable.GormDbMysql.Table("animals").Model(&animal).Where("id = ?", anmId).Scan(&animal).Error // TIP GORM.First 采取默认的
|
||||
if err != nil {
|
||||
response.Fail(context, errcode.ErrAnimalSqlFind, errcode.ErrMsg[errcode.ErrAnimalSqlFind], err) // UPDATE consts ?
|
||||
} else {
|
||||
animal := curd.CreateUserCurdFactory().Detail(anmId)
|
||||
if animal != nil {
|
||||
response.Success(context, consts.CurdStatusOkMsg, animal)
|
||||
} else {
|
||||
response.Fail(context, errcode.AnimalNoFind, errcode.ErrMsg[errcode.AnimalNoFind], "")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,16 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"catface/app/global/variable"
|
||||
"catface/app/utils/gorm_v2"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func CreateAnimalFactory(sqlType string) *Animal {
|
||||
return &Animal{BaseModel: BaseModel{DB: UseDbConn(sqlType)}}
|
||||
}
|
||||
|
||||
type Animal struct {
|
||||
BaseModel // 假设 BaseModel 中不需要添加 omitempty 标签
|
||||
Name string `gorm:"type:varchar(20)" json:"name,omitempty"` // 名称
|
||||
@ -21,37 +32,35 @@ type Animal struct {
|
||||
Tags string `json:"tags,omitempty"` // 活动半径
|
||||
}
|
||||
|
||||
type Breed struct {
|
||||
BriefModel
|
||||
func (a *Animal) TableName() string {
|
||||
return "animals"
|
||||
}
|
||||
|
||||
type Sterilzation struct { // TEST How to use BriefModel, the dif between Common
|
||||
Id int64 `json:"id"`
|
||||
NameZh string `json:"name_zh"`
|
||||
NameEn string `json:"name_en"`
|
||||
func (a *Animal) Show(attrs []string, gender []uint8, breed []uint8, sterilzation []uint8, status []uint8, num int, skip int) (temp []Animal) {
|
||||
db := a.DB.Table(a.TableName()).Limit(int(num)).Offset(int(skip)).Select(attrs)
|
||||
|
||||
// 创建条件映射
|
||||
conditions := map[string][]uint8{
|
||||
"gender": gender,
|
||||
"breed": breed,
|
||||
"sterilization": sterilzation,
|
||||
"status": status,
|
||||
}
|
||||
|
||||
type AnmStatus struct {
|
||||
BriefModel
|
||||
db = gorm_v2.BuildWhere(db, conditions)
|
||||
|
||||
err := db.Find(&temp).Error
|
||||
if err != nil {
|
||||
variable.ZapLog.Error("Animal Show Error", zap.Error(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type AnmGender struct {
|
||||
BriefModel
|
||||
func (a *Animal) ShowByID(id int) *Animal {
|
||||
var temp Animal
|
||||
err := a.DB.Table(a.TableName()).Model(&temp).Where("id = ?", id).Scan(&temp).Error
|
||||
if err != nil {
|
||||
variable.ZapLog.Error("Animal ShowByID Error", zap.Error(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 保留 Top 3, 辅助 catface - breed 子模型判断; 单独建表,因为只会被 CatFace 模块使用。
|
||||
* @return {*}
|
||||
*/
|
||||
type AnmFaceBreed struct { // TODO 迁移 python 的时候再考虑一下细节
|
||||
BriefModel
|
||||
Top1 uint8
|
||||
Prob1 float64
|
||||
Top2 uint8
|
||||
Prob2 float64
|
||||
Top3 uint8
|
||||
Prob3 float64
|
||||
|
||||
AnimalId int64 // INFO 外键设定?
|
||||
Animal Animal
|
||||
return &temp
|
||||
}
|
||||
|
21
app/model/animal_com.go
Normal file
21
app/model/animal_com.go
Normal file
@ -0,0 +1,21 @@
|
||||
package model
|
||||
|
||||
// INFO 一些基础表单的整合
|
||||
|
||||
type Breed struct {
|
||||
BriefModel
|
||||
}
|
||||
|
||||
type Sterilzation struct { // TEST How to use BriefModel, the dif between Common
|
||||
Id int64 `json:"id"`
|
||||
NameZh string `json:"name_zh"`
|
||||
NameEn string `json:"name_en"`
|
||||
}
|
||||
|
||||
type AnmStatus struct {
|
||||
BriefModel
|
||||
}
|
||||
|
||||
type AnmGender struct {
|
||||
BriefModel
|
||||
}
|
18
app/model/animal_face_breed.go
Normal file
18
app/model/animal_face_breed.go
Normal file
@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
/**
|
||||
* @description: 保留 Top 3, 辅助 catface - breed 子模型判断; 单独建表,因为只会被 CatFace 模块使用。
|
||||
* @return {*}
|
||||
*/
|
||||
type AnmFaceBreed struct { // TODO 迁移 python 的时候再考虑一下细节
|
||||
BriefModel
|
||||
Top1 uint8
|
||||
Prob1 float64
|
||||
Top2 uint8
|
||||
Prob2 float64
|
||||
Top3 uint8
|
||||
Prob3 float64
|
||||
|
||||
AnimalId int64 // INFO 外键设定?
|
||||
Animal Animal
|
||||
}
|
6
app/model/encounter.go
Normal file
6
app/model/encounter.go
Normal file
@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
type post struct { // Encounter 或者称为 post,指的就是 Human 单次的记录。
|
||||
BaseModel
|
||||
UserID int
|
||||
}
|
@ -17,7 +17,7 @@ import (
|
||||
// 参数说明: 传递空值,默认使用 配置文件选项:UseDbType(mysql)
|
||||
|
||||
func CreateUserFactory(sqlType string) *UsersModel {
|
||||
return &UsersModel{BaseModel: BaseModel{DB: UseDbConn(sqlType)}}
|
||||
return &UsersModel{BaseModel: BaseModel{DB: UseDbConn(sqlType)}} // INFO 这里补充 DB 的指针
|
||||
}
|
||||
|
||||
type UsersModel struct {
|
||||
|
74
app/service/animals/curd/animals_curd.go
Normal file
74
app/service/animals/curd/animals_curd.go
Normal file
@ -0,0 +1,74 @@
|
||||
package curd
|
||||
|
||||
import (
|
||||
"catface/app/model"
|
||||
"catface/app/utils/model_handler"
|
||||
"catface/app/utils/query_handler"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func CreateUserCurdFactory() *AnimalsCurd {
|
||||
return &AnimalsCurd{model.CreateAnimalFactory("")}
|
||||
}
|
||||
|
||||
type AnimalsCurd struct {
|
||||
animals *model.Animal // INFO 难道数据就是存储到这里?
|
||||
}
|
||||
|
||||
func getSelectAttrs(attrs string) (validSelectedFields []string) {
|
||||
if len(attrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
// 1. 获取空 Field
|
||||
fieldMap := model_handler.GetModelField(model.Animal{})
|
||||
|
||||
// 2. 开始检查请求字段
|
||||
attrsArray := query_handler.StringToStringArray(attrs)
|
||||
for _, attr := range attrsArray {
|
||||
if attr == "*" { // 不需要过滤,直接返回
|
||||
return nil
|
||||
} else if attr == "avatar" {
|
||||
fieldMap["avatar_height"] = true
|
||||
fieldMap["avatar_width"] = true
|
||||
}
|
||||
// 过滤 无效 的请求字段
|
||||
if _, ok := fieldMap[attr]; ok {
|
||||
fieldMap[attr] = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 装填字段
|
||||
for key, value := range fieldMap {
|
||||
if value {
|
||||
validSelectedFields = append(validSelectedFields, key)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (a *AnimalsCurd) List(attrs string, gender string, breed string, sterilzation string, status string, num int, skip int) []model.Animal {
|
||||
validSelectedFields := getSelectAttrs(attrs)
|
||||
genderArray := query_handler.StringToUint8Array(gender)
|
||||
breedArray := query_handler.StringToUint8Array(breed)
|
||||
sterilzationArray := query_handler.StringToUint8Array(sterilzation)
|
||||
statusArray := query_handler.StringToUint8Array(status)
|
||||
|
||||
if num == 0 {
|
||||
num = 10
|
||||
}
|
||||
|
||||
return model.CreateAnimalFactory("mysql").Show(validSelectedFields, genderArray, breedArray, sterilzationArray, statusArray, num, skip)
|
||||
}
|
||||
|
||||
func (a *AnimalsCurd) Detail(id string) *model.Animal {
|
||||
idInt, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
// TODO LOG
|
||||
fmt.Println("Detail id error:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return model.CreateAnimalFactory("mysql").ShowByID(idInt)
|
||||
}
|
19
app/utils/gorm_v2/utils.go
Normal file
19
app/utils/gorm_v2/utils.go
Normal file
@ -0,0 +1,19 @@
|
||||
package gorm_v2
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
/**
|
||||
* @description: 通过检查字段的方式构建 Where 函数。
|
||||
* @param {*gorm.DB} db
|
||||
* @param {map[string][]uint8} conditions
|
||||
* @return {*}
|
||||
*/
|
||||
func BuildWhere(db *gorm.DB, conditions map[string][]uint8) *gorm.DB {
|
||||
for field, values := range conditions {
|
||||
if len(values) == 0 || len(values) == 1 && values[0] == 0 {
|
||||
continue
|
||||
}
|
||||
db = db.Where(field+" in (?)", values)
|
||||
}
|
||||
return db
|
||||
}
|
@ -30,7 +30,7 @@ func getProcessedJSONTag(field reflect.StructField) string {
|
||||
}
|
||||
|
||||
func GetModelField(v interface{}) map[string]bool {
|
||||
t := reflect.TypeOf(v)
|
||||
t := reflect.TypeOf(v) // TODO 特化处理掉 BaseModel 这样的继承字段
|
||||
|
||||
fieldMap := make(map[string]bool)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user