123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- package rest
- import (
- "gorm.io/gorm/schema"
- "reflect"
- "strings"
- "time"
- )
- var (
- timeKind = reflect.TypeOf(time.Time{}).Kind()
- timePtrKind = reflect.TypeOf(&time.Time{}).Kind()
- )
- //dataTypeOf 推断数据的类型
- func dataTypeOf(field *schema.Field) string {
- var dataType string
- reflectType := field.FieldType
- for reflectType.Kind() == reflect.Ptr {
- reflectType = reflectType.Elem()
- }
- dataValue := reflect.Indirect(reflect.New(reflectType))
- switch dataValue.Kind() {
- case reflect.Bool:
- dataType = "boolean"
- case reflect.Int8, reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- dataType = "integer"
- case reflect.Float32, reflect.Float64:
- dataType = "double"
- case reflect.Struct:
- if _, ok := dataValue.Interface().(time.Time); ok {
- dataType = "string"
- }
- default:
- dataType = "string"
- }
- return dataType
- }
- //dataFormatOf 推断数据的格式
- func dataFormatOf(field *schema.Field) string {
- var format string
- format = field.Tag.Get("format")
- if format != "" {
- return format
- }
- //如果有枚举值,直接设置为下拉类型
- enum := field.Tag.Get("enum")
- if enum != "" {
- return "dropdown"
- }
- reflectType := field.FieldType
- for reflectType.Kind() == reflect.Ptr {
- reflectType = reflectType.Elem()
- }
- //时间处理
- if field.Name == "CreatedAt" || field.Name == "UpdatedAt" || field.Name == "DeletedAt" {
- return "datetime"
- }
- if strings.Contains(strings.ToLower(field.Name), "pass") {
- return "password"
- }
- dataValue := reflect.Indirect(reflect.New(reflectType))
- switch dataValue.Kind() {
- case timeKind, timePtrKind:
- format = "datetime"
- case reflect.Bool:
- format = "boolean"
- case reflect.Int8, reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- format = "integer"
- case reflect.Float32, reflect.Float64:
- format = "decimal"
- case reflect.Struct:
- if _, ok := dataValue.Interface().(time.Time); ok {
- format = "datetime"
- }
- default:
- if field.Size >= 1024 {
- format = "text"
- } else {
- format = "string"
- }
- }
- return format
- }
- //generateFieldName 生成字段名称
- func generateFieldName(name string) string {
- tokens := strings.Split(name, "_")
- for i, s := range tokens {
- tokens[i] = strings.Title(s)
- }
- return strings.Join(tokens, " ")
- }
- //generateFieldScenario 生成数据的显示场景
- func generateFieldScenario(index int, field *schema.Field) Scenarios {
- var ss Scenarios
- if v, ok := field.Tag.Lookup("scenarios"); ok {
- v = strings.TrimSpace(v)
- if v != "" {
- ss = strings.Split(v, ";")
- }
- } else {
- if field.PrimaryKey {
- ss = []string{ScenarioList, ScenarioView, ScenarioExport}
- } else if field.Name == "CreatedAt" || field.Name == "UpdatedAt" {
- ss = []string{ScenarioList}
- } else if field.Name == "DeletedAt" || field.Name == "Namespace" {
- //不添加任何显示场景
- ss = []string{}
- } else {
- if index < 10 {
- //高级字段只配置一些简单的场景
- ss = []string{ScenarioSearch, ScenarioList, ScenarioCreate, ScenarioUpdate, ScenarioView, ScenarioExport}
- } else {
- //高级字段只配置一些简单的场景
- ss = []string{ScenarioCreate, ScenarioUpdate, ScenarioView, ScenarioExport}
- }
- }
- }
- return ss
- }
- //generateFieldRule 生成字段的规则
- func generateFieldRule(field *schema.Field) Rule {
- r := Rule{
- Required: []string{},
- }
- if field.GORMDataType == schema.String {
- r.Max = field.Size
- }
- if field.GORMDataType == schema.Int || field.GORMDataType == schema.Float || field.GORMDataType == schema.Uint {
- r.Max = field.Scale
- }
- if field.NotNull {
- r.Required = []string{ScenarioCreate, ScenarioUpdate}
- }
- if field.PrimaryKey {
- r.Unique = true
- }
- return r
- }
- // generateFieldAttribute 生成数据属性
- func generateFieldAttribute(field *schema.Field) Attribute {
- attr := Attribute{
- Match: MatchFuzzy,
- PrimaryKey: field.PrimaryKey,
- DefaultValue: field.DefaultValue,
- Readonly: []string{},
- Disable: []string{},
- Visible: make([]VisibleCondition, 0),
- Values: make([]EnumValue, 0),
- Live: LiveValue{},
- Description: "",
- }
- //赋值属性
- props := field.Tag.Get("props")
- if props != "" {
- vs := strings.Split(props, ";")
- for _, str := range vs {
- kv := strings.SplitN(str, ":", 2)
- if len(kv) != 2 {
- continue
- }
- switch strings.ToLower(kv[0]) {
- case "icon":
- attr.Icon = kv[1]
- case "suffix":
- attr.Suffix = kv[1]
- case "tooltip":
- attr.Tooltip = kv[1]
- case "description":
- attr.Description = kv[1]
- case "live":
- //在线数据解析
- ss := strings.Split(kv[1], ",")
- for _, s := range ss {
- if len(s) == 0 {
- continue
- }
- attr.Live.Enable = true
- if s == LiveTypeDropdown || s == LiveTypeCascader {
- attr.Live.Type = s
- } else if s[0] == '/' || strings.HasPrefix(s, "http") {
- attr.Live.Url = s
- } else {
- if strings.IndexByte(s, '.') > -1 {
- attr.Live.Columns = strings.Split(s, ".")
- }
- }
- }
- }
- }
- }
- //赋值枚举值
- enumns := field.Tag.Get("enum")
- if enumns != "" {
- vs := strings.Split(enumns, ";")
- for _, str := range vs {
- kv := strings.SplitN(str, ":", 2)
- if len(kv) != 2 {
- continue
- }
- fv := EnumValue{Value: kv[0]}
- //颜色分隔符
- if pos := strings.IndexByte(kv[1], '#'); pos > -1 {
- fv.Label = kv[1][:pos]
- fv.Color = kv[1][pos:]
- } else {
- fv.Label = kv[1]
- }
- attr.Values = append(attr.Values, fv)
- }
- }
- if !field.Creatable {
- attr.Disable = append(attr.Disable, ScenarioCreate)
- }
- if !field.Updatable {
- attr.Disable = append(attr.Disable, ScenarioUpdate)
- }
- attr.Tooltip = field.Comment
- return attr
- }
|