导表工具支持前后端导出

This commit is contained in:
kercylan98 2023-05-17 20:14:23 +08:00
parent 78e8d18b24
commit 54a000c7d3
3 changed files with 228 additions and 119 deletions

View File

@ -1,18 +1,15 @@
package main package configxport
import ( import (
"fmt" "fmt"
"github.com/kercylan98/minotaur/planner/configexport/internal" "github.com/kercylan98/minotaur/planner/configexport/internal"
"github.com/kercylan98/minotaur/utils/file" "github.com/kercylan98/minotaur/utils/file"
"github.com/kercylan98/minotaur/utils/log"
"github.com/kercylan98/minotaur/utils/str" "github.com/kercylan98/minotaur/utils/str"
"github.com/tealeg/xlsx" "github.com/tealeg/xlsx"
"go.uber.org/zap"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime/debug" "strings"
"sync"
) )
func New(xlsxPath string) *ConfigExport { func New(xlsxPath string) *ConfigExport {
@ -22,7 +19,9 @@ func New(xlsxPath string) *ConfigExport {
panic(err) panic(err)
} }
for i := 0; i < len(xlsxFile.Sheets); i++ { for i := 0; i < len(xlsxFile.Sheets); i++ {
ce.configs = append(ce.configs, internal.NewConfig(xlsxFile.Sheets[i])) if config := internal.NewConfig(xlsxFile.Sheets[i]); config != nil {
ce.configs = append(ce.configs, config)
}
} }
return ce return ce
} }
@ -33,31 +32,14 @@ type ConfigExport struct {
} }
func (slf *ConfigExport) ExportJSON(outputDir string) { func (slf *ConfigExport) ExportJSON(outputDir string) {
var errors []func()
var wait sync.WaitGroup
for _, config := range slf.configs { for _, config := range slf.configs {
config := config config := config
go func() { if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.json", config.GetName())), config.GetJSON()); err != nil {
wait.Add(1) panic(err)
defer func() { }
if err := recover(); err != nil { if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.client.json", config.GetName())), config.GetJSONC()); err != nil {
errors = append(errors, func() { panic(err)
log.Error("导出失败", zap.String("名称", slf.xlsxPath), zap.String("Sheet", config.GetName()), zap.Any("err", err)) }
fmt.Println(debug.Stack())
})
}
}()
if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.json", config.GetName())), config.GetJSON()); err != nil {
panic(err)
}
wait.Done()
}()
}
wait.Wait()
for _, f := range errors {
f()
} }
} }
@ -69,13 +51,21 @@ func (slf *ConfigExport) ExportGo(packageName string, outputDir string) {
for _, config := range slf.configs { for _, config := range slf.configs {
v := config.GetVariable() v := config.GetVariable()
vars += fmt.Sprintf("var %s %s\nvar _%sReady %s\n", str.FirstUpper(config.GetName()), v, str.FirstUpper(config.GetName()), v) vars += fmt.Sprintf("var %s %s\nvar _%sReady %s\n", str.FirstUpper(config.GetName()), v, str.FirstUpper(config.GetName()), v)
varsMake += fmt.Sprintf("_%sReady = make(%s)"+` if config.GetIndexCount() == 0 {
varsMake += fmt.Sprintf("_%sReady = new(%s)"+`
if err := handle("%s.json", &_%sReady); err != nil {
panic(err)
}
`, str.FirstUpper(config.GetName()), strings.TrimPrefix(v, "*"), str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName()))
} else {
varsMake += fmt.Sprintf("_%sReady = make(%s)"+`
if err := handle("%s.json", &_%sReady); err != nil { if err := handle("%s.json", &_%sReady); err != nil {
panic(err) panic(err)
} }
`, str.FirstUpper(config.GetName()), v, str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName())) `, str.FirstUpper(config.GetName()), v, str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName()))
}
types += fmt.Sprintf("%s\n", config.GetStruct()) types += fmt.Sprintf("%s\n", config.GetStruct())
varsReplace += fmt.Sprintf("%s = _%sReady", str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName())) varsReplace += fmt.Sprintf("%s = _%sReady\n", str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName()))
} }
_ = os.MkdirAll(outputDir, 0666) _ = os.MkdirAll(outputDir, 0666)

View File

@ -14,105 +14,186 @@ func NewConfig(sheet *xlsx.Sheet) *Config {
Sheet: sheet, Sheet: sheet,
} }
var ( if len(config.Sheet.Rows) < 2 || len(config.Sheet.Rows[1].Cells) < 2 {
skipField = make(map[int]bool) return nil
describeLine = config.Sheet.Rows[3]
nameLine = config.Sheet.Rows[4]
typeLine = config.Sheet.Rows[5]
exportParamLine = config.Sheet.Rows[6]
)
// 分析数据
{
for i := 1; i < len(describeLine.Cells); i++ {
describe := strings.TrimSpace(nameLine.Cells[i].String())
if strings.HasPrefix(describe, "#") {
skipField[i] = true
continue
}
typ := strings.TrimSpace(typeLine.Cells[i].String())
if strings.HasPrefix(typ, "#") || len(typ) == 0 {
skipField[i] = true
continue
}
exportParam := strings.TrimSpace(exportParamLine.Cells[i].String())
if strings.HasPrefix(exportParam, "#") || len(exportParam) == 0 {
skipField[i] = true
continue
}
}
if len(nameLine.Cells)-1-len(skipField) < config.GetIndexCount() {
panic(errors.New("index count must greater or equal to field count"))
}
} }
config.skipField = skipField if config.GetIndexCount() > 0 && len(config.Sheet.Rows) < 7 {
config.describeLine = describeLine return nil
config.nameLine = nameLine }
config.typeLine = typeLine
config.exportParamLine = exportParamLine
// 整理数据
var (
dataLine = make([]map[any]any, len(config.Sheet.Rows))
)
for i := 1; i < len(config.describeLine.Cells); i++ {
if skipField[i] {
continue
}
if config.GetIndexCount() > 0 {
var ( var (
//describe = strings.TrimSpace(describeLine.Cells[i].String()) skipField = make(map[int]bool)
name = strings.TrimSpace(nameLine.Cells[i].String()) describeLine = config.Sheet.Rows[3]
//typ = strings.TrimSpace(typeLine.Cells[i].String()) nameLine = config.Sheet.Rows[4]
//exportParam = strings.TrimSpace(exportParamLine.Cells[i].String()) typeLine = config.Sheet.Rows[5]
exportParamLine = config.Sheet.Rows[6]
) )
// 分析数据
for row := 7; row < len(config.Sheet.Rows); row++ { {
//value := slf.Sheet.Rows[row].Cells[i].String() for i := 1; i < len(describeLine.Cells); i++ {
var value = getValueWithType(typeLine.Cells[i].String(), config.Sheet.Rows[row].Cells[i].String()) describe := strings.TrimSpace(nameLine.Cells[i].String())
if strings.HasPrefix(describe, "#") {
line := dataLine[row] skipField[i] = true
if line == nil { continue
line = map[any]any{} }
dataLine[row] = line typ := strings.TrimSpace(typeLine.Cells[i].String())
if strings.HasPrefix(typ, "#") || len(typ) == 0 {
skipField[i] = true
continue
}
exportParam := strings.TrimSpace(exportParamLine.Cells[i].String())
if strings.HasPrefix(exportParam, "#") || len(exportParam) == 0 {
skipField[i] = true
continue
}
}
if len(nameLine.Cells)-1-len(skipField) < config.GetIndexCount() {
panic(errors.New("index count must greater or equal to field count"))
} }
line[name] = value
} }
}
// 索引 config.skipField = skipField
var dataSource = make(map[any]any) config.describeLine = describeLine
var data = dataSource config.nameLine = nameLine
var index = config.GetIndexCount() config.typeLine = typeLine
var currentIndex = 0 config.exportParamLine = exportParamLine
for row := 7; row < len(config.Sheet.Rows); row++ {
for i, cell := range config.Sheet.Rows[row].Cells { // 整理数据
if i == 0 || skipField[i] { var (
dataLine = make([]map[any]any, len(config.Sheet.Rows))
dataLineC = make([]map[any]any, len(config.Sheet.Rows))
)
for i := 1; i < len(config.describeLine.Cells); i++ {
if skipField[i] {
continue continue
} }
var value = getValueWithType(typeLine.Cells[i].String(), cell.String())
if currentIndex < index { var (
currentIndex++ //describe = strings.TrimSpace(describeLine.Cells[i].String())
m, exist := data[value] name = strings.TrimSpace(nameLine.Cells[i].String())
if !exist { //typ = strings.TrimSpace(typeLine.Cells[i].String())
if currentIndex == index { exportParam = strings.TrimSpace(exportParamLine.Cells[i].String())
data[value] = dataLine[row] )
} else {
m = map[any]any{} for row := 7; row < len(config.Sheet.Rows); row++ {
data[value] = m //value := slf.Sheet.Rows[row].Cells[i].String()
var value = getValueWithType(typeLine.Cells[i].String(), config.Sheet.Rows[row].Cells[i].String())
var needC, needS bool
switch strings.ToLower(exportParam) {
case "c":
needC = true
case "s":
needS = true
case "sc", "cs":
needS = true
needC = true
}
if needC {
line := dataLineC[row]
if line == nil {
line = map[any]any{}
dataLineC[row] = line
}
line[name] = value
}
if needS {
line := dataLine[row]
if line == nil {
line = map[any]any{}
dataLine[row] = line
}
line[name] = value
}
}
}
// 索引
var dataSource = make(map[any]any)
var data = dataSource
var dataSourceC = make(map[any]any)
var dataC = dataSourceC
var index = config.GetIndexCount()
var currentIndex = 0
for row := 7; row < len(config.Sheet.Rows); row++ {
for i, cell := range config.Sheet.Rows[row].Cells {
if i == 0 {
if strings.HasPrefix(typeLine.Cells[i].String(), "#") {
break
}
continue
}
if skipField[i] {
continue
}
var value = getValueWithType(typeLine.Cells[i].String(), cell.String())
if currentIndex < index {
currentIndex++
m, exist := data[value]
if !exist {
if currentIndex == index {
data[value] = dataLine[row]
} else {
m = map[any]any{}
data[value] = m
}
}
if currentIndex < index {
data = m.(map[any]any)
}
m, exist = dataC[value]
if !exist {
if currentIndex == index {
dataC[value] = dataLineC[row]
} else {
m = map[any]any{}
dataC[value] = m
}
}
if currentIndex < index {
dataC = m.(map[any]any)
} }
} }
if currentIndex < index { }
data = m.(map[any]any) data = dataSource
} dataC = dataSourceC
currentIndex = 0
}
config.data = dataSource
config.dataC = dataSourceC
} else {
config.data = map[any]any{}
config.dataC = map[any]any{}
for i := 4; i < len(config.Rows); i++ {
row := config.Sheet.Rows[i]
desc := row.Cells[0].String()
if strings.HasPrefix(desc, "#") {
continue
}
name := row.Cells[1].String()
typ := row.Cells[2].String()
exportParam := row.Cells[3].String()
value := row.Cells[4].String()
switch strings.ToLower(exportParam) {
case "c":
config.dataC[name] = getValueWithType(typ, value)
case "s":
config.data[name] = getValueWithType(typ, value)
case "sc", "cs":
config.dataC[name] = getValueWithType(typ, value)
config.data[name] = getValueWithType(typ, value)
} }
} }
data = dataSource
currentIndex = 0
} }
config.data = dataSource
config.dataLine = dataLine[len(dataLine)-1]
return config return config
} }
@ -124,7 +205,7 @@ type Config struct {
typeLine *xlsx.Row typeLine *xlsx.Row
exportParamLine *xlsx.Row exportParamLine *xlsx.Row
data map[any]any data map[any]any
dataLine map[any]any dataC map[any]any
} }
// GetDisplayName 获取显示名称 // GetDisplayName 获取显示名称
@ -134,7 +215,7 @@ func (slf *Config) GetDisplayName() string {
// GetName 获取配置名称 // GetName 获取配置名称
func (slf *Config) GetName() string { func (slf *Config) GetName() string {
return slf.Sheet.Rows[0].Cells[1].String() return str.FirstUpper(slf.Sheet.Rows[0].Cells[1].String())
} }
// GetIndexCount 获取索引数量 // GetIndexCount 获取索引数量
@ -160,8 +241,20 @@ func (slf *Config) GetJSON() []byte {
return bytes return bytes
} }
// GetJSONC 获取JSON类型数据
func (slf *Config) GetJSONC() []byte {
bytes, err := jsonIter.MarshalIndent(slf.dataC, "", " ")
if err != nil {
panic(err)
}
return bytes
}
func (slf *Config) GetVariable() string { func (slf *Config) GetVariable() string {
var index = slf.GetIndexCount() var index = slf.GetIndexCount()
if index <= 0 {
return fmt.Sprintf("*_%s", slf.GetName())
}
var mapStr = "map[%s]%s" var mapStr = "map[%s]%s"
for i := 1; i < len(slf.typeLine.Cells); i++ { for i := 1; i < len(slf.typeLine.Cells); i++ {
if slf.skipField[i] { if slf.skipField[i] {
@ -185,15 +278,41 @@ func (slf *Config) GetVariable() string {
func (slf *Config) GetStruct() string { func (slf *Config) GetStruct() string {
var result string var result string
if slf.GetIndexCount() <= 0 {
for i := 4; i < len(slf.Rows); i++ {
row := slf.Sheet.Rows[i]
desc := row.Cells[0].String()
if strings.HasPrefix(desc, "#") {
continue
}
name := row.Cells[1].String()
typ := row.Cells[2].String()
exportParam := row.Cells[3].String()
switch strings.ToLower(exportParam) {
case "s", "sc", "cs":
result += fmt.Sprintf("%s %s\n", str.FirstUpper(name), slf.GetType(typ))
case "c":
continue
}
}
return fmt.Sprintf("type _%s struct{\n%s}", slf.GetName(), result)
}
for i := 1; i < len(slf.typeLine.Cells); i++ { for i := 1; i < len(slf.typeLine.Cells); i++ {
if slf.skipField[i] { if slf.skipField[i] {
continue continue
} }
typ := slf.typeLine.Cells[i].String() typ := slf.typeLine.Cells[i].String()
name := slf.nameLine.Cells[i].String() name := slf.nameLine.Cells[i].String()
exportParam := slf.exportParamLine.Cells[i].String()
name = str.FirstUpper(name) switch strings.ToLower(exportParam) {
result += fmt.Sprintf("%s %s\n", name, slf.GetType(typ)) case "s", "sc", "cs":
name = str.FirstUpper(name)
result += fmt.Sprintf("%s %s\n", name, slf.GetType(typ))
case "c":
continue
}
} }
return fmt.Sprintf("type _%s struct{\n%s}", str.FirstUpper(slf.GetName()), result) return fmt.Sprintf("type _%s struct{\n%s}", str.FirstUpper(slf.GetName()), result)
} }