package domain import ( "git.sxidc.com/go-tools/utils/reflectutils" "git.sxidc.com/go-tools/utils/strutils" "git.sxidc.com/go-tools/utils/template" "git.sxidc.com/service-supports/fserr" "github.com/iancoleman/strcase" "reflect" ) type Object interface { DBSchema() string DomainCNName() string DomainCamelName() string } func HasField(object Object, fieldName string) bool { return hasField(object, fieldName) } func SetField[T any](object Object, fieldName string, value T) error { if object == nil { return fserr.New("领域对象为nil") } fieldValue, err := getFieldValue(object, fieldName) if err != nil { return err } if !fieldValue.IsValid() || !fieldValue.CanSet() { return fserr.New("领域对象" + fieldValue.Type().String() + "的字段" + fieldName + "无法赋值") } fieldValue.Set(reflect.ValueOf(value)) return nil } func Field[T any](object Object, fieldName string) (T, error) { zero := reflectutils.Zero[T]() if object == nil { return zero, fserr.New("领域对象为nil") } fieldValue, err := getFieldValue(object, fieldName) if err != nil { return zero, err } if !fieldValue.IsValid() { return zero, fserr.New("领域对象" + fieldValue.Type().String() + "的字段" + fieldName + "无法赋值") } retValue, ok := fieldValue.Interface().(T) if !ok { return zero, err } return retValue, nil } func ToConcrete[T Object](object Object) (T, error) { zero := reflectutils.Zero[T]() if object == nil { return zero, fserr.New("领域对象为nil") } concrete, ok := object.(T) if !ok { return zero, fserr.New("领域对象转化失败") } return concrete, nil } func hasField(object Object, fieldName string) bool { if object == nil { return false } objectValue := reflect.ValueOf(object) if !reflectutils.IsValueStructOrStructPointer(objectValue) { return false } fieldValue := reflectutils.PointerValueElem(objectValue).FieldByName(fieldName) if !fieldValue.IsValid() { return false } return true } func getFieldValue(object Object, fieldName string) (*reflect.Value, error) { if object == nil { return nil, fserr.New("领域对象为nil") } objectValue := reflect.ValueOf(object) if !reflectutils.IsValueStructOrStructPointer(objectValue) { return nil, fserr.New("领域对象必须是结构或结构指针") } fieldValue := reflectutils.PointerValueElem(objectValue).FieldByName(fieldName) return &fieldValue, nil } func TableName(schema string, object Object) string { if strutils.IsStringNotEmpty(object.DBSchema()) { schema = object.DBSchema() } if strutils.IsStringEmpty(schema) { return template.Plural(strcase.ToSnake(template.Id(object.DomainCamelName()))) } else { return schema + "." + template.Plural(strcase.ToSnake(template.Id(object.DomainCamelName()))) } } func RelationTableName(schema string, left Object, right Object) string { if strutils.IsStringEmpty(schema) { return strcase.ToSnake(template.Id(left.DomainCamelName())) + "_and_" + strcase.ToSnake(template.Id(right.DomainCamelName())) } else { return schema + "." + strcase.ToSnake(template.Id(left.DomainCamelName())) + "_and_" + strcase.ToSnake(template.Id(right.DomainCamelName())) } } func RelativeDomainPath(object Object) string { return "/" + strcase.ToLowerCamel(template.Id(object.DomainCamelName())) } func SnakeDomainName(object Object) string { return strcase.ToSnake(template.Id(object.DomainCamelName())) }