v0.9.29 更新UI
This commit is contained in:
parent
b6c65a63f1
commit
64d177fc27
4 changed files with 330 additions and 12 deletions
217
imports/column.go
Normal file
217
imports/column.go
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
package imports
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
// MarshalJSON for json marshalJSON
|
||||
func (column Column) MarshalJSON() ([]byte, error) {
|
||||
data := column.ToMap()
|
||||
return jsoniter.Marshal(data)
|
||||
}
|
||||
|
||||
// UnmarshalJSON for json marshalJSON
|
||||
func (column *Column) UnmarshalJSON(source []byte) error {
|
||||
var data = map[string]interface{}{}
|
||||
err := jsoniter.Unmarshal(source, &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
new, err := ColumnOf(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*column = *new
|
||||
return nil
|
||||
}
|
||||
|
||||
// ColumnOf 映射表转换为字段定义
|
||||
func ColumnOf(data map[string]interface{}) (*Column, error) {
|
||||
var column = &Column{}
|
||||
|
||||
err := column.setLabel(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = column.setName(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = column.setMatch(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = column.setRules(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if primary, ok := data["primary"].(bool); ok {
|
||||
column.Primary = primary
|
||||
}
|
||||
|
||||
if nullable, ok := data["nullable"].(bool); ok {
|
||||
column.Nullable = nullable
|
||||
}
|
||||
|
||||
return column, nil
|
||||
}
|
||||
|
||||
// ToMap 转换为映射表
|
||||
func (column Column) ToMap() map[string]interface{} {
|
||||
if column.IsArray {
|
||||
column.Name = column.Name + "[*]"
|
||||
}
|
||||
|
||||
if column.IsObject {
|
||||
column.Name = column.Name + "." + column.Key
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"name": column.Name,
|
||||
"label": column.Label,
|
||||
"match": column.Match,
|
||||
"rules": column.Rules,
|
||||
}
|
||||
|
||||
if column.Nullable {
|
||||
data["nullable"] = true
|
||||
}
|
||||
|
||||
if column.Primary {
|
||||
data["primary"] = true
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// setRules 设置清洗规则
|
||||
func (column *Column) setRules(data map[string]interface{}) error {
|
||||
rules, err := GetArrayString(data, "rules")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查 process 是否存在
|
||||
|
||||
column.Rules = rules
|
||||
return nil
|
||||
}
|
||||
|
||||
// setLabel 读取并设置字段标签
|
||||
func (column *Column) setLabel(data map[string]interface{}) error {
|
||||
label, err := GetString(data, "label", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
column.Label = label
|
||||
return nil
|
||||
}
|
||||
|
||||
// setMatch 读取并设置字段名称
|
||||
func (column *Column) setMatch(data map[string]interface{}) error {
|
||||
match, err := GetArrayString(data, "match")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
column.Match = match
|
||||
return nil
|
||||
}
|
||||
|
||||
// setName 读取并设置字段名称
|
||||
func (column *Column) setName(data map[string]interface{}) error {
|
||||
name, err := GetString(data, "name", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.Contains(name, "[*]") { // Array
|
||||
namer := strings.Split(name, "[*]")
|
||||
name = namer[0]
|
||||
column.IsArray = true
|
||||
name = strings.Join(namer, "")
|
||||
}
|
||||
|
||||
if strings.Contains(name, ".") { // Object
|
||||
namer := strings.Split(name, ".")
|
||||
name = namer[0]
|
||||
if len(namer) > 1 {
|
||||
column.IsObject = true
|
||||
column.Key = strings.Join(namer[1:], ".")
|
||||
}
|
||||
}
|
||||
|
||||
column.Name = name
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetString 读取字符串格式
|
||||
func GetString(data map[string]interface{}, key string, required bool) (string, error) {
|
||||
value, ok := data[key].(string)
|
||||
if !ok {
|
||||
if bytes, isok := data[key].([]byte); isok {
|
||||
ok = isok
|
||||
value = string(bytes)
|
||||
}
|
||||
}
|
||||
if !ok || (value == "" && required) {
|
||||
return "", ErrorF("the %s format is incorrect", key)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// GetArrayString 读取字符串数组
|
||||
func GetArrayString(data map[string]interface{}, key string) ([]string, error) {
|
||||
value := []string{}
|
||||
|
||||
if data[key] == nil {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
if v, ok := data[key].(string); ok {
|
||||
return []string{v}, nil
|
||||
}
|
||||
|
||||
value, ok := data[key].([]string)
|
||||
if !ok {
|
||||
if anys, isok := data[key].([]interface{}); isok {
|
||||
ok = isok
|
||||
for _, any := range anys {
|
||||
value = append(value, fmt.Sprintf("%v", any))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if !ok {
|
||||
if anys, isok := data[key].([][]byte); isok {
|
||||
ok = isok
|
||||
for _, any := range anys {
|
||||
value = append(value, string(any))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return nil, ErrorF("the %s format is incorrect", key)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// ErrorF 返回错误数据对象
|
||||
func ErrorF(format string, data ...interface{}) error {
|
||||
values := []interface{}{}
|
||||
for _, value := range data {
|
||||
v, _ := jsoniter.Marshal(value)
|
||||
values = append(values, v)
|
||||
}
|
||||
return fmt.Errorf(format, values...)
|
||||
}
|
||||
102
imports/column_test.go
Normal file
102
imports/column_test.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package imports
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var data = map[string][]byte{
|
||||
"normal": []byte(`{
|
||||
"label": "订单号",
|
||||
"name": "order_sn",
|
||||
"match": ["订单号", "订单", "order_sn", "id"],
|
||||
"rules": ["scripts.rules.order_sn"],
|
||||
"primary": true
|
||||
}`),
|
||||
"object": []byte(`{
|
||||
"label": "性别",
|
||||
"name": "user.sex",
|
||||
"match": "性别",
|
||||
"rules": ["scripts.rules.FmtUser"],
|
||||
"nullable": true
|
||||
}`),
|
||||
"array": []byte(`{
|
||||
"label": "库存",
|
||||
"name": "stock[*]",
|
||||
"rules": ["scripts.rules.FmtGoods"]
|
||||
}`),
|
||||
"arrayObject": []byte(`{
|
||||
"label": "商品",
|
||||
"name": "skus[*].name",
|
||||
"match": ["商品", "商品名称", "goods", "skus", "sku_id", "goods_id"],
|
||||
"rules": ["scripts.rules.FmtGoods"]
|
||||
}`),
|
||||
"failure": []byte(`{
|
||||
"xx": "商品",
|
||||
"sx": "skus[*].name",
|
||||
"a": ["商品", "商品名称", "goods", "skus", "sku_id", "goods_id"],
|
||||
"b": ["scripts.rules.FmtGoods"]
|
||||
}`),
|
||||
}
|
||||
|
||||
func TestUnmarshalJSON(t *testing.T) {
|
||||
var normal Column
|
||||
err := jsoniter.Unmarshal(data["normal"], &normal)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "订单号", normal.Label)
|
||||
assert.Equal(t, "order_sn", normal.Name)
|
||||
assert.Equal(t, "", normal.Key)
|
||||
assert.Equal(t, []string{"订单号", "订单", "order_sn", "id"}, normal.Match)
|
||||
assert.Equal(t, []string{"scripts.rules.order_sn"}, normal.Rules)
|
||||
assert.Equal(t, false, normal.Nullable)
|
||||
assert.Equal(t, true, normal.Primary)
|
||||
assert.Equal(t, false, normal.IsArray)
|
||||
assert.Equal(t, false, normal.IsObject)
|
||||
|
||||
var object Column
|
||||
err = jsoniter.Unmarshal(data["object"], &object)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "性别", object.Label)
|
||||
assert.Equal(t, "user", object.Name)
|
||||
assert.Equal(t, "sex", object.Key)
|
||||
assert.Equal(t, []string{"性别"}, object.Match)
|
||||
assert.Equal(t, []string{"scripts.rules.FmtUser"}, object.Rules)
|
||||
assert.Equal(t, true, object.Nullable)
|
||||
assert.Equal(t, false, object.IsArray)
|
||||
assert.Equal(t, true, object.IsObject)
|
||||
assert.Equal(t, false, object.Primary)
|
||||
|
||||
var array Column
|
||||
err = jsoniter.Unmarshal(data["array"], &array)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "库存", array.Label)
|
||||
assert.Equal(t, "stock", array.Name)
|
||||
assert.Equal(t, "", array.Key)
|
||||
assert.Equal(t, []string{}, array.Match)
|
||||
assert.Equal(t, []string{"scripts.rules.FmtGoods"}, array.Rules)
|
||||
assert.Equal(t, false, array.Nullable)
|
||||
assert.Equal(t, true, array.IsArray)
|
||||
assert.Equal(t, false, array.IsObject)
|
||||
assert.Equal(t, false, array.Primary)
|
||||
|
||||
var arrayObject Column
|
||||
err = jsoniter.Unmarshal(data["arrayObject"], &arrayObject)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "商品", arrayObject.Label)
|
||||
assert.Equal(t, "skus", arrayObject.Name)
|
||||
assert.Equal(t, "name", arrayObject.Key)
|
||||
assert.Equal(t, []string{"商品", "商品名称", "goods", "skus", "sku_id", "goods_id"}, arrayObject.Match)
|
||||
assert.Equal(t, []string{"scripts.rules.FmtGoods"}, arrayObject.Rules)
|
||||
assert.Equal(t, false, arrayObject.Nullable)
|
||||
assert.Equal(t, true, arrayObject.IsArray)
|
||||
assert.Equal(t, true, arrayObject.IsObject)
|
||||
assert.Equal(t, false, arrayObject.Primary)
|
||||
|
||||
var failure Column
|
||||
err = jsoniter.Unmarshal(data["failure"], &failure)
|
||||
assert.NotNil(t, err)
|
||||
assert.Contains(t, err.Error(), `"label" format is incorrect`)
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
package imports
|
||||
|
||||
import "github.com/yaoapp/gou"
|
||||
|
||||
// PreviewAuto 一直显示
|
||||
const PreviewAuto = "auto"
|
||||
|
||||
|
|
@ -13,19 +11,20 @@ const PreviewNever = "never"
|
|||
|
||||
// Imports 数据导入
|
||||
type Imports struct {
|
||||
Title string `json:"title,omitempty"` // 导入名称
|
||||
Process *gou.Process `json:"process"` // 处理器名称
|
||||
Columns []Column `json:"columns"` // 字段列表
|
||||
Option Option `json:"option,omitempty"` // 导入配置项
|
||||
Title string `json:"title,omitempty"` // 导入名称
|
||||
Process string `json:"process"` // 处理器名称
|
||||
Columns []Column `json:"columns"` // 字段列表
|
||||
Option Option `json:"option,omitempty"` // 导入配置项
|
||||
}
|
||||
|
||||
// Column 导入字段定义
|
||||
type Column struct {
|
||||
Label string `json:"label"` // 字段标签
|
||||
Name string `json:"name"` // 字段名称
|
||||
Match []string `json:"match,omitempty"` // 匹配建议
|
||||
Rules []gou.Process `json:"rules,omitempty"` // 清洗规则定义
|
||||
Nullable bool `json:"nullable,omitempty"` // 是否可以为空
|
||||
Label string `json:"label"` // 字段标签
|
||||
Name string `json:"name"` // 字段名称
|
||||
Match []string `json:"match,omitempty"` // 匹配建议
|
||||
Rules []string `json:"rules,omitempty"` // 清洗规则定义
|
||||
Nullable bool `json:"nullable,omitempty"` // 是否可以为空
|
||||
Primary bool `json:"primary,omitempty"` // 是否为主键
|
||||
|
||||
Key string // 字段键名 Object Only
|
||||
IsArray bool // 字段是否为 Array
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package share
|
||||
|
||||
// VERSION 版本号
|
||||
const VERSION = "0.9.28"
|
||||
const VERSION = "0.9.29"
|
||||
|
||||
// DOMAIN 许可域(废弃)
|
||||
const DOMAIN = "*.iqka.com"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue