v0.9.29 更新UI

This commit is contained in:
Max 2022-01-14 16:04:47 +08:00
parent b6c65a63f1
commit 64d177fc27
4 changed files with 330 additions and 12 deletions

217
imports/column.go Normal file
View 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
View 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`)
}

View file

@ -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

View file

@ -1,7 +1,7 @@
package share
// VERSION 版本号
const VERSION = "0.9.28"
const VERSION = "0.9.29"
// DOMAIN 许可域(废弃)
const DOMAIN = "*.iqka.com"