🎨 better model code

This commit is contained in:
unknown 2024-10-14 19:27:46 +08:00
parent eaf4bb4ad8
commit 9b24a1f645
12 changed files with 209 additions and 126 deletions

View File

@ -2,8 +2,10 @@ package errcode
const (
ErrAnimalSqlFind = iota + ErrAnimal
AnimalNoFind
)
func AnimalMsgInit(m msg) {
m[ErrAnimalSqlFind] = "Animals 表单查询失败"
m[AnimalNoFind] = "Animals 没有查询到符合条件的目标"
}

View File

@ -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], "")
}
}

View File

@ -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
View 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
}

View 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
View File

@ -0,0 +1,6 @@
package model
type post struct { // Encounter 或者称为 post指的就是 Human 单次的记录。
BaseModel
UserID int
}

View File

@ -17,7 +17,7 @@ import (
// 参数说明: 传递空值,默认使用 配置文件选项UseDbTypemysql
func CreateUserFactory(sqlType string) *UsersModel {
return &UsersModel{BaseModel: BaseModel{DB: UseDbConn(sqlType)}}
return &UsersModel{BaseModel: BaseModel{DB: UseDbConn(sqlType)}} // INFO 这里补充 DB 的指针
}
type UsersModel struct {

View 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)
}

View 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
}

View File

@ -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.