From c6ec8deb7c4f9836a40436c8077cda6f2641da8e Mon Sep 17 00:00:00 2001 From: maolinc <2391582228@qq.com> Date: Sat, 19 Aug 2023 15:46:13 +0800 Subject: [PATCH 1/3] vision soul gencode --- template/api_common.tpl | 26 +------ template/api_types.tpl | 2 +- template/model_model.tpl | 103 +++++++++++++++++++++++--- template/model_schema.tpl | 129 ++++++++++++++------------------- template/model_typs_common.tpl | 2 +- 5 files changed, 154 insertions(+), 108 deletions(-) diff --git a/template/api_common.tpl b/template/api_common.tpl index 10fc99c..0e91b6b 100644 --- a/template/api_common.tpl +++ b/template/api_common.tpl @@ -9,19 +9,6 @@ info ( version: "{{.Version}}" ) -type SearchItem { - Table string `json:"table,optional"` //表 - Field string `json:"field"` // 字段 - Value string `json:"value"` // 值 - Type string `json:"type"` // 值的数据类型 number string date numberArray stringArray - Operator string `json:"operator"` // 操作符 = != > >= 包含 不包含... - Logic string `json:"logic,optional"` // 逻辑符 and | or -} -type SearchGroup { - Group []SearchItem `json:"group"` // 条件组合 - Logic string `json:"logic,optional"` // 逻辑符 and | or -} - // 基本查询参数, 根据自己需要进行修改 type SearchBase { Keyword string `json:"keyword,optional"` // 关键字 @@ -30,7 +17,7 @@ type SearchBase { PageSize int `json:"pageSize,default=20,optional"` // 每页条数 PageCurrent int `json:"pageCurrent,default=1,optional"` // 当前页 OrderSort []string `json:"orderSort,optional"` // 排序 eg: ["create_time asc", "id desc"] - SearchPlus []SearchGroup `json:"searchPlus,optional"` // 加强版自定义搜索参数 + SearchPlus string `json:"searchPlus,optional"` // 加强版自定义搜索参数 } // 统一分页返回 @@ -40,13 +27,4 @@ type PageBase { PageSize int `json:"pageSize,omitempty"` // 分页大小 PageTotal int `json:"pageTotal,omitempty"` // 总分页数 LastCursor int64 `json:"lastCursor,omitempty"` // 使用游标分页时, 返回最后一个游标 -} - -type ( - IdReq { - Id int64 `json:"id"` - } - IdsReq { - Ids []int64 `json:"ids"` - } -) \ No newline at end of file +} \ No newline at end of file diff --git a/template/api_types.tpl b/template/api_types.tpl index 5502351..bd4da9c 100644 --- a/template/api_types.tpl +++ b/template/api_types.tpl @@ -10,7 +10,7 @@ info ( ) import ( - "types/common.api" + "common.api" ) //-----------------------{{.CamelName}}的接口----------------------- diff --git a/template/model_model.tpl b/template/model_model.tpl index fcc7a89..cb054cc 100644 --- a/template/model_model.tpl +++ b/template/model_model.tpl @@ -6,7 +6,11 @@ import ( "database/sql" {{if .IsCache -}} "fmt" + "time" + "gitee.com/maolinc/vision-soul-common/collectx" + "gitee.com/maolinc/vision-soul-common/utilx" "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/redis" {{end -}} "gorm.io/gorm" {{if .IsDate}}"time"{{end -}} @@ -22,7 +26,7 @@ type ( {{range .Fields}} {{.CamelName}} {{.DataType}} `gorm:"{{.Name}} {{- if .IsPrimary}};primary_key{{end}}"` //{{.Comment}} {{end}}} - // {{.CamelName}} query cond + // {{.CamelName}}Query query cond {{.CamelName}}Query struct { SearchBase {{.CamelName}} @@ -48,18 +52,28 @@ type ( // FindListByCursor Cursor is required based on cursor paging, Only the primary key is of type int, and other types can be expanded by themselves FindListByCursor(ctx context.Context, cond *{{.CamelName}}Query) (list []*{{.CamelName}}, err error) FindAll(ctx context.Context, cond *{{.CamelName}}Query) (list []*{{.CamelName}}, err error) + // FindListByIds + FindListByIds(ctx context.Context, ids []{{.Primary.DataType}}) (list []*Picture, err error) // ---------------Write your other interfaces below--------------- } default{{.CamelName}}Model struct { *customConn + {{if .IsCache}} + redis *redis.Redis + expire time.Duration + {{end}} table string } ) -func New{{.CamelName}}Model(db *gorm.DB {{- if .IsCache}}, c cache.CacheConf{{end}}) {{.CamelName}}Model { +func New{{.CamelName}}Model(db *gorm.DB {{- if .IsCache}}, c cache.CacheConf, redis *redis.Redis{{end}}) {{.CamelName}}Model { return &default{{.CamelName}}Model{ customConn: {{if .IsCache}}newCustomConn(db, c){{else}}newCustomConnNoCache(db){{end}}, + {{if .IsCache}} + redis: redis, + expire: 10, + {{end}} table: "{{.Name}}", } } @@ -87,7 +101,7 @@ func (m *default{{.CamelName}}Model) Trans(ctx context.Context, fn func(ctx cont func (m *default{{.CamelName}}Model) Insert(ctx context.Context, data *{{.CamelName}}, db ...*gorm.DB) (err error) { {{if .IsCache -}} - cacheKey := fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV}}) + cacheKey := m.getPrimaryCacheKey(data.{{.Primary.CamelName}}) {{end -}} return m.Exec(ctx, func() error { return m.conn(ctx, db...).Create(data).Error @@ -96,7 +110,7 @@ func (m *default{{.CamelName}}Model) Insert(ctx context.Context, data *{{.CamelN func (m *default{{.CamelName}}Model) Update(ctx context.Context, data *{{.CamelName}}, db ...*gorm.DB) (err error) { {{if .IsCache -}} - cacheKey := fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV}}) + cacheKey := m.getPrimaryCacheKey(data.{{.Primary.CamelName}}) {{end -}} return m.Exec(ctx, func() error { return m.conn(ctx, db...).Model(&data).Updates(data).Error @@ -105,7 +119,7 @@ func (m *default{{.CamelName}}Model) Update(ctx context.Context, data *{{.CamelN func (m *default{{.CamelName}}Model) Delete(ctx context.Context, {{.PrimaryFields}}, db ...*gorm.DB) (err error) { {{if .IsCache -}} - cacheKey := fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV2}}) + cacheKey := m.getPrimaryCacheKey({{.PrimaryFmtV2}}) {{end -}} return m.Exec(ctx, func() error { return m.conn(ctx, db...).Where("{{.PrimaryFieldWhere}}", {{.PrimaryFmtV2}}).Delete({{.CamelName}}{}).Error @@ -114,7 +128,7 @@ func (m *default{{.CamelName}}Model) Delete(ctx context.Context, {{.PrimaryField func (m *default{{.CamelName}}Model) ForceDelete(ctx context.Context, {{.PrimaryFields}}, db ...*gorm.DB) (err error) { {{if .IsCache -}} - cacheKey := fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV2}}) + cacheKey := m.getPrimaryCacheKey({{.PrimaryFmtV2}}) {{end -}} return m.Exec(ctx, func() error { return m.conn(ctx, db...).Unscoped().Where("{{.PrimaryFieldWhere}}", {{.PrimaryFmtV2}}).Delete({{.CamelName}}{}).Error @@ -130,7 +144,7 @@ func (m *default{{.CamelName}}Model) Count(ctx context.Context, cond *{{.CamelNa func (m *default{{.CamelName}}Model) FindOne(ctx context.Context, {{.PrimaryFields}}) (data *{{.CamelName}}, err error) { {{if .IsCache -}} - cacheKey := fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV2}}) + cacheKey := m.getPrimaryCacheKey({{.PrimaryFmtV2}}) {{end -}} err = m.QueryRow(ctx, &data, func(v interface{}) error { tx := m.conn(ctx).Where("{{.PrimaryFieldWhere}}", {{.PrimaryFmtV2}}).Find(v) @@ -163,8 +177,22 @@ func (m *default{{.CamelName}}Model) FindListByPage(ctx context.Context, cond *{ searchPlusScope(cond.SearchPlus, m.table), orderScope(cond.OrderSort...), pageScope(cond.PageCurrent, cond.PageSize), - ) - err = conn.Where(cond.{{.CamelName}}).Find(&list).Error + ).Where(cond.{{.CamelName}}) + + {{if .IsCache}} + ids := make([]{{.Primary.DataType}}, 0, cond.PageSize) + if err = conn.Pluck("{{.Primary.Name}}", &ids).Error; err != nil { + return nil, err + } + if len(ids) == 0 { + return list, nil + } + + list, err = m.FindListByIds(ctx, ids) + {{else}} + err = conn.Find(&list).Error + {{end}} + return list, err } @@ -186,3 +214,60 @@ func (m *default{{.CamelName}}Model) FindAll(ctx context.Context, cond *{{.Camel err = conn.Where(cond.{{.CamelName}}).Find(&list).Error return list, err } + +func (m *defaultPictureModel) FindListByIds(ctx context.Context, ids []{{.Primary.DataType}}) (list []*Picture, err error) { + {{if .IsCache}} + idKeys := m.getCacheKeysByIds(ids) + jsonArr, err := m.redis.Mget(idKeys...) + if err != nil { + return list, nil + } + list = utilx.Json2StructArr[{{.CamelName}}](jsonArr) + if len(list) == len(ids) { + return list, nil + } + + notExistIds := make([]{{.Primary.DataType}}, 0) + set := collectx.NewSet[int64]() + for _, item := range list { + set.Add(item.{{.Primary.CamelName}}) + } + for _, id := range ids { + if set.Add(id) { + notExistIds = append(notExistIds, id) + } + } + dbList := make([]*{{.CamelName}}, 0, len(notExistIds)) + err = m.conn(ctx).Where("{{.Primary.Name}} in ?", notExistIds).Find(&dbList).Error + if err != nil { + return nil, err + } + + _ = m.redis.PipelinedCtx(ctx, func(pipeliner redis.Pipeliner) error { + for _, item := range dbList { + key := m.getPrimaryCacheKey(item.{{.Primary.CamelName}}) + pipeliner.SetEX(ctx, key, item, m.expire) + } + return nil + }) + + return append(list, dbList...), nil + {{else}} + {{end}} +} + + +{{if .IsCache}} +func (m *default{{.CamelName}}Model) getPrimaryCacheKey({{.PrimaryFields}}) string { + return fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV2}}) +} + +func (m *defaultPictureModel) getCacheKeysByIds(ids []{{.Primary.DataType}}) []string { + idKeys := make([]string, 0, len(ids)) + for _, id := range ids { + idKeys = append(idKeys, fmt.Sprintf("%s%v", cachePicturePrimaryPrefix, id)) + } + return idKeys +} + +{{end}} \ No newline at end of file diff --git a/template/model_schema.tpl b/template/model_schema.tpl index 2a9194c..2c1d14f 100644 --- a/template/model_schema.tpl +++ b/template/model_schema.tpl @@ -70,6 +70,14 @@ func (c *customConn) QueryRow(ctx context.Context, v interface{}, query func(v i }) } +func getCacheKeysByIds(prefixFormat string, ids []any) []string { + idKeys := make([]string, 0, len(ids)) + for _, id := range ids { + idKeys = append(idKeys, fmt.Sprintf("%s%v", prefixFormat, id)) + } + return idKeys +} + // -----------gorm common scope---------------------- // Normal pagination func pageScope(pageCurrent, pageSize int) func(db *gorm.DB) *gorm.DB { @@ -151,74 +159,41 @@ func searchPlusScope(plus []SearchGroup, tableName string) func(db *gorm.DB) *go if searchItem.Field == "" { continue } - value, typ, operator := searchItem.Value, strings.ToLower(searchItem.Type), strings.ToLower(searchItem.Operator) + typ, operator := strings.ToLower(searchItem.Type), strings.ToLower(searchItem.Operator) var ( - v any err error logic = getLogic(searchItem.Logic) ) + value, err := getRealValue(typ, searchItem.Value) + if err != nil || value == nil { + continue + } - switch typ { - case "number": - v, err = strconv.ParseInt(value, 10, 64) - case "float": - v, err = strconv.ParseFloat(value, 64) - case "date": - if v1, err := strconv.ParseInt(value, 10, 64); err == nil { - if t := time.Unix(v1, 0); err == nil { - v = t.String() - } - break - } - if t, err := time.Parse("2006-01-02 15:04:05", value); err == nil { - v = t.String() - } - case "string": - if !strings.HasPrefix(value, "\"") { - // ”abc“ -> ""abc"" - value = fmt.Sprintf("\"%s\"", value) - } - v, err = unmarshal[string](value) - if operator == "包含" || operator == "不包含" || operator == "like" || operator == "not like" { - v = fmt.Sprintf("%%%v%%", v) - } - case "stringarray": - if strings.HasPrefix(value, "[") { - // "[”a”,“b”,“c“]" - v, err = unmarshal[[]string](value) - } else { - // "a,b,c" - v = strings.Split(value, ",") - } - case "numberarray": - if !strings.HasPrefix(value, "[") { - // 1,2,3 -> "[1,2,3]" - value = fmt.Sprintf("[%s]", value) + switch vv := reflect.ValueOf(value); vv.Kind() { + case reflect.Slice: + if operator == "不包含" || operator == "!=" { + operator = "NOT IN" + } else if operator == "包含" || operator == "=" { + operator = "IN" } - v, err = unmarshal[[]int64](value) - case "floatarray": - if !strings.HasPrefix(value, "[") { - // 1,2,3.2 -> "[1,2,3.2]" - value = fmt.Sprintf("[%s]", value) - } - v, err = unmarshal[[]float64](value) default: - v = value - } - - if err != nil || v == nil { - continue + if operator == "不包含" { + operator = "NOT LIKE" + } else if operator == "包含" { + operator = "LIKE" + } + value = fmt.Sprintf("%%%v%%", value) } if subQ.Len() != 0 { fmt.Fprintf(&subQ, " %s ", logic) } if searchItem.Table == "" { - fmt.Fprintf(&subQ, "`%s`.`%s` %s ?", tableName, searchItem.Field, getOperator(operator, typ)) + fmt.Fprintf(&subQ, "`%s`.`%s` %s ?", tableName, searchItem.Field, operator) } else { - fmt.Fprintf(&subQ, "`%s`.`%s` %s ?", searchItem.Table, searchItem.Field, getOperator(operator, typ)) + fmt.Fprintf(&subQ, "`%s`.`%s` %s ?", searchItem.Table, searchItem.Field, operator) } - queryArgs = append(queryArgs, v) + queryArgs = append(queryArgs, value) } if subQ.Len() == 0 { continue @@ -241,31 +216,39 @@ func searchPlusScope(plus []SearchGroup, tableName string) func(db *gorm.DB) *go } func getLogic(logic string) string { - logic = strings.ToLower(logic) - if logic != "and" && logic != "or" { - return "and" + logic = strings.ToUpper(logic) + if logic != "And" && logic != "OR" { + return "And" } return logic } -func getOperator(oper, typ string) string { - switch oper { - case "包含": - if typ == "string" { - return "like" - } - return "in" - case "不包含": - if typ == "string" { - return "not like" +func getRealValue(typ string, value interface{}) (interface{}, error) { + var ( + v interface{} + err error + ) + switch typ { + case "date": + var dataT time.Time + switch vv := value.(type) { + case float64: + dataT = time.Unix(int64(vv), 0) + case float32: + dataT = time.Unix(int64(vv), 0) + case int64: + dataT = time.Unix(vv, 0) + case int: + dataT = time.Unix(int64(vv), 0) + case string: + if dataT, err = time.Parse("2006-01-02 15:04:05", vv); err != nil { + dataT = time.Now() + } } - return "not in" + v = dataT.UTC().Format("2006-01-02 15:04:05") + default: + v = value } - return oper -} -func unmarshal[T any](v string) (T, error) { - var t T - err := json.Unmarshal([]byte(v), &t) - return t, err + return v, err } diff --git a/template/model_typs_common.tpl b/template/model_typs_common.tpl index a548e10..8b11416 100644 --- a/template/model_typs_common.tpl +++ b/template/model_typs_common.tpl @@ -3,7 +3,7 @@ package model type SearchItem struct { Table string `json:"table"` Field string `json:"field"` // 字段 - Value string `json:"value"` // 值 + Value any `json:"value"` // 值 Type string `json:"type"` // 值的数据类型 number string date numberArray stringArray Operator string `json:"operator"` // 操作符 = != > >= 包含 不包含... Logic string `json:"logic,optional"` // 逻辑符 and | or From 87f9457c84ad2a754b381d353ea96a7e64412989 Mon Sep 17 00:00:00 2001 From: maolinc <2391582228@qq.com> Date: Tue, 22 Aug 2023 01:11:42 +0800 Subject: [PATCH 2/3] vision soul gencode --- genConfig.json | 26 ++++++++++++++------------ template/model_model.tpl | 6 +++--- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/genConfig.json b/genConfig.json index 05379f5..881cf40 100644 --- a/genConfig.json +++ b/genConfig.json @@ -1,29 +1,31 @@ { "DBConfig": { "DbType": "mysql", - "DBName": "", - "Host": "", + "DBName": "vision_soul", + "Host": "101.33.244.52", "Port": 3306, - "User": "", - "Password": "" + "User": "root", + "Password": "lucas9" }, "GlobalConfig": { - "ServiceName": "artifact" + "FieldStyle": "m_lc", + "ServiceName": "vision_soul" }, "ApiConfig": { "Switch": "C", - "OutPath": "C:\\Users\\maolin.chen\\Desktop\\me\\workspace\\xyz\\app\\artifact/api", + "OutPath": "D:\\CML\\Desktop\\ai\\vision-soul", "GoZeroStyle": "go_zero", - "DateStyle": "string" + "DateStyle": "string", + "Tables": ["picture"] }, "ProtoConfig": { - "Switch": "B", + "Switch": "C", "OutPath": "artifact/rpc" }, "ModelConfig": { - "Switch": "C", - "OutPath": "C:\\Users\\maolin.chen\\Desktop\\me\\workspace\\xyz\\app\\artifact/model", - "Tables": [], - "IsCache": true + "Switch": "B", + "OutPath": "D:\\CML\\Desktop\\ai\\vision-soul\\model", + "IsCache": true, + "Tables": ["file_object"] } } \ No newline at end of file diff --git a/template/model_model.tpl b/template/model_model.tpl index cb054cc..155747a 100644 --- a/template/model_model.tpl +++ b/template/model_model.tpl @@ -53,7 +53,7 @@ type ( FindListByCursor(ctx context.Context, cond *{{.CamelName}}Query) (list []*{{.CamelName}}, err error) FindAll(ctx context.Context, cond *{{.CamelName}}Query) (list []*{{.CamelName}}, err error) // FindListByIds - FindListByIds(ctx context.Context, ids []{{.Primary.DataType}}) (list []*Picture, err error) + FindListByIds(ctx context.Context, ids []{{.Primary.DataType}}) (list []*{{.CamelName}}, err error) // ---------------Write your other interfaces below--------------- } @@ -215,7 +215,7 @@ func (m *default{{.CamelName}}Model) FindAll(ctx context.Context, cond *{{.Camel return list, err } -func (m *defaultPictureModel) FindListByIds(ctx context.Context, ids []{{.Primary.DataType}}) (list []*Picture, err error) { +func (m *default{{.CamelName}}Model) FindListByIds(ctx context.Context, ids []{{.Primary.DataType}}) (list []*{{.CamelName}}, err error) { {{if .IsCache}} idKeys := m.getCacheKeysByIds(ids) jsonArr, err := m.redis.Mget(idKeys...) @@ -262,7 +262,7 @@ func (m *default{{.CamelName}}Model) getPrimaryCacheKey({{.PrimaryFields}}) stri return fmt.Sprintf("%s{{.PrimaryFmt}}", cache{{.CamelName}}PrimaryPrefix, {{.PrimaryFmtV2}}) } -func (m *defaultPictureModel) getCacheKeysByIds(ids []{{.Primary.DataType}}) []string { +func (m *default{{.CamelName}}Model) getCacheKeysByIds(ids []{{.Primary.DataType}}) []string { idKeys := make([]string, 0, len(ids)) for _, id := range ids { idKeys = append(idKeys, fmt.Sprintf("%s%v", cachePicturePrimaryPrefix, id)) From d4115a965f2bd884a6e03297c009ca712aff83c3 Mon Sep 17 00:00:00 2001 From: maolinc <82015883+maolinc@users.noreply.github.com> Date: Tue, 22 Aug 2023 12:19:01 +0800 Subject: [PATCH 3/3] Update genConfig.json --- genConfig.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/genConfig.json b/genConfig.json index 881cf40..46ecad6 100644 --- a/genConfig.json +++ b/genConfig.json @@ -1,31 +1,31 @@ { "DBConfig": { "DbType": "mysql", - "DBName": "vision_soul", - "Host": "101.33.244.52", - "Port": 3306, - "User": "root", - "Password": "lucas9" + "DBName": "", + "Host": "", + "Port": , + "User": "", + "Password": "" }, "GlobalConfig": { "FieldStyle": "m_lc", - "ServiceName": "vision_soul" + "ServiceName": "" }, "ApiConfig": { "Switch": "C", - "OutPath": "D:\\CML\\Desktop\\ai\\vision-soul", + "OutPath": "", "GoZeroStyle": "go_zero", "DateStyle": "string", - "Tables": ["picture"] + "Tables": [""] }, "ProtoConfig": { "Switch": "C", - "OutPath": "artifact/rpc" + "OutPath": "" }, "ModelConfig": { - "Switch": "B", - "OutPath": "D:\\CML\\Desktop\\ai\\vision-soul\\model", + "Switch": "C", + "OutPath": "", "IsCache": true, - "Tables": ["file_object"] + "Tables": [""] } -} \ No newline at end of file +}