From 335c93f92bae6faa14f73358c36e420108d53615 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Thu, 18 May 2023 18:04:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E8=A1=A8=E5=B7=A5=E5=85=B7=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 4 + go.sum | 24 + planner/configexport/configexport.go | 139 ++-- planner/configexport/configexport_test.go | 11 + planner/configexport/internal/config.go | 656 +++++++++--------- planner/configexport/internal/constants.go | 42 -- planner/configexport/internal/errors.go | 14 + planner/configexport/internal/field.go | 146 ++++ .../internal/{types.go => field_types.go} | 46 +- planner/configexport/internal/postion.go | 13 + planner/configexport/internal/template.go | 76 ++ .../configexport/{internal => }/template.xlsx | Bin utils/g2d/matrix/matrix.go | 5 +- utils/xlsxtool/sheet.go | 20 + 14 files changed, 740 insertions(+), 456 deletions(-) create mode 100644 planner/configexport/configexport_test.go delete mode 100644 planner/configexport/internal/constants.go create mode 100644 planner/configexport/internal/errors.go create mode 100644 planner/configexport/internal/field.go rename planner/configexport/internal/{types.go => field_types.go} (100%) create mode 100644 planner/configexport/internal/postion.go create mode 100644 planner/configexport/internal/template.go rename planner/configexport/{internal => }/template.xlsx (100%) create mode 100644 utils/xlsxtool/sheet.go diff --git a/go.mod b/go.mod index 6ef6e62..a1ee0d0 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 0c58604..dd78ace 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/planner/configexport/configexport.go b/planner/configexport/configexport.go index e5c5cb2..aa28c4d 100644 --- a/planner/configexport/configexport.go +++ b/planner/configexport/configexport.go @@ -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) + } } diff --git a/planner/configexport/configexport_test.go b/planner/configexport/configexport_test.go new file mode 100644 index 0000000..90a5b9b --- /dev/null +++ b/planner/configexport/configexport_test.go @@ -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") +} diff --git a/planner/configexport/internal/config.go b/planner/configexport/internal/config.go index 898df13..65cda64 100644 --- a/planner/configexport/internal/config.go +++ b/planner/configexport/internal/config.go @@ -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) } diff --git a/planner/configexport/internal/constants.go b/planner/configexport/internal/constants.go deleted file mode 100644 index 652e621..0000000 --- a/planner/configexport/internal/constants.go +++ /dev/null @@ -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 -` diff --git a/planner/configexport/internal/errors.go b/planner/configexport/internal/errors.go new file mode 100644 index 0000000..c0d9bd5 --- /dev/null +++ b/planner/configexport/internal/errors.go @@ -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") +) diff --git a/planner/configexport/internal/field.go b/planner/configexport/internal/field.go new file mode 100644 index 0000000..b0f5762 --- /dev/null +++ b/planner/configexport/internal/field.go @@ -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 +} diff --git a/planner/configexport/internal/types.go b/planner/configexport/internal/field_types.go similarity index 100% rename from planner/configexport/internal/types.go rename to planner/configexport/internal/field_types.go index 2d0910c..c754804 100644 --- a/planner/configexport/internal/types.go +++ b/planner/configexport/internal/field_types.go @@ -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] diff --git a/planner/configexport/internal/postion.go b/planner/configexport/internal/postion.go new file mode 100644 index 0000000..5a7fcd9 --- /dev/null +++ b/planner/configexport/internal/postion.go @@ -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 +} diff --git a/planner/configexport/internal/template.go b/planner/configexport/internal/template.go new file mode 100644 index 0000000..82bf982 --- /dev/null +++ b/planner/configexport/internal/template.go @@ -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}} + +` +) diff --git a/planner/configexport/internal/template.xlsx b/planner/configexport/template.xlsx similarity index 100% rename from planner/configexport/internal/template.xlsx rename to planner/configexport/template.xlsx diff --git a/utils/g2d/matrix/matrix.go b/utils/g2d/matrix/matrix.go index 4514d6b..e39d0be 100644 --- a/utils/g2d/matrix/matrix.go +++ b/utils/g2d/matrix/matrix.go @@ -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] } diff --git a/utils/xlsxtool/sheet.go b/utils/xlsxtool/sheet.go new file mode 100644 index 0000000..9c89c36 --- /dev/null +++ b/utils/xlsxtool/sheet.go @@ -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 +}