diff --git a/importer/column.go b/importer/column.go index 2a960db2..30942755 100644 --- a/importer/column.go +++ b/importer/column.go @@ -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] diff --git a/importer/importer.go b/importer/importer.go index dd0a9b0d..bf917c6c 100644 --- a/importer/importer.go +++ b/importer/importer.go @@ -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 +} diff --git a/importer/importer_test.go b/importer/importer_test.go index ab08d659..82b67d1d 100644 --- a/importer/importer_test.go +++ b/importer/importer_test.go @@ -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) +} diff --git a/importer/process.go b/importer/process.go index 7c8936a9..c68207f4 100644 --- a/importer/process.go +++ b/importer/process.go @@ -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 diff --git a/importer/types.go b/importer/types.go index efb9f4f8..434aa1a1 100644 --- a/importer/types.go +++ b/importer/types.go @@ -11,16 +11,18 @@ const PreviewNever = "never" // Importer 数据导入器 type Importer struct { - Title string `json:"title,omitempty"` // 导入名称 - Process string `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"` // 导入配置项 + 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"` // 是否可以为空 diff --git a/tests/imports/order.imp.json b/tests/imports/order.imp.json index 7c561c3d..b3bb64bf 100644 --- a/tests/imports/order.imp.json +++ b/tests/imports/order.imp.json @@ -72,5 +72,11 @@ "logging": "error", "mappingPreview": "auto", "dataPreview": "auto" + }, + "rules": { + "scripts.rules.order_sn": "订单号验证", + "scripts.rules.mobile": "手机号验证", + "scripts.rules.FmtUser": "用户数据匹配验证", + "scripts.rules.FmtGoods": "商品数据匹配验证" } } diff --git a/xiang/apis/import.http.json b/xiang/apis/import.http.json index 035b52ef..a420d10d 100644 --- a/xiang/apis/import.http.json +++ b/xiang/apis/import.http.json @@ -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"