+ 映射表配置 API

This commit is contained in:
Max 2022-01-18 12:26:22 +08:00
parent 633fe903fe
commit 6b1f3bdf4a
7 changed files with 134 additions and 16 deletions

View file

@ -67,16 +67,9 @@ func ColumnOf(data map[string]interface{}) (*Column, error) {
// 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,
"name": column.Field,
"label": column.Label,
"match": column.Match,
"rules": column.Rules,
@ -133,6 +126,8 @@ func (column *Column) setName(data map[string]interface{}) error {
return err
}
column.Field = name // 留存原始数值
if strings.Contains(name, "[*]") { // Array
namer := strings.Split(name, "[*]")
name = namer[0]

View file

@ -233,8 +233,71 @@ func (imp *Importer) DataSetting(src from.Source) []map[string]interface{} {
}
// MappingSetting 预览映射数据表格配置
func (imp *Importer) MappingSetting(src from.Source) []map[string]interface{} {
return nil
func (imp *Importer) MappingSetting(src from.Source) map[string]interface{} {
columns := map[string]share.Column{
"关联字段": {
Label: "关联字段",
View: share.Render{
Type: "label",
Props: map[string]interface{}{"value": ":label"},
},
Edit: share.Render{
Type: "select",
Props: map[string]interface{}{"option": imp.getFieldOption(), "value": ":field"},
},
},
"数据源": {
Label: "数据源",
View: share.Render{
Type: "label",
Props: map[string]interface{}{"value": ":name"},
},
Edit: share.Render{
Type: "select",
Props: map[string]interface{}{"option": imp.getSourceOption(src), "value": ":axis"},
},
},
"清洗规则": {
Label: "清洗规则",
View: share.Render{
Type: "tag",
Props: map[string]interface{}{"value": ":rules"},
},
Edit: share.Render{
Type: "select",
Props: map[string]interface{}{"option": imp.getRulesOption(), "value": ":rules"},
},
},
"数据示例": {
Label: "数据示例",
View: share.Render{
Type: "label",
Props: map[string]interface{}{"value": ":value"},
},
},
}
setting := map[string]interface{}{
"columns": columns,
"filters": map[string]interface{}{},
"list": share.Page{
Primary: "field",
Layout: map[string]interface{}{
"columns": []map[string]interface{}{
{"name": "字段"},
{"name": "数据源"},
{"name": "清洗规则"},
{"name": "数据示例"},
},
},
},
"actions": map[string]interface{}{},
"option": map[string]interface{}{
"operation": map[string]interface{}{"hideView": true, "hideEdit": true, "width": 0},
},
"edit": map[string]interface{}{},
}
return setting
}
// Fingerprint 文件结构指纹
@ -333,3 +396,39 @@ func (imp *Importer) getColumns() map[string]*Column {
}
return columns
}
func (imp *Importer) getFieldOption() []map[string]interface{} {
option := []map[string]interface{}{}
for _, col := range imp.Columns {
option = append(option, map[string]interface{}{
"label": col.Label, "value": col.Field,
})
}
return option
}
func (imp *Importer) getSourceOption(src from.Source) []map[string]interface{} {
option := []map[string]interface{}{}
columns := src.Columns()
for _, col := range columns {
option = append(option, map[string]interface{}{
"label": col.Name, "value": col.Axis,
})
}
return option
}
func (imp *Importer) getRulesOption() []map[string]interface{} {
option := []map[string]interface{}{}
keys := []string{}
for key := range imp.Rules {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
option = append(option, map[string]interface{}{
"label": imp.Rules[key], "value": key,
})
}
return option
}

View file

@ -137,3 +137,13 @@ func TestMappingPreviewSimple(t *testing.T) {
}
}
}
func TestMappingSetting(t *testing.T) {
simple := filepath.Join(config.Conf.Root, "imports", "assets", "simple.xlsx")
file := xlsx.Open(simple)
defer file.Close()
imp := Select("order")
setting := imp.MappingSetting(file)
assert.NotNil(t, setting)
}

View file

@ -66,7 +66,13 @@ func ProcessMapping(process *gou.Process) interface{} {
// ProcessMappingSetting xiang.import.MappingSetting
// 字段映射表格配置
func ProcessMappingSetting(process *gou.Process) interface{} {
return nil
process.ValidateArgNums(2)
name := process.ArgsString(0)
imp := Select(name)
filename := process.ArgsString(1)
src := Open(filename)
return imp.MappingSetting(src)
}
// ProcessRules xiang.import.Rules

View file

@ -15,12 +15,14 @@ type Importer struct {
Process string `json:"process"` // 处理器名称
Columns []Column `json:"columns"` // 字段列表
Option Option `json:"option,omitempty"` // 导入配置项
Rules map[string]string `json:"rules,omitempty"` // 许可导入规则
}
// Column 导入字段定义
type Column struct {
Label string `json:"label"` // 字段标签
Name string `json:"name"` // 字段名称
Field string `json:"field"` // 字段名称(原始值)
Match []string `json:"match,omitempty"` // 匹配建议
Rules []string `json:"rules,omitempty"` // 清洗规则定义
Nullable bool `json:"nullable,omitempty"` // 是否可以为空

View file

@ -72,5 +72,11 @@
"logging": "error",
"mappingPreview": "auto",
"dataPreview": "auto"
},
"rules": {
"scripts.rules.order_sn": "订单号验证",
"scripts.rules.mobile": "手机号验证",
"scripts.rules.FmtUser": "用户数据匹配验证",
"scripts.rules.FmtGoods": "商品数据匹配验证"
}
}

View file

@ -55,7 +55,7 @@
"path": "/:name/mapping/setting",
"method": "GET",
"process": "xiang.import.MappingSetting",
"in": ["$param.name", ":query"],
"in": ["$param.name", "$query.file"],
"out": {
"status": 200,
"type": "application/json"