From 45e0d82ba3fd39833eb6b565910e5058e47f35ed Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 24 Oct 2021 17:27:45 +0800 Subject: [PATCH] =?UTF-8?q?+=20helper=20=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/bindata.go | 52 +++++++++++------------ helper/array.go | 22 ++++++++++ helper/map.go | 19 +++++++++ helper/process.go | 106 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 172 insertions(+), 27 deletions(-) create mode 100644 helper/map.go diff --git a/data/bindata.go b/data/bindata.go index c01fdb95..448b5ca9 100644 --- a/data/bindata.go +++ b/data/bindata.go @@ -204,7 +204,7 @@ func uiFooBarHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "ui/foo/bar.html", size: 21, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "ui/foo/bar.html", size: 21, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -224,7 +224,7 @@ func uiIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "ui/index.html", size: 12, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "ui/index.html", size: 12, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -244,7 +244,7 @@ func xiangDs_store() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/.DS_Store", size: 6148, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/.DS_Store", size: 6148, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -264,7 +264,7 @@ func xiangApisReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -284,7 +284,7 @@ func xiangApisChartHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -304,7 +304,7 @@ func xiangApisPageHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -324,7 +324,7 @@ func xiangApisStorageHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/storage.http.json", size: 1092, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/storage.http.json", size: 1092, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -344,7 +344,7 @@ func xiangApisTableHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/table.http.json", size: 2632, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/table.http.json", size: 2632, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -364,7 +364,7 @@ func xiangApisUserHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -384,7 +384,7 @@ func xiangApisXiangHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/xiang.http.json", size: 797, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/apis/xiang.http.json", size: 797, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -404,7 +404,7 @@ func xiangDataAppJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/app.json", size: 245, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/app.json", size: 245, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -424,7 +424,7 @@ func xiangDataIconsDs_store() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/.DS_Store", size: 6148, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/icons/.DS_Store", size: 6148, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -444,7 +444,7 @@ func xiangDataIcons404Png() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -464,7 +464,7 @@ func xiangDataIconsIconIcns() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/icon.icns", size: 75636, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/icons/icon.icns", size: 75636, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -484,7 +484,7 @@ func xiangDataIconsIconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/icon.ico", size: 31310, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/icons/icon.ico", size: 31310, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -504,7 +504,7 @@ func xiangDataIconsIconPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/icon.png", size: 22420, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/icons/icon.png", size: 22420, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -524,7 +524,7 @@ func xiangDataIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/index.html", size: 302, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/data/index.html", size: 302, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -544,7 +544,7 @@ func xiangFlowsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -564,7 +564,7 @@ func xiangFlowsMenuFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -584,7 +584,7 @@ func xiangFlowsTableGetFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/flows/table/get.flow.json", size: 541, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/flows/table/get.flow.json", size: 541, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -604,7 +604,7 @@ func xiangModelsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -624,7 +624,7 @@ func xiangModelsMenuJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/menu.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/models/menu.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -644,7 +644,7 @@ func xiangModelsUserJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/user.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/models/user.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -664,7 +664,7 @@ func xiangTablesReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -684,7 +684,7 @@ func xiangTablesMenuJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/tables/menu.json", size: 10382, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/tables/menu.json", size: 10382, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -704,7 +704,7 @@ func xiangTablesUserJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/tables/user.json", size: 1422, mode: os.FileMode(420), modTime: time.Unix(1634983507, 0)} + info := bindataFileInfo{name: "xiang/tables/user.json", size: 1422, mode: os.FileMode(420), modTime: time.Unix(1635064961, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/helper/array.go b/helper/array.go index 21a0debd..b1cec79f 100644 --- a/helper/array.go +++ b/helper/array.go @@ -14,6 +14,28 @@ type ArrayPluckValue struct { Items []map[string]interface{} `json:"items"` } +// ArrayColumn 返回多条数据记录,指定字段数值。 +func ArrayColumn(records []map[string]interface{}, name string) []interface{} { + values := []interface{}{} + for _, record := range records { + values = append(values, record[name]) + } + return values +} + +// ArrayKeep 仅保留指定键名的数据 +func ArrayKeep(records []map[string]interface{}, keeps []string) []map[string]interface{} { + values := []map[string]interface{}{} + for _, record := range records { + value := map[string]interface{}{} + for _, keep := range keeps { + value[keep] = record[keep] + } + values = append(values, value) + } + return values +} + // ArraySplit 将多条数记录集合,分解为一个 columns:[]string 和 values: [][]interface{} func ArraySplit(records []map[string]interface{}) ([]string, [][]interface{}) { columns := []string{} diff --git a/helper/map.go b/helper/map.go new file mode 100644 index 00000000..08a09abf --- /dev/null +++ b/helper/map.go @@ -0,0 +1,19 @@ +package helper + +// MapValues 返回映射的数值 +func MapValues(record map[string]interface{}) []interface{} { + values := []interface{}{} + for _, value := range record { + values = append(values, value) + } + return values +} + +// MapKeys 返回映射的键 +func MapKeys(record map[string]interface{}) []string { + keys := []string{} + for key := range record { + keys = append(keys, key) + } + return keys +} diff --git a/helper/process.go b/helper/process.go index 3c7857fe..4d114c7e 100644 --- a/helper/process.go +++ b/helper/process.go @@ -13,7 +13,10 @@ func init() { // 注册处理器 gou.RegisterProcessHandler("xiang.helper.ArrayPluck", ProcessArrayPluck) gou.RegisterProcessHandler("xiang.helper.ArraySplit", ProcessArraySplit) - + gou.RegisterProcessHandler("xiang.helper.ArrayColumn", ProcessArrayColumn) + gou.RegisterProcessHandler("xiang.helper.ArrayKeep", ProcessArrayKeep) + gou.RegisterProcessHandler("xiang.helper.MapKeys", ProcessMapKeys) + gou.RegisterProcessHandler("xiang.helper.MapValues", ProcessMapValues) } // ProcessArrayPluck xiang.helper.ArrayPluck 将多个数据记录集合,合并为一个数据记录集合 @@ -76,3 +79,104 @@ func ProcessArraySplit(process *gou.Process) interface{} { "values": values, } } + +// ProcessArrayColumn xiang.helper.ArrayColumn 返回多条数据记录,指定字段数值。 +func ProcessArrayColumn(process *gou.Process) interface{} { + process.ValidateArgNums(2) + args := process.Args[0] + records := []map[string]interface{}{} + name := process.ArgsString(1) + + switch args.(type) { + case []interface{}: + for _, v := range args.([]interface{}) { + value, ok := v.(map[string]interface{}) + if ok { + records = append(records, value) + continue + } + exception.New("参数错误: 第1个参数不是数组", 400).Ctx(fmt.Sprintf("%#v", process.Args[0])).Throw() + } + break + case []share.Record: + for _, v := range args.([]share.Record) { + records = append(records, v) + } + break + case []map[string]interface{}: + records = args.([]map[string]interface{}) + break + default: + fmt.Printf("%#v %s\n", args, reflect.TypeOf(args).Kind()) + exception.New("参数错误: 第1个参数不是数组", 400).Ctx(fmt.Sprintf("%#v", process.Args[0])).Throw() + break + } + values := ArrayColumn(records, name) + return values +} + +// ProcessArrayKeep xiang.helper.ArrayKeep 仅保留指定键名的数据 +func ProcessArrayKeep(process *gou.Process) interface{} { + process.ValidateArgNums(2) + args := process.Args[0] + columnsAny := process.Args[1] + records := []map[string]interface{}{} + columns := []string{} + + switch args.(type) { + case []interface{}: + for _, v := range args.([]interface{}) { + value, ok := v.(map[string]interface{}) + if ok { + records = append(records, value) + continue + } + exception.New("参数错误: 第1个参数不是数组", 400).Ctx(fmt.Sprintf("%#v", process.Args[0])).Throw() + } + break + case []share.Record: + for _, v := range args.([]share.Record) { + records = append(records, v) + } + break + case []map[string]interface{}: + records = args.([]map[string]interface{}) + break + default: + fmt.Printf("%#v %s\n", args, reflect.TypeOf(args).Kind()) + exception.New("参数错误: 第1个参数不是数组", 400).Ctx(fmt.Sprintf("%#v", process.Args[0])).Throw() + break + } + + switch columnsAny.(type) { + case []interface{}: + for _, v := range columnsAny.([]interface{}) { + value, ok := v.(string) + if ok { + columns = append(columns, value) + continue + } + exception.New("参数错误: 第2个参数不是字符串数组", 400).Ctx(process.Args[0]).Throw() + } + case []string: + default: + exception.New("参数错误: 第2个参数不是字符串数组", 400).Ctx(process.Args[0]).Throw() + break + } + + return ArrayKeep(records, columns) +} + +// ProcessMapValues xiang.helper.MapValues 返回映射的数值 +func ProcessMapValues(process *gou.Process) interface{} { + process.ValidateArgNums(1) + record := process.ArgsMap(0) + return MapValues(record) +} + +// ProcessMapKeys xiang.helper.MapKeys 返回映射的键 +func ProcessMapKeys(process *gou.Process) interface{} { + process.ValidateArgNums(1) + record := process.ArgsMap(0) + return MapKeys(record) +}