导表工具重构

This commit is contained in:
kercylan98 2023-05-18 18:04:46 +08:00
parent 54a000c7d3
commit 335c93f92b
14 changed files with 740 additions and 456 deletions

4
go.mod
View File

@ -18,13 +18,17 @@ require (
require (
github.com/bytedance/sonic v1.8.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.11.2 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jonboulle/clockwork v0.3.0 // indirect

24
go.sum
View File

@ -11,6 +11,9 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -18,6 +21,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f h1:3Z9NjtffvA8Qoh8xjgUpPmyKawJw/mDRcJlR9oPCvqI=
github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
@ -34,6 +45,8 @@ github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyh
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -59,10 +72,13 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
@ -82,6 +98,8 @@ github.com/klauspost/reedsolomon v1.9.9/go.mod h1:O7yFFHiQwDR6b2t63KPUpccPtNdp5A
github.com/klauspost/reedsolomon v1.11.7 h1:9uaHU0slncktTEEg4+7Vl7q7XUNMBUOK4R9gnKhMjAU=
github.com/klauspost/reedsolomon v1.11.7/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -135,6 +153,7 @@ github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -277,6 +296,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211204120058-94396e421777/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -292,6 +312,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
@ -340,12 +361,15 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -1,15 +1,15 @@
package configxport
package configexport
import (
"bytes"
"fmt"
"github.com/kercylan98/minotaur/planner/configexport/internal"
"github.com/kercylan98/minotaur/utils/file"
"github.com/kercylan98/minotaur/utils/str"
"github.com/tealeg/xlsx"
"os"
"os/exec"
"path/filepath"
"strings"
"text/template"
)
func New(xlsxPath string) *ConfigExport {
@ -19,7 +19,9 @@ func New(xlsxPath string) *ConfigExport {
panic(err)
}
for i := 0; i < len(xlsxFile.Sheets); i++ {
if config := internal.NewConfig(xlsxFile.Sheets[i]); config != nil {
if config, err := internal.NewConfig(xlsxFile.Sheets[i]); err != nil {
panic(err)
} else {
ce.configs = append(ce.configs, config)
}
}
@ -31,58 +33,99 @@ type ConfigExport struct {
configs []*internal.Config
}
func (slf *ConfigExport) ExportJSON(outputDir string) {
func (slf *ConfigExport) ExportClient(prefix, outputDir string) {
for _, config := range slf.configs {
config := config
if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.json", config.GetName())), config.GetJSON()); err != nil {
panic(err)
}
if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.client.json", config.GetName())), config.GetJSONC()); err != nil {
if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.%s.json", prefix, config.Name)), config.JsonClient()); err != nil {
panic(err)
}
}
}
func (slf *ConfigExport) ExportGo(packageName string, outputDir string) {
var vars string
var varsMake string
var types string
var varsReplace string
func (slf *ConfigExport) ExportServer(prefix, outputDir string) {
for _, config := range slf.configs {
v := config.GetVariable()
vars += fmt.Sprintf("var %s %s\nvar _%sReady %s\n", str.FirstUpper(config.GetName()), v, str.FirstUpper(config.GetName()), v)
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 {
panic(err)
}
`, str.FirstUpper(config.GetName()), v, str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName()))
config := config
if err := file.WriterFile(filepath.Join(outputDir, fmt.Sprintf("%s.%s.json", prefix, config.Name)), config.JsonServer()); err != nil {
panic(err)
}
types += fmt.Sprintf("%s\n", config.GetStruct())
varsReplace += fmt.Sprintf("%s = _%sReady\n", str.FirstUpper(config.GetName()), str.FirstUpper(config.GetName()))
}
_ = os.MkdirAll(outputDir, 0666)
if err := file.WriterFile(filepath.Join(outputDir, "config.struct.go"), []byte(fmt.Sprintf(internal.TemplateStructGo, packageName, types))); err != nil {
panic(err)
}
if err := file.WriterFile(filepath.Join(outputDir, "config.go"), []byte(fmt.Sprintf(internal.TemplateGo, packageName, vars, varsMake, varsReplace))); err != nil {
panic(err)
}
cmd := exec.Command("gofmt", "-w", filepath.Join(outputDir, "config.struct.go"))
if err := cmd.Run(); err != nil {
fmt.Println(err)
}
cmd = exec.Command("gofmt", "-w", filepath.Join(outputDir, "config.go"))
if err := cmd.Run(); err != nil {
fmt.Println(err)
}
}
func (slf *ConfigExport) ExportGo(outputDir string) {
slf.exportGoConfig(outputDir)
slf.exportGoDefine(outputDir)
}
func (slf *ConfigExport) exportGoConfig(outputDir string) {
var v struct {
Package string
Configs []*internal.Config
}
v.Package = filepath.Base(outputDir)
for _, config := range slf.configs {
v.Configs = append(v.Configs, config)
}
tmpl, err := template.New("struct").Parse(internal.GenerateGoConfigTemplate)
if err != nil {
panic(err)
}
var buf bytes.Buffer
if err = tmpl.Execute(&buf, &v); err != nil {
panic(err)
}
var result string
_ = str.RangeLine(buf.String(), func(index int, line string) error {
if len(strings.TrimSpace(line)) == 0 {
return nil
}
result += fmt.Sprintf("%s\n", strings.ReplaceAll(line, "\t\t", "\t"))
if len(strings.TrimSpace(line)) == 1 {
result += "\n"
}
return nil
})
if err := file.WriterFile(filepath.Join(outputDir, "config.go"), []byte(result)); err != nil {
panic(err)
}
}
func (slf *ConfigExport) exportGoDefine(outputDir string) {
var v struct {
Package string
Configs []*internal.Config
}
v.Package = filepath.Base(outputDir)
for _, config := range slf.configs {
v.Configs = append(v.Configs, config)
}
tmpl, err := template.New("struct").Parse(internal.GenerateGoDefineTemplate)
if err != nil {
panic(err)
}
var buf bytes.Buffer
if err = tmpl.Execute(&buf, &v); err != nil {
panic(err)
}
var result string
_ = str.RangeLine(buf.String(), func(index int, line string) error {
if len(strings.TrimSpace(line)) == 0 {
return nil
}
result += fmt.Sprintf("%s\n", strings.ReplaceAll(line, "\t\t", "\t"))
if len(strings.TrimSpace(line)) == 1 {
result += "\n"
}
return nil
})
if err := file.WriterFile(filepath.Join(outputDir, "config.define.go"), []byte(result)); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,11 @@
package configexport
import "testing"
func TestNew(t *testing.T) {
c := New(`D:\sources\minotaur\planner\configexport\template.xlsx`)
c.ExportGo("./example")
c.ExportClient("client", "./example")
c.ExportServer("server", "./example")
}

View File

@ -1,376 +1,348 @@
package internal
import (
"errors"
"bytes"
"fmt"
jsonIter "github.com/json-iterator/go"
"github.com/kercylan98/minotaur/utils/g2d/matrix"
"github.com/kercylan98/minotaur/utils/str"
"github.com/kercylan98/minotaur/utils/xlsxtool"
"github.com/tealeg/xlsx"
"strconv"
"strings"
"text/template"
)
func NewConfig(sheet *xlsx.Sheet) *Config {
// NewConfig 定位为空将读取Sheet名称
// - 表格中需要严格遵守 描述、名称、类型、导出参数、数据列的顺序
func NewConfig(sheet *xlsx.Sheet) (*Config, error) {
config := &Config{
Sheet: sheet,
ignore: "#",
excludeFields: map[int]bool{0: true},
}
if len(config.Sheet.Rows) < 2 || len(config.Sheet.Rows[1].Cells) < 2 {
return nil
if err := config.initField(sheet); err != nil {
return nil, err
}
if config.GetIndexCount() > 0 && len(config.Sheet.Rows) < 7 {
return nil
}
if config.GetIndexCount() > 0 {
var (
skipField = make(map[int]bool)
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
config.describeLine = describeLine
config.nameLine = nameLine
config.typeLine = typeLine
config.exportParamLine = exportParamLine
// 整理数据
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
}
var (
//describe = strings.TrimSpace(describeLine.Cells[i].String())
name = strings.TrimSpace(nameLine.Cells[i].String())
//typ = strings.TrimSpace(typeLine.Cells[i].String())
exportParam = strings.TrimSpace(exportParamLine.Cells[i].String())
)
for row := 7; row < len(config.Sheet.Rows); row++ {
//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)
}
}
}
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)
}
}
}
return config
return config, nil
}
type Config struct {
*xlsx.Sheet
skipField map[int]bool
describeLine *xlsx.Row
nameLine *xlsx.Row
typeLine *xlsx.Row
exportParamLine *xlsx.Row
data map[any]any
dataC map[any]any
DisplayName string
Name string
Describe string
ExportParam string
IndexCount int
Fields []*Field
matrix *matrix.Matrix[*xlsx.Cell]
excludeFields map[int]bool // 排除的字段
ignore string
horizontal bool
dataStart int
dataServer map[any]any
dataClient map[any]any
}
// GetDisplayName 获取显示名称
func (slf *Config) GetDisplayName() string {
return slf.Name
}
// GetName 获取配置名称
func (slf *Config) GetName() string {
return str.FirstUpper(slf.Sheet.Rows[0].Cells[1].String())
}
// GetIndexCount 获取索引数量
func (slf *Config) GetIndexCount() int {
index, err := slf.Sheet.Rows[1].Cells[1].Int()
if err != nil {
panic(err)
func (slf *Config) initField(sheet *xlsx.Sheet) error {
slf.matrix = xlsxtool.GetSheetMatrix(sheet)
var displayName *Position
name, indexCount := NewPosition(1, 0), NewPosition(1, 1)
if displayName == nil {
slf.DisplayName = sheet.Name
} else {
if value := slf.matrix.Get(displayName.X, displayName.Y); value == nil {
return ErrReadConfigFailedWithDisplayName
} else {
slf.DisplayName = strings.TrimSpace(value.String())
}
}
return index
}
// GetData 获取数据
func (slf *Config) GetData() map[any]any {
return slf.data
}
// GetJSON 获取JSON类型数据
func (slf *Config) GetJSON() []byte {
bytes, err := jsonIter.MarshalIndent(slf.GetData(), "", " ")
if err != nil {
panic(err)
if name == nil {
slf.Name = sheet.Name
} else {
if value := slf.matrix.Get(name.X, name.Y); value == nil {
return ErrReadConfigFailedWithName
} else {
slf.Name = str.FirstUpper(strings.TrimSpace(value.String()))
}
}
return bytes
if indexCount == nil {
slf.IndexCount, _ = strconv.Atoi(sheet.Name)
} else {
if value := slf.matrix.Get(indexCount.X, indexCount.Y); value == nil {
return ErrReadConfigFailedWithIndexCount
} else {
indexCount, err := value.Int()
if err != nil {
return err
}
if indexCount < 0 {
return ErrReadConfigFailedWithIndexCountLessThanZero
}
slf.IndexCount = indexCount
}
}
var (
describeStart int
horizontal bool
fields = make(map[string]bool)
dx, dy, nx, ny, tx, ty, ex, ey int
)
horizontal = slf.IndexCount > 0
slf.horizontal = horizontal
if horizontal {
describeStart = 3
dy = describeStart
ny = dy + 1
ty = ny + 1
ey = ty + 1
slf.dataStart = ey + 1
} else {
delete(slf.excludeFields, 0)
describeStart = 4
dy = describeStart
ny = dy
ty = dy
ey = dy
nx = dx + 1
tx = nx + 1
ex = tx + 1
slf.dataStart = ey + 1
}
var index = slf.IndexCount
for {
var (
describe, fieldName, fieldType, exportParam string
)
if value := slf.matrix.Get(dx, dy); value == nil {
return ErrReadConfigFailedWithFieldPosition
} else {
describe = value.String()
}
if value := slf.matrix.Get(nx, ny); value == nil {
return ErrReadConfigFailedWithFieldPosition
} else {
fieldName = str.FirstUpper(strings.TrimSpace(value.String()))
}
if value := slf.matrix.Get(tx, ty); value == nil {
return ErrReadConfigFailedWithFieldPosition
} else {
fieldType = strings.TrimSpace(value.String())
}
if value := slf.matrix.Get(ex, ey); value == nil {
return ErrReadConfigFailedWithFieldPosition
} else {
exportParam = strings.ToLower(strings.TrimSpace(value.String()))
}
var field = NewField(slf.Name, fieldName, fieldType)
field.Describe = describe
field.ExportParam = exportParam
switch field.ExportParam {
case "s", "sc", "cs":
field.Server = true
}
if horizontal {
dx++
nx++
tx++
ex++
} else {
dy++
ny++
ty++
ey++
}
field.Ignore = slf.excludeFields[len(slf.Fields)]
if !field.Ignore {
if strings.HasPrefix(field.Describe, slf.ignore) {
field.Ignore = true
} else if strings.HasPrefix(field.Name, slf.ignore) {
field.Ignore = true
} else if strings.HasPrefix(field.Type, slf.ignore) {
field.Ignore = true
} else if strings.HasPrefix(field.ExportParam, slf.ignore) {
field.Ignore = true
}
}
if !field.Ignore {
switch exportParam {
case "s", "c", "sc", "cs":
default:
return ErrReadConfigFailedWithExportParamException
}
}
if fields[field.Name] && !field.Ignore {
return ErrReadConfigFailedWithNameDuplicate
}
if index > 0 && !field.Ignore {
if _, exist := basicTypeName[field.Type]; !exist {
return ErrReadConfigFailedWithIndexTypeException
}
index--
}
fields[field.Name] = true
slf.Fields = append(slf.Fields, field)
if horizontal {
if dx >= slf.matrix.GetWidth() {
break
}
} else {
if dy >= slf.matrix.GetHeight() {
break
}
}
}
return slf.initData()
}
// GetJSONC 获取JSON类型数据
func (slf *Config) GetJSONC() []byte {
bytes, err := jsonIter.MarshalIndent(slf.dataC, "", " ")
if err != nil {
panic(err)
func (slf *Config) initData() error {
var x, y int
if slf.horizontal {
y = slf.dataStart
} else {
x = 4
y = 4
}
return bytes
var dataSourceServer = make(map[any]any)
var dataSourceClient = make(map[any]any)
for {
var dataServer = dataSourceServer
var dataClient = dataSourceClient
var currentIndex = 0
var lineServer = map[any]any{}
var lineClient = map[any]any{}
for i := 0; i < len(slf.Fields); i++ {
if slf.excludeFields[i] {
continue
}
field := slf.Fields[i]
var value any
if slf.horizontal {
value = getValueWithType(field.SourceType, slf.matrix.Get(x+i, y).String())
} else {
value = getValueWithType(field.SourceType, slf.matrix.Get(x, y+i).String())
}
switch field.ExportParam {
case "s":
lineServer[field.Name] = value
case "c":
lineClient[field.Name] = value
case "sc", "cs":
lineServer[field.Name] = value
lineClient[field.Name] = value
}
if currentIndex < slf.IndexCount {
currentIndex++
m, exist := dataServer[value]
if !exist {
if currentIndex == slf.IndexCount {
dataServer[value] = lineServer
} else {
m = map[any]any{}
dataServer[value] = m
}
}
if currentIndex < slf.IndexCount {
dataServer = m.(map[any]any)
}
m, exist = dataClient[value]
if !exist {
if currentIndex == slf.IndexCount {
dataClient[value] = lineClient
} else {
m = map[any]any{}
dataClient[value] = m
}
}
if currentIndex < slf.IndexCount {
dataClient = m.(map[any]any)
}
}
}
if slf.horizontal {
y++
if y >= slf.matrix.GetHeight() {
break
}
} else {
x++
if x >= slf.matrix.GetWidth() {
slf.dataServer = lineServer
slf.dataClient = lineClient
break
}
}
}
if slf.horizontal {
slf.dataServer = dataSourceServer
slf.dataClient = dataSourceClient
}
return nil
}
func (slf *Config) String() string {
tmpl, err := template.New("struct").Parse(generateConfigTemplate)
if err != nil {
return ""
}
var buf bytes.Buffer
if err = tmpl.Execute(&buf, slf); err != nil {
return ""
}
var result string
_ = str.RangeLine(buf.String(), func(index int, line string) error {
if len(strings.TrimSpace(line)) == 0 {
return nil
}
result += fmt.Sprintf("%s\n", strings.ReplaceAll(line, "\t\t", "\t"))
if len(strings.TrimSpace(line)) == 1 {
result += "\n"
}
return nil
})
return result
}
func (slf *Config) JsonServer() []byte {
d, _ := jsonIter.MarshalIndent(slf.dataServer, "", " ")
return d
}
func (slf *Config) JsonClient() []byte {
d, _ := jsonIter.MarshalIndent(slf.dataClient, "", " ")
return d
}
func (slf *Config) GetVariable() string {
var index = slf.GetIndexCount()
if index <= 0 {
return fmt.Sprintf("*_%s", slf.GetName())
}
var mapStr = "map[%s]%s"
for i := 1; i < len(slf.typeLine.Cells); i++ {
if slf.skipField[i] {
continue
}
typ := slf.typeLine.Cells[i].String()
if index > 0 {
index--
if index == 0 {
mapStr = fmt.Sprintf(mapStr, typ, "%s")
} else {
mapStr = fmt.Sprintf(mapStr, typ, "map[%s]%s")
}
} else {
mapStr = fmt.Sprintf(mapStr, "*_"+str.FirstUpper(slf.GetName()))
break
}
}
return fmt.Sprintf("%s", mapStr)
}
func (slf *Config) GetStruct() 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, "#") {
var count int
if slf.IndexCount > 0 {
for _, field := range slf.Fields {
if field.Ignore {
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
result += fmt.Sprintf("map[%s]", field.Type)
count++
if count >= slf.IndexCount {
break
}
}
return fmt.Sprintf("type _%s struct{\n%s}", slf.GetName(), result)
}
for i := 1; i < len(slf.typeLine.Cells); i++ {
if slf.skipField[i] {
continue
}
typ := slf.typeLine.Cells[i].String()
name := slf.nameLine.Cells[i].String()
exportParam := slf.exportParamLine.Cells[i].String()
switch strings.ToLower(exportParam) {
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)
}
func (slf *Config) GetType(fieldType string) string {
if name, exist := basicTypeName[fieldType]; exist {
return name
} else if strings.HasPrefix(fieldType, "[]") {
s := strings.TrimPrefix(fieldType, "[]")
if name, exist := basicTypeName[s]; exist {
return fmt.Sprintf("map[int]%s", name)
} else {
return slf.GetType(s)
}
}
var s = strings.TrimSuffix(strings.TrimPrefix(fieldType, "{"), "}")
var fields []string
var field string
var leftBrackets []int
for i, c := range s {
switch c {
case ',':
if len(leftBrackets) == 0 {
fields = append(fields, field)
field = ""
} else {
field += string(c)
}
case '{':
leftBrackets = append(leftBrackets, i)
field += string(c)
case '}':
leftBrackets = leftBrackets[:len(leftBrackets)-1]
field += string(c)
if len(leftBrackets) == 0 {
fields = append(fields, field)
field = ""
}
default:
field += string(c)
}
}
if len(field) > 0 {
fields = append(fields, field)
}
var result = "*struct {\n%s}"
var fieldStr string
for _, fieldInfo := range fields {
fieldName, fieldType := str.KV(strings.TrimSpace(fieldInfo), ":")
n, exist := basicTypeName[fieldType]
if exist {
fieldStr += fmt.Sprintf("%s %s\n", str.FirstUpper(fieldName), n)
} else {
fieldStr += fmt.Sprintf("%s %s\n", str.FirstUpper(fieldName), slf.GetType(fieldType))
}
}
return fmt.Sprintf(result, fieldStr)
return fmt.Sprintf("%s*%s", result, slf.Name)
}

View File

@ -1,42 +0,0 @@
package internal
var TemplateGo = `// Code generated DO NOT EDIT.
package %s
import (
jsonIter "github.com/json-iterator/go"
"os"
)
var json = jsonIter.ConfigCompatibleWithStandardLibrary
%s
func LoadConfig(handle func(filename string, config any) error) {
%s
}
func Replace() {
%s
}
func DefaultLoad(filepath string) {
LoadConfig(func(filename string, config any) error {
bytes, err := os.ReadFile(filepath)
if err != nil {
return err
}
return json.Unmarshal(bytes, &config)
})
}
`
var TemplateStructGo = `// Code generated DO NOT EDIT.
package %s
%s
`

View File

@ -0,0 +1,14 @@
package internal
import "errors"
var (
ErrReadConfigFailedWithDisplayName = errors.New("read config display name failed, can not found position")
ErrReadConfigFailedWithName = errors.New("read config name failed, can not found position")
ErrReadConfigFailedWithIndexCount = errors.New("read config index count failed, can not found position")
ErrReadConfigFailedWithIndexCountLessThanZero = errors.New("read config index count failed, value less than zero")
ErrReadConfigFailedWithFieldPosition = errors.New("read config index count failed, field position exception")
ErrReadConfigFailedWithNameDuplicate = errors.New("read config index count failed, duplicate field names")
ErrReadConfigFailedWithExportParamException = errors.New("read config index count failed, export param must is s or c or sc or cs")
ErrReadConfigFailedWithIndexTypeException = errors.New("read config index count failed, the index type is only allowed to be the basic type")
)

View File

@ -0,0 +1,146 @@
package internal
import (
"bytes"
"fmt"
"github.com/kercylan98/minotaur/utils/str"
"html/template"
"strings"
)
func NewField(configName, fieldName, fieldType string) *Field {
sourceType := fieldType
var handleStruct = func(configName, fieldType string) []*Field {
var fs []*Field
var s = strings.TrimSuffix(strings.TrimPrefix(fieldType, "{"), "}")
var fields []string
var field string
var leftBrackets []int
for i, c := range s {
switch c {
case ',':
if len(leftBrackets) == 0 {
fields = append(fields, field)
field = ""
} else {
field += string(c)
}
case '{':
leftBrackets = append(leftBrackets, i)
field += string(c)
case '}':
leftBrackets = leftBrackets[:len(leftBrackets)-1]
field += string(c)
if len(leftBrackets) == 0 {
fields = append(fields, field)
field = ""
}
default:
field += string(c)
}
}
if len(field) > 0 {
fields = append(fields, field)
}
for _, fieldInfo := range fields {
fieldName, fieldType := str.KV(strings.TrimSpace(fieldInfo), ":")
fs = append(fs, NewField(configName, str.FirstUpper(fieldName), fieldType))
}
return fs
}
var fs []*Field
var sliceField *Field
if t, exist := basicTypeName[fieldType]; exist {
fieldType = t
goto end
}
if strings.HasPrefix(fieldType, "[]") {
fieldType = strings.TrimPrefix(fieldType, "[]")
if t, exist := basicTypeName[fieldType]; exist {
fieldType = fmt.Sprintf("map[int]%s", t)
} else {
sliceField = NewField(configName, fieldName, fieldType)
fieldType = fmt.Sprintf("map[int]*%s", configName+fieldName)
}
goto end
}
fs = handleStruct(configName+fieldName, fieldType)
fieldType = fmt.Sprintf("*%s", configName+fieldName)
end:
{
return &Field{
Name: fieldName,
Type: fieldType,
SourceType: sourceType,
TypeNotStar: strings.TrimPrefix(fieldType, "*"),
Fields: fs,
SliceField: sliceField,
}
}
}
type Field struct {
Name string
Type string
SourceType string
TypeNotStar string
Fields []*Field
SliceField *Field
ExportParam string
Server bool
Describe string
Ignore bool
}
func (slf *Field) Struct() string {
if len(slf.Fields) == 0 && slf.SliceField == nil {
return ""
}
tmpl, err := template.New("struct").Parse(generateGoStructTemplate)
if err != nil {
return ""
}
var buf bytes.Buffer
if len(slf.Fields) > 0 {
if err = tmpl.Execute(&buf, slf); err != nil {
return ""
}
} else if slf.SliceField != nil {
if err = tmpl.Execute(&buf, slf.SliceField); err != nil {
return ""
}
}
s := buf.String()
return s
}
func (slf *Field) String() string {
if len(slf.Fields) == 0 && slf.SliceField == nil {
return ""
}
tmpl, err := template.New("struct").Parse(generateGoStructTemplate)
if err != nil {
return ""
}
var buf bytes.Buffer
if len(slf.Fields) > 0 {
if err = tmpl.Execute(&buf, slf); err != nil {
return ""
}
} else if slf.SliceField != nil {
if err = tmpl.Execute(&buf, slf.SliceField); err != nil {
return ""
}
}
s := buf.String()
for _, field := range slf.Fields {
s += fmt.Sprintf("%s", field.String())
}
return s
}

View File

@ -7,29 +7,6 @@ import (
"strings"
)
var basicType = map[string]func(fieldValue string) any{
"string": withStringType,
"int": withIntType,
"int8": withInt8Type,
"int16": withInt16Type,
"int32": withInt32Type,
"int64": withInt64Type,
"uint": withUintType,
"uint8": withUint8Type,
"uint16": withUint16Type,
"uint32": withUint32Type,
"uint64": withUint64Type,
"float32": withFloat32Type,
"float64": withFloat64Type,
"float": withFloat64Type,
"double": withFloat64Type,
"number": withFloat64Type,
"byte": withByteType,
"rune": withRuneType,
"bool": withBoolType,
"boolean": withBoolType,
}
var basicTypeName = map[string]string{
"string": "string",
"int": "int",
@ -53,6 +30,29 @@ var basicTypeName = map[string]string{
"boolean": "bool",
}
var basicType = map[string]func(fieldValue string) any{
"string": withStringType,
"int": withIntType,
"int8": withInt8Type,
"int16": withInt16Type,
"int32": withInt32Type,
"int64": withInt64Type,
"uint": withUintType,
"uint8": withUint8Type,
"uint16": withUint16Type,
"uint32": withUint32Type,
"uint64": withUint64Type,
"float32": withFloat32Type,
"float64": withFloat64Type,
"float": withFloat64Type,
"double": withFloat64Type,
"number": withFloat64Type,
"byte": withByteType,
"rune": withRuneType,
"bool": withBoolType,
"boolean": withBoolType,
}
func getValueWithType(fieldType string, fieldValue string) any {
fieldType = strings.ToLower(strings.TrimSpace(fieldType))
handle, exist := basicType[fieldType]

View File

@ -0,0 +1,13 @@
package internal
func NewPosition(x, y int) *Position {
return &Position{
X: x,
Y: y,
}
}
type Position struct {
X int
Y int
}

View File

@ -0,0 +1,76 @@
package internal
const (
generateConfigTemplate = `
// {{.Name}} {{.DisplayName}}
type {{.Name}} struct {
{{range $index, $value := .Fields}}{{if eq $value.Server true}}{{if eq $value.Ignore false}}{{$value.Name}} {{$value.Type}} // {{$value.Describe}}{{end}}{{end}}
{{end}}
}
{{range $index, $value := .Fields}}{{$value}}{{end}}
`
generateGoStructTemplate = `
{{if eq .Ignore false}}
type {{.TypeNotStar}} struct {
{{range $index, $value := .Fields}}
{{$value.Name}} {{$value.Type}}
{{end}}
}
{{end}}
`
GenerateGoConfigTemplate = `// Code generated by minotaur-config-export. DO NOT EDIT.
package {{.Package}}
import (
jsonIter "github.com/json-iterator/go"
"os"
)
var json = jsonIter.ConfigCompatibleWithStandardLibrary
var (
{{range $index, $config := .Configs}}
Game{{$config.Name}} {{$config.GetVariable}}
game{{$config.Name}} {{$config.GetVariable}}
{{end}}
)
func LoadConfig(handle func(filename string, config any) error) {
{{range $index, $config := .Configs}}
handle("{{$config.Name}}.json", &game{{$config.Name}})
{{end}}
}
func Refresh() {
{{range $index, $config := .Configs}}
Game{{$config.Name}} = game{{$config.Name}}
{{end}}
}
func DefaultLoad(filepath string) {
LoadConfig(func(filename string, config any) error {
bytes, err := os.ReadFile(filepath)
if err != nil {
return err
}
return json.Unmarshal(bytes, &config)
})
}
`
GenerateGoDefineTemplate = `// Code generated by minotaur-config-export. DO NOT EDIT.
package {{.Package}}
{{range $index, $config := .Configs}}
{{$config.String}}
{{end}}
`
)

View File

@ -34,7 +34,10 @@ func (slf *Matrix[T]) GetMatrix() [][]T {
}
// Get 获取特定坐标的内容
func (slf *Matrix[T]) Get(x, y int) T {
func (slf *Matrix[T]) Get(x, y int) (value T) {
if x >= slf.w || x < 0 || y >= slf.h || y < 0 {
return value
}
return slf.m[x][y]
}

20
utils/xlsxtool/sheet.go Normal file
View File

@ -0,0 +1,20 @@
package xlsxtool
import (
"github.com/kercylan98/minotaur/utils/g2d/matrix"
"github.com/tealeg/xlsx"
)
// GetSheetMatrix 将sheet转换为二维矩阵
func GetSheetMatrix(sheet *xlsx.Sheet) *matrix.Matrix[*xlsx.Cell] {
m := matrix.NewMatrix[*xlsx.Cell](sheet.MaxCol, sheet.MaxRow)
for y := 0; y < sheet.MaxRow; y++ {
for x := 0; x < sheet.MaxCol; x++ {
if x >= len(sheet.Rows[y].Cells) {
continue
}
m.Set(x, y, sheet.Rows[y].Cells[x])
}
}
return m
}