+ 映射表配置 API
This commit is contained in:
parent
633fe903fe
commit
6b1f3bdf4a
7 changed files with 134 additions and 16 deletions
|
|
@ -67,16 +67,9 @@ func ColumnOf(data map[string]interface{}) (*Column, error) {
|
||||||
|
|
||||||
// ToMap 转换为映射表
|
// ToMap 转换为映射表
|
||||||
func (column Column) ToMap() map[string]interface{} {
|
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{}{
|
data := map[string]interface{}{
|
||||||
"name": column.Name,
|
"name": column.Field,
|
||||||
"label": column.Label,
|
"label": column.Label,
|
||||||
"match": column.Match,
|
"match": column.Match,
|
||||||
"rules": column.Rules,
|
"rules": column.Rules,
|
||||||
|
|
@ -133,6 +126,8 @@ func (column *Column) setName(data map[string]interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
column.Field = name // 留存原始数值
|
||||||
|
|
||||||
if strings.Contains(name, "[*]") { // Array
|
if strings.Contains(name, "[*]") { // Array
|
||||||
namer := strings.Split(name, "[*]")
|
namer := strings.Split(name, "[*]")
|
||||||
name = namer[0]
|
name = namer[0]
|
||||||
|
|
|
||||||
|
|
@ -233,8 +233,71 @@ func (imp *Importer) DataSetting(src from.Source) []map[string]interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MappingSetting 预览映射数据表格配置
|
// MappingSetting 预览映射数据表格配置
|
||||||
func (imp *Importer) MappingSetting(src from.Source) []map[string]interface{} {
|
func (imp *Importer) MappingSetting(src from.Source) map[string]interface{} {
|
||||||
return nil
|
|
||||||
|
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 文件结构指纹
|
// Fingerprint 文件结构指纹
|
||||||
|
|
@ -333,3 +396,39 @@ func (imp *Importer) getColumns() map[string]*Column {
|
||||||
}
|
}
|
||||||
return columns
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,13 @@ func ProcessMapping(process *gou.Process) interface{} {
|
||||||
// ProcessMappingSetting xiang.import.MappingSetting
|
// ProcessMappingSetting xiang.import.MappingSetting
|
||||||
// 字段映射表格配置
|
// 字段映射表格配置
|
||||||
func ProcessMappingSetting(process *gou.Process) interface{} {
|
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
|
// ProcessRules xiang.import.Rules
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,18 @@ const PreviewNever = "never"
|
||||||
|
|
||||||
// Importer 数据导入器
|
// Importer 数据导入器
|
||||||
type Importer struct {
|
type Importer struct {
|
||||||
Title string `json:"title,omitempty"` // 导入名称
|
Title string `json:"title,omitempty"` // 导入名称
|
||||||
Process string `json:"process"` // 处理器名称
|
Process string `json:"process"` // 处理器名称
|
||||||
Columns []Column `json:"columns"` // 字段列表
|
Columns []Column `json:"columns"` // 字段列表
|
||||||
Option Option `json:"option,omitempty"` // 导入配置项
|
Option Option `json:"option,omitempty"` // 导入配置项
|
||||||
|
Rules map[string]string `json:"rules,omitempty"` // 许可导入规则
|
||||||
}
|
}
|
||||||
|
|
||||||
// Column 导入字段定义
|
// Column 导入字段定义
|
||||||
type Column struct {
|
type Column struct {
|
||||||
Label string `json:"label"` // 字段标签
|
Label string `json:"label"` // 字段标签
|
||||||
Name string `json:"name"` // 字段名称
|
Name string `json:"name"` // 字段名称
|
||||||
|
Field string `json:"field"` // 字段名称(原始值)
|
||||||
Match []string `json:"match,omitempty"` // 匹配建议
|
Match []string `json:"match,omitempty"` // 匹配建议
|
||||||
Rules []string `json:"rules,omitempty"` // 清洗规则定义
|
Rules []string `json:"rules,omitempty"` // 清洗规则定义
|
||||||
Nullable bool `json:"nullable,omitempty"` // 是否可以为空
|
Nullable bool `json:"nullable,omitempty"` // 是否可以为空
|
||||||
|
|
|
||||||
|
|
@ -72,5 +72,11 @@
|
||||||
"logging": "error",
|
"logging": "error",
|
||||||
"mappingPreview": "auto",
|
"mappingPreview": "auto",
|
||||||
"dataPreview": "auto"
|
"dataPreview": "auto"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"scripts.rules.order_sn": "订单号验证",
|
||||||
|
"scripts.rules.mobile": "手机号验证",
|
||||||
|
"scripts.rules.FmtUser": "用户数据匹配验证",
|
||||||
|
"scripts.rules.FmtGoods": "商品数据匹配验证"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
"path": "/:name/mapping/setting",
|
"path": "/:name/mapping/setting",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"process": "xiang.import.MappingSetting",
|
"process": "xiang.import.MappingSetting",
|
||||||
"in": ["$param.name", ":query"],
|
"in": ["$param.name", "$query.file"],
|
||||||
"out": {
|
"out": {
|
||||||
"status": 200,
|
"status": 200,
|
||||||
"type": "application/json"
|
"type": "application/json"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue