mirror of
https://github.com/tobycroft/gorose-pro.git
synced 2026-04-22 15:47:04 +08:00
添加 DataStructStrict 方法并实现严格模式解析
- 在 orm.go 和 orm_interface.go 中添加 DataStructStrict 方法,支持基于 tag 的严格解析 - 在 structEngineNew.go 中添加 StructToMapStrict 和 StructToMapStrictSlices 函数,仅解析带有指定标签的字段
This commit is contained in:
@@ -137,6 +137,12 @@ func (dba *Orm) DataStruct(data interface{}) IOrm {
|
||||
return dba
|
||||
}
|
||||
|
||||
// DataStructStrict : 这是在DataStruct基础上加入的基于tag判断的输入项,如果没有对应标签例如默认的gorose标签则不会解析
|
||||
func (dba *Orm) DataStructStrict(data interface{}) IOrm {
|
||||
dba.data = StructToMapStrictSlices(data)
|
||||
return dba
|
||||
}
|
||||
|
||||
// Group : select group by
|
||||
func (dba *Orm) Group(group string) IOrm {
|
||||
dba.group = group
|
||||
|
||||
@@ -19,6 +19,7 @@ type IOrm interface {
|
||||
Distinct() IOrm
|
||||
Data(data interface{}) IOrm
|
||||
DataStruct(data interface{}) IOrm
|
||||
DataStructStrict(data interface{}) IOrm
|
||||
// groupBy, orderBy, having
|
||||
Group(group string) IOrm
|
||||
GroupBy(group string) IOrm
|
||||
|
||||
+84
-26
@@ -5,8 +5,7 @@ import (
|
||||
)
|
||||
|
||||
// ========================
|
||||
// 版本1:返回 []map[string]interface{}
|
||||
// 支持:struct/*struct/[]struct/[]*struct
|
||||
// 【原有版本1】切片版
|
||||
// ========================
|
||||
func StructToMapSlices(data interface{}) []map[string]interface{} {
|
||||
if data == nil {
|
||||
@@ -14,13 +13,11 @@ func StructToMapSlices(data interface{}) []map[string]interface{} {
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(data)
|
||||
return autoParse(v)
|
||||
return autoParse(v, parseStructWithDefault)
|
||||
}
|
||||
|
||||
// ========================
|
||||
// 版本2:返回 map[string]interface{}
|
||||
// 支持:struct/*struct
|
||||
// 就是原版
|
||||
// 【原有版本2】单个结构体
|
||||
// ========================
|
||||
func StructToMapV2(data interface{}) map[string]interface{} {
|
||||
if data == nil {
|
||||
@@ -29,7 +26,6 @@ func StructToMapV2(data interface{}) map[string]interface{} {
|
||||
|
||||
v := reflect.ValueOf(data)
|
||||
|
||||
// 解指针
|
||||
for v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return nil
|
||||
@@ -41,11 +37,49 @@ func StructToMapV2(data interface{}) map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
return parseStruct(v)
|
||||
return parseStructWithDefault(v)
|
||||
}
|
||||
|
||||
// 自动解析
|
||||
func autoParse(v reflect.Value) []map[string]interface{} {
|
||||
// ========================
|
||||
// 【新增:严格模式 - 只有带tag才解析,无tag跳过】
|
||||
// ========================
|
||||
func StructToMapStrict(data interface{}) map[string]interface{} {
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(data)
|
||||
|
||||
for v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil
|
||||
}
|
||||
|
||||
return parseStructStrict(v)
|
||||
}
|
||||
|
||||
// ========================
|
||||
// 【新增:严格模式切片版】
|
||||
// ========================
|
||||
func StructToMapStrictSlices(data interface{}) []map[string]interface{} {
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(data)
|
||||
return autoParse(v, parseStructStrict)
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// 内部通用解析
|
||||
// ------------------------------
|
||||
func autoParse(v reflect.Value, parseFunc func(val reflect.Value) map[string]interface{}) []map[string]interface{} {
|
||||
for v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return nil
|
||||
@@ -57,25 +91,29 @@ func autoParse(v reflect.Value) []map[string]interface{} {
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Struct:
|
||||
res = append(res, parseStruct(v))
|
||||
res = append(res, parseFunc(v))
|
||||
|
||||
case reflect.Slice, reflect.Array:
|
||||
// 🔥 这里修复了:val.Len() → v.Len()
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
item := v.Index(i)
|
||||
for item.Kind() == reflect.Ptr {
|
||||
item = item.Elem()
|
||||
}
|
||||
if item.Kind() == reflect.Struct {
|
||||
res = append(res, parseStruct(item))
|
||||
res = append(res, parseFunc(item))
|
||||
}
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// 解析结构体核心方法
|
||||
func parseStruct(val reflect.Value) map[string]interface{} {
|
||||
// ------------------------------
|
||||
// 普通模式:无tag用字段名
|
||||
// ------------------------------
|
||||
func parseStructWithDefault(val reflect.Value) map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
typ := val.Type()
|
||||
|
||||
@@ -83,32 +121,52 @@ func parseStruct(val reflect.Value) map[string]interface{} {
|
||||
field := typ.Field(i)
|
||||
fv := val.Field(i)
|
||||
|
||||
// 跳过私有字段
|
||||
if field.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 跳过嵌套结构体
|
||||
if fv.Kind() == reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
// 读取 gorose 标签
|
||||
tag := field.Tag.Get(TAGNAME)
|
||||
|
||||
// 忽略标记
|
||||
if tag == "ignore" {
|
||||
continue
|
||||
}
|
||||
|
||||
// ======================
|
||||
// ✅ 关键:无标签 → 使用结构体原生字段名
|
||||
// ======================
|
||||
if tag == "" {
|
||||
tag = field.Name // 这里就是自动使用原生名字
|
||||
tag = field.Name
|
||||
}
|
||||
|
||||
m[tag] = fv.Interface()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// 严格模式:无tag 直接跳过不解析
|
||||
// ------------------------------
|
||||
func parseStructStrict(val reflect.Value) map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
typ := val.Type()
|
||||
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
fv := val.Field(i)
|
||||
|
||||
if field.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
tag := field.Tag.Get(TAGNAME)
|
||||
|
||||
// 🔥 无tag 或 ignore → 跳过
|
||||
if tag == "" || tag == "ignore" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 保留所有值:0 / "" / false 都不会丢
|
||||
m[tag] = fv.Interface()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user