diff --git a/README.md b/README.md index fd16d72..acb3e3c 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@
- ' + operator + ' IP:' + row.ip + ' 接口:' + row.url + ' 名称:' + row.tags + ' / ' + row.summary + ' 状态码:' +
- row.errorMsg +
- '(' +
- row.errorCode +
- ')' +
- ' 处理耗时:' + row.takeUpTime + 'ms 响应时间:' + timestampToTime(row.timestamp) + '
+
-
+
@@ -136,7 +136,7 @@
* 本项目包含的第三方源码和二进制文件之版权信息另行标注。
-* 版权所有Copyright © 2020-2024 by Ms (https://github.com/bufanyun/hotgo)
+* 版权所有Copyright © 2020-2025 by Ms (https://github.com/bufanyun/hotgo)
* All rights reserved。
@@ -154,7 +154,7 @@
## [感谢JetBrains提供的免费GoLand](https://jb.gg/OpenSource)
-[](https://jb.gg/OpenSource)
+[](https://jb.gg/OpenSource)
## License
diff --git a/docs/guide-zh-CN/start-environment.md b/docs/guide-zh-CN/start-environment.md
index e32f5ae..cedfe4f 100644
--- a/docs/guide-zh-CN/start-environment.md
+++ b/docs/guide-zh-CN/start-environment.md
@@ -25,7 +25,7 @@
> 需要本地具有 git node golang 环境
-- node版本 >= 16.0.0
+- node版本 >= 20.0.0
- golang版本 >= 1.23
- mysql版本 >= 5.7,引擎需要是 innoDB
- IDE推荐:Goland
diff --git a/docs/guide-zh-CN/start-installation.md b/docs/guide-zh-CN/start-installation.md
index c69ddf5..ab69804 100644
--- a/docs/guide-zh-CN/start-installation.md
+++ b/docs/guide-zh-CN/start-installation.md
@@ -7,7 +7,7 @@
### 环境要求
-- node版本 >= v16.0.0
+- node版本 >= v20.0.0
- golang版本 >= v1.23
- goframe版本 >=v2.7.0
- mysql版本 >=5.7
diff --git a/docs/guide-zh-CN/start-update-log.md b/docs/guide-zh-CN/start-update-log.md
index edda09c..f55c515 100644
--- a/docs/guide-zh-CN/start-update-log.md
+++ b/docs/guide-zh-CN/start-update-log.md
@@ -11,6 +11,20 @@
> 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整
+### v2.16.10
+updated 2025.3.22
+
+- 增加:增加组合下拉用户筛选组件
+- 优化:文件上传类型限制改为统一由后台配置控制
+- 优化:websocket重连时间调整为10秒,初始化数据库中的网站地址调整为`127.0.0.1`
+- 优化:优化访问日志字段展示方式
+- 优化:系统公告发送编辑模态框调整为抽屉
+- 优化:gf版本升级到v2.9.0
+- 优化:naive-ui版本升级到2.41.0
+- 修复:修复vue路由`Redirect`命名重复问题
+- 修复:优化代码生成在插件中`使用生成字典选项`时model包名重复问题
+
+
### v2.15.11
updated 2024.11.27
diff --git a/server/go.mod b/server/go.mod
index 43f37c1..2329a48 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -14,10 +14,10 @@ require (
github.com/forgoer/openssl v1.6.0
github.com/go-pay/crypto v0.0.1
github.com/go-pay/gopay v1.5.104
- github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1
- github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1
+ github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0
+ github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.4
- github.com/gogf/gf/v2 v2.8.1
+ github.com/gogf/gf/v2 v2.9.0
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/gorilla/websocket v1.5.3
@@ -26,6 +26,7 @@ require (
github.com/mojocn/base64Captcha v1.3.6
github.com/olekukonko/tablewriter v0.0.5
github.com/qiniu/go-sdk/v7 v7.21.1
+ github.com/schollz/progressbar/v3 v3.18.0
github.com/shirou/gopsutil/v3 v3.24.5
github.com/silenceper/wechat/v2 v2.1.6
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.993
@@ -35,7 +36,7 @@ require (
github.com/xuri/excelize/v2 v2.6.0
go.opentelemetry.io/otel v1.32.0
golang.org/x/mod v0.20.0
- golang.org/x/net v0.31.0
+ golang.org/x/net v0.32.0
golang.org/x/tools v0.24.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -98,12 +99,13 @@ require (
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 // indirect
- github.com/magiconair/properties v1.8.7 // indirect
+ github.com/magiconair/properties v1.8.9 // indirect
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
+ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -136,11 +138,12 @@ require (
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
- golang.org/x/crypto v0.29.0 // indirect
+ golang.org/x/crypto v0.30.0 // indirect
golang.org/x/image v0.19.0 // indirect
- golang.org/x/sync v0.9.0 // indirect
- golang.org/x/sys v0.27.0 // indirect
- golang.org/x/text v0.20.0 // indirect
+ golang.org/x/sync v0.10.0 // indirect
+ golang.org/x/sys v0.29.0 // indirect
+ golang.org/x/term v0.28.0 // indirect
+ golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.6.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
diff --git a/server/go.sum b/server/go.sum
index 1f69c6f..e875759 100644
--- a/server/go.sum
+++ b/server/go.sum
@@ -78,6 +78,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
+github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -162,14 +164,14 @@ github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PU
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
-github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1 h1:jbaPawkb8qmaYzrmBDbTa8Zkhzacq1RBOZw+qRJExI4=
-github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1/go.mod h1:s2aI1fV9AvKi4NtMpv3pV0EHtazkvfUNVQmzapr7UJQ=
-github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1 h1:1vPFyN0GLv24JD3WGhvKzXvKG+fmuixDTawbtfzCzRQ=
-github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1/go.mod h1:IWyGxzplp06tRc6Ah/eCLuBntnKSw9sn1maH0vzPPtw=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0 h1:1f7EeD0lfPHoXfaJDSL7cxRcSRelbsAKgF3MGXY+Uyo=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0/go.mod h1:tToO1PjGkLIR+9DbJ0wrKicYma0H/EUHXOpwel6Dw+0=
+github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0 h1:EEZqu1PNRSmm+7Cqm9A/8+ObgfbMzhE1ps9Z3LD7HgM=
+github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0/go.mod h1:LHrxY+2IzNTHVTPG/s5yaz1VmXbj+CQ7Hr5SeVkHiTw=
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.4 h1:JnUjXb7C9vmwcZFwXqnxi9H4/I0rir9LmRryIX7xNds=
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.4/go.mod h1:A3NhV8u45twLq5VdqObhYNhT4szLFLCROw4LzHM+lYg=
-github.com/gogf/gf/v2 v2.8.1 h1:1oVQg3G5OgCats4qWFTH3pHLe92nfUQeUDta05tUs1g=
-github.com/gogf/gf/v2 v2.8.1/go.mod h1:6iYuZZ+A0ZcH8+4MDS/P0SvTPCvKzRvyAsY1kbkJYJc=
+github.com/gogf/gf/v2 v2.9.0 h1:semN5Q5qGjDQEv4620VzxcJzJlSD07gmyJ9Sy9zfbHk=
+github.com/gogf/gf/v2 v2.9.0/go.mod h1:sWGQw+pLILtuHmbOxoe0D+0DdaXxbleT57axOLH2vKI=
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f h1:7xfXR/BhG3JDqO1s45n65Oyx9t4E/UqDOXep6jXdLCM=
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f/go.mod h1:HnYoio6S7VaFJdryKcD/r9HgX+4QzYfr00XiXUo/xz0=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
@@ -274,8 +276,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 h1:5RK988zAqB3/AN3opGfRpoQgAVqr6/A5+qRTi67VUZY=
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
-github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
-github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
+github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f h1:B0OD7nYl2FPQEVrw8g2uyc1lGEzNbvrKh7fspGZcbvY=
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -290,6 +292,8 @@ github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.76 h1:9nxHH2XDai61cT/EFhyIw/wW4vJfpPNvl7lSFpRt+Ng=
github.com/minio/minio-go/v7 v7.0.76/go.mod h1:AVM3IUN6WwKzmwBxVdjzhH8xq+f57JSbbvzqvUzR6eg=
+github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
+github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
@@ -356,10 +360,12 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
-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/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
+github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
+github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
@@ -395,8 +401,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.993 h1:+iJMmF0q1MPyhLs0+J7CcJ47w/vq6ICsCxnV4gc0dKw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.993/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
@@ -468,8 +474,8 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
-golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
-golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
+golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
+golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
@@ -511,8 +517,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
-golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
+golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
+golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -523,8 +529,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
-golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -559,8 +565,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
-golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -568,6 +574,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
+golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
+golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -579,8 +587,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
-golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/server/internal/consts/version.go b/server/internal/consts/version.go
index b7ef1d8..11def75 100644
--- a/server/internal/consts/version.go
+++ b/server/internal/consts/version.go
@@ -7,5 +7,5 @@ package consts
// VersionApp HotGo版本
const (
- VersionApp = "2.15.11"
+ VersionApp = "2.16.10"
)
diff --git a/server/internal/library/hggen/hggen.go b/server/internal/library/hggen/hggen.go
index 2db397d..cb23db3 100644
--- a/server/internal/library/hggen/hggen.go
+++ b/server/internal/library/hggen/hggen.go
@@ -49,7 +49,7 @@ func Dao(ctx context.Context) (err error) {
inp.ImportPrefix = utils.GetImportPath(inp.Path)
inp.Path = tempPathPrefix + "/" + inp.Path
- if err = gfile.Remove(inp.Path); err != nil {
+ if err = gfile.RemoveAll(inp.Path); err != nil {
err = gerror.Newf("清理临时生成目录失败:%v", err)
return err
}
diff --git a/server/internal/library/hggen/internal/cmd/cmd.go b/server/internal/library/hggen/internal/cmd/cmd.go
index e8b8bc8..d3668ef 100644
--- a/server/internal/library/hggen/internal/cmd/cmd.go
+++ b/server/internal/library/hggen/internal/cmd/cmd.go
@@ -4,6 +4,7 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
+// Package cmd provides the management of CLI commands for `gf` tool.
package cmd
import (
@@ -19,9 +20,8 @@ import (
"hotgo/internal/library/hggen/internal/utility/mlog"
)
-var (
- GF = cGF{}
-)
+// GF is the management object for `gf` command line tool.
+var GF = cGF{}
type cGF struct {
g.Meta `name:"gf" ad:"{cGFAd}"`
diff --git a/server/internal/library/hggen/internal/cmd/cmd_doc.go b/server/internal/library/hggen/internal/cmd/cmd_doc.go
index 08f8257..163732d 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_doc.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_doc.go
@@ -19,6 +19,7 @@ import (
"github.com/gogf/gf/v2/encoding/gcompress"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
+
"hotgo/internal/library/hggen/internal/utility/mlog"
)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_fix.go b/server/internal/library/hggen/internal/cmd/cmd_fix.go
index 2e605ee..0a338aa 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_fix.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_fix.go
@@ -9,13 +9,13 @@ package cmd
import (
"context"
- "github.com/gogf/gf/v2/os/gproc"
- "github.com/gogf/gf/v2/text/gregex"
-
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gproc"
+ "github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/utility/mlog"
)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go b/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
index c5e445e..c53a52d 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
@@ -8,13 +8,15 @@ package cmd
import (
//_ "github.com/gogf/gf/contrib/drivers/clickhouse/v2"
- // _ "github.com/gogf/gf/contrib/drivers/dm/v2" // precompilation does not support certain target platforms.
//_ "github.com/gogf/gf/contrib/drivers/mssql/v2"
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
//_ "github.com/gogf/gf/contrib/drivers/oracle/v2"
//_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
//_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
+ // do not add dm in cli pre-compilation,
+ // the dm driver does not support certain target platforms.
+ // _ "github.com/gogf/gf/contrib/drivers/dm/v2"
"hotgo/internal/library/hggen/internal/cmd/gendao"
)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_init.go b/server/internal/library/hggen/internal/cmd/cmd_init.go
index 7ad160e..319f730 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_init.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_init.go
@@ -19,6 +19,7 @@ import (
"github.com/gogf/gf/v2/os/gres"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
+
"hotgo/internal/library/hggen/internal/utility/allyes"
"hotgo/internal/library/hggen/internal/utility/mlog"
"hotgo/internal/library/hggen/internal/utility/utils"
diff --git a/server/internal/library/hggen/internal/cmd/cmd_up.go b/server/internal/library/hggen/internal/cmd/cmd_up.go
index 8c8efeb..eebe364 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_up.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_up.go
@@ -19,6 +19,7 @@ import (
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
+
"hotgo/internal/library/hggen/internal/utility/mlog"
"hotgo/internal/library/hggen/internal/utility/utils"
)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_init_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_init_test.go
deleted file mode 100644
index 1e71cbd..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_init_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "context"
- "fmt"
-
- "github.com/gogf/gf/v2/database/gdb"
- "github.com/gogf/gf/v2/test/gtest"
-)
-
-var (
- ctx = context.Background()
- testDB gdb.DB
- link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=true"
-)
-
-func init() {
- var err error
- testDB, err = gdb.New(gdb.ConfigNode{
- Link: link,
- })
- if err != nil {
- panic(err)
- }
-}
-
-func dropTableWithDb(db gdb.DB, table string) {
- dropTableStmt := fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)
- if _, err := db.Exec(ctx, dropTableStmt); err != nil {
- gtest.Error(err)
- }
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_build_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_build_test.go
deleted file mode 100644
index 3392596..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_build_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "testing"
-
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/os/gproc"
- "github.com/gogf/gf/v2/test/gtest"
- "github.com/gogf/gf/v2/text/gstr"
-)
-
-func Test_Build_Single(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- buildPath = gtest.DataPath(`build`, `single`)
- pwd = gfile.Pwd()
- binaryName = `t.test`
- binaryPath = gtest.DataPath(`build`, `single`, binaryName)
- f = cBuild{}
- )
- defer gfile.Chdir(pwd)
- defer gfile.Remove(binaryPath)
- err := gfile.Chdir(buildPath)
- t.AssertNil(err)
-
- t.Assert(gfile.Exists(binaryPath), false)
- _, err = f.Index(ctx, cBuildInput{
- File: cBuildDefaultFile,
- Name: binaryName,
- })
- t.AssertNil(err)
- t.Assert(gfile.Exists(binaryPath), true)
- })
-}
-
-func Test_Build_Single_Output(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- buildPath = gtest.DataPath(`build`, `single`)
- pwd = gfile.Pwd()
- binaryName = `tt`
- binaryDirPath = gtest.DataPath(`build`, `single`, `tt`)
- binaryPath = gtest.DataPath(`build`, `single`, `tt`, binaryName)
- f = cBuild{}
- )
- defer gfile.Chdir(pwd)
- defer gfile.Remove(binaryDirPath)
- err := gfile.Chdir(buildPath)
- t.AssertNil(err)
-
- t.Assert(gfile.Exists(binaryPath), false)
- _, err = f.Index(ctx, cBuildInput{
- Output: "./tt/tt",
- })
- t.AssertNil(err)
- t.Assert(gfile.Exists(binaryPath), true)
- })
-}
-
-func Test_Build_Single_Path(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- buildPath = gtest.DataPath(`build`, `single`)
- pwd = gfile.Pwd()
- dirName = "ttt"
- binaryName = `main`
- binaryDirPath = gtest.DataPath(`build`, `single`, dirName)
- binaryPath = gtest.DataPath(`build`, `single`, dirName, binaryName)
- f = cBuild{}
- )
- defer gfile.Chdir(pwd)
- defer gfile.Remove(binaryDirPath)
- err := gfile.Chdir(buildPath)
- t.AssertNil(err)
-
- t.Assert(gfile.Exists(binaryPath), false)
- _, err = f.Index(ctx, cBuildInput{
- Path: "ttt",
- })
- t.AssertNil(err)
- t.Assert(gfile.Exists(binaryPath), true)
- })
-}
-
-func Test_Build_Single_VarMap(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- buildPath = gtest.DataPath(`build`, `varmap`)
- pwd = gfile.Pwd()
- binaryName = `main`
- binaryPath = gtest.DataPath(`build`, `varmap`, binaryName)
- f = cBuild{}
- )
- defer gfile.Chdir(pwd)
- defer gfile.Remove(binaryPath)
- err := gfile.Chdir(buildPath)
- t.AssertNil(err)
-
- t.Assert(gfile.Exists(binaryPath), false)
- _, err = f.Index(ctx, cBuildInput{
- VarMap: map[string]interface{}{
- "a": "1",
- "b": "2",
- },
- })
- t.AssertNil(err)
- t.Assert(gfile.Exists(binaryPath), true)
-
- result, err := gproc.ShellExec(ctx, binaryPath)
- t.AssertNil(err)
- t.Assert(gstr.Contains(result, `a: 1`), true)
- t.Assert(gstr.Contains(result, `b: 2`), true)
- })
-}
-
-func Test_Build_Multiple(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- buildPath = gtest.DataPath(`build`, `multiple`)
- pwd = gfile.Pwd()
- binaryDirPath = gtest.DataPath(`build`, `multiple`, `temp`)
- binaryPathLinux = gtest.DataPath(`build`, `multiple`, `temp`, `v1.1`, `linux_amd64`, `ttt`)
- binaryPathWindows = gtest.DataPath(`build`, `multiple`, `temp`, `v1.1`, `windows_amd64`, `ttt.exe`)
- f = cBuild{}
- )
- defer gfile.Chdir(pwd)
- defer gfile.Remove(binaryDirPath)
- err := gfile.Chdir(buildPath)
- t.AssertNil(err)
-
- t.Assert(gfile.Exists(binaryPathLinux), false)
- t.Assert(gfile.Exists(binaryPathWindows), false)
- _, err = f.Index(ctx, cBuildInput{
- File: "multiple.go",
- Name: "ttt",
- Version: "v1.1",
- Arch: "amd64",
- System: "linux, windows",
- Path: "temp",
- })
- t.AssertNil(err)
- t.Assert(gfile.Exists(binaryPathLinux), true)
- t.Assert(gfile.Exists(binaryPathWindows), true)
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_fix_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_fix_test.go
deleted file mode 100644
index ad53e41..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_fix_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "testing"
-
- "github.com/gogf/gf/v2/test/gtest"
-)
-
-func Test_Fix_doFixV25Content(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- content = gtest.DataContent(`fix`, `fix25_content.go`)
- f = cFix{}
- )
- _, err := f.doFixV25Content(content)
- t.AssertNil(err)
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_ctrl_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_ctrl_test.go
deleted file mode 100644
index 2d4dff4..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_ctrl_test.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "path/filepath"
- "testing"
-
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/test/gtest"
- "github.com/gogf/gf/v2/util/guid"
- "github.com/gogf/gf/v2/util/gutil"
- "hotgo/internal/library/hggen/internal/cmd/genctrl"
-)
-
-func Test_Gen_Ctrl_Default(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- path = gfile.Temp(guid.S())
- apiFolder = gtest.DataPath("genctrl", "api")
- in = genctrl.CGenCtrlInput{
- SrcFolder: apiFolder,
- DstFolder: path,
- WatchFile: "",
- SdkPath: "",
- SdkStdVersion: false,
- SdkNoV1: false,
- Clear: false,
- Merge: false,
- }
- )
- err := gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
- t.AssertNil(err)
-
- // apiInterface file
- var (
- genApi = apiFolder + filepath.FromSlash("/article/article.go")
- genApiExpect = apiFolder + filepath.FromSlash("/article/article_expect.go")
- )
- defer gfile.Remove(genApi)
- t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- path + filepath.FromSlash("/article/article.go"),
- path + filepath.FromSlash("/article/article_new.go"),
- path + filepath.FromSlash("/article/article_v1_create.go"),
- path + filepath.FromSlash("/article/article_v1_get_list.go"),
- path + filepath.FromSlash("/article/article_v1_get_one.go"),
- path + filepath.FromSlash("/article/article_v1_update.go"),
- path + filepath.FromSlash("/article/article_v2_create.go"),
- path + filepath.FromSlash("/article/article_v2_update.go"),
- })
-
- // content
- testPath := gtest.DataPath("genctrl", "controller")
- expectFiles := []string{
- testPath + filepath.FromSlash("/article/article.go"),
- testPath + filepath.FromSlash("/article/article_new.go"),
- testPath + filepath.FromSlash("/article/article_v1_create.go"),
- testPath + filepath.FromSlash("/article/article_v1_get_list.go"),
- testPath + filepath.FromSlash("/article/article_v1_get_one.go"),
- testPath + filepath.FromSlash("/article/article_v1_update.go"),
- testPath + filepath.FromSlash("/article/article_v2_create.go"),
- testPath + filepath.FromSlash("/article/article_v2_update.go"),
- }
- for i := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-func expectFilesContent(t *gtest.T, paths []string, expectPaths []string) {
- for i, expectFile := range expectPaths {
- val := gfile.GetContents(paths[i])
- expect := gfile.GetContents(expectFile)
- t.Assert(val, expect)
- }
-}
-
-// gf gen ctrl -m
-// In the same module, different API files are added
-func Test_Gen_Ctrl_UseMerge_AddNewFile(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- ctrlPath = gfile.Temp(guid.S())
- //ctrlPath = gtest.DataPath("issue", "3460", "controller")
- apiFolder = gtest.DataPath("genctrl-merge", "add_new_file", "api")
- in = genctrl.CGenCtrlInput{
- SrcFolder: apiFolder,
- DstFolder: ctrlPath,
- Merge: true,
- }
- )
- const testNewApiFile = `
-package v1
-import "github.com/gogf/gf/v2/frame/g"
-type DictTypeAddReq struct {
- g.Meta
-}
-type DictTypeAddRes struct {
-}
-`
-
- err := gfile.Mkdir(ctrlPath)
- t.AssertNil(err)
- defer gfile.Remove(ctrlPath)
-
- _, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
- t.AssertNil(err)
-
- var (
- genApi = filepath.Join(apiFolder, "/dict/dict.go")
- genApiExpect = filepath.Join(apiFolder, "/dict/dict_expect.go")
- )
- defer gfile.Remove(genApi)
- t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
-
- genCtrlFiles, err := gfile.ScanDir(ctrlPath, "*.go", true)
- t.AssertNil(err)
- t.Assert(genCtrlFiles, []string{
- filepath.Join(ctrlPath, "/dict/dict.go"),
- filepath.Join(ctrlPath, "/dict/dict_new.go"),
- filepath.Join(ctrlPath, "/dict/dict_v1_dict_type.go"),
- })
-
- expectCtrlPath := gtest.DataPath("genctrl-merge", "add_new_file", "controller")
- expectFiles := []string{
- filepath.Join(expectCtrlPath, "/dict/dict.go"),
- filepath.Join(expectCtrlPath, "/dict/dict_new.go"),
- filepath.Join(expectCtrlPath, "/dict/dict_v1_dict_type.go"),
- }
-
- // Line Feed maybe \r\n or \n
- expectFilesContent(t, genCtrlFiles, expectFiles)
-
- // Add a new API file
- newApiFilePath := filepath.Join(apiFolder, "/dict/v1/test_new.go")
- err = gfile.PutContents(newApiFilePath, testNewApiFile)
- t.AssertNil(err)
- defer gfile.Remove(newApiFilePath)
-
- // Then execute the command
- _, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
- t.AssertNil(err)
-
- genApi = filepath.Join(apiFolder, "/dict.go")
- genApiExpect = filepath.Join(apiFolder, "/dict_add_new_ctrl_expect.gotest")
-
- t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
-
- genCtrlFiles = append(genCtrlFiles, filepath.Join(ctrlPath, "/dict/dict_v1_test_new.go"))
- // Use the gotest suffix, otherwise the IDE will delete the import
- expectFiles = append(expectFiles, filepath.Join(expectCtrlPath, "/dict/dict_v1_test_new.gotest"))
- // Line Feed maybe \r\n or \n
- expectFilesContent(t, genCtrlFiles, expectFiles)
-
- })
-
-}
-
-// gf gen ctrl -m
-// In the same module, Add the same file to the API
-func Test_Gen_Ctrl_UseMerge_AddNewCtrl(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- ctrlPath = gfile.Temp(guid.S())
- //ctrlPath = gtest.DataPath("issue", "3460", "controller")
- apiFolder = gtest.DataPath("genctrl-merge", "add_new_ctrl", "api")
- in = genctrl.CGenCtrlInput{
- SrcFolder: apiFolder,
- DstFolder: ctrlPath,
- Merge: true,
- }
- )
-
- err := gfile.Mkdir(ctrlPath)
- t.AssertNil(err)
- defer gfile.Remove(ctrlPath)
-
- _, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
- t.AssertNil(err)
-
- var (
- genApi = filepath.Join(apiFolder, "/dict/dict.go")
- genApiExpect = filepath.Join(apiFolder, "/dict/dict_expect.go")
- )
- defer gfile.Remove(genApi)
- t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
-
- genCtrlFiles, err := gfile.ScanDir(ctrlPath, "*.go", true)
- t.AssertNil(err)
- t.Assert(genCtrlFiles, []string{
- filepath.Join(ctrlPath, "/dict/dict.go"),
- filepath.Join(ctrlPath, "/dict/dict_new.go"),
- filepath.Join(ctrlPath, "/dict/dict_v1_dict_type.go"),
- })
-
- expectCtrlPath := gtest.DataPath("genctrl-merge", "add_new_ctrl", "controller")
- expectFiles := []string{
- filepath.Join(expectCtrlPath, "/dict/dict.go"),
- filepath.Join(expectCtrlPath, "/dict/dict_new.go"),
- filepath.Join(expectCtrlPath, "/dict/dict_v1_dict_type.go"),
- }
-
- // Line Feed maybe \r\n or \n
- expectFilesContent(t, genCtrlFiles, expectFiles)
-
- const testNewApiFile = `
-
-type DictTypeAddReq struct {
- g.Meta
-}
-type DictTypeAddRes struct {
-}
-`
- dictModuleFileName := filepath.Join(apiFolder, "/dict/v1/dict_type.go")
- // Save the contents of the file before the changes
- apiFileContents := gfile.GetContents(dictModuleFileName)
-
- // Add a new API file
- err = gfile.PutContentsAppend(dictModuleFileName, testNewApiFile)
- t.AssertNil(err)
-
- //==================================
- // Then execute the command
- _, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
- t.AssertNil(err)
-
- genApi = filepath.Join(apiFolder, "/dict.go")
- genApiExpect = filepath.Join(apiFolder, "/dict_add_new_ctrl_expect.gotest")
- t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
-
- // Use the gotest suffix, otherwise the IDE will delete the import
- expectFiles[2] = filepath.Join(expectCtrlPath, "/dict/dict_v1_test_new.gotest")
- // Line Feed maybe \r\n or \n
- expectFilesContent(t, genCtrlFiles, expectFiles)
-
- // Restore the contents of the original API file
- err = gfile.PutContents(dictModuleFileName, apiFileContents)
- t.AssertNil(err)
- })
-
-}
-
-// https://github.com/gogf/gf/issues/3460
-func Test_Gen_Ctrl_UseMerge_Issue3460(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- ctrlPath = gfile.Temp(guid.S())
- //ctrlPath = gtest.DataPath("issue", "3460", "controller")
- apiFolder = gtest.DataPath("issue", "3460", "api")
- in = genctrl.CGenCtrlInput{
- SrcFolder: apiFolder,
- DstFolder: ctrlPath,
- WatchFile: "",
- SdkPath: "",
- SdkStdVersion: false,
- SdkNoV1: false,
- Clear: false,
- Merge: true,
- }
- )
-
- err := gfile.Mkdir(ctrlPath)
- t.AssertNil(err)
- defer gfile.Remove(ctrlPath)
-
- _, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
- t.AssertNil(err)
-
- files, err := gfile.ScanDir(ctrlPath, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.Join(ctrlPath, "/hello/hello.go"),
- filepath.Join(ctrlPath, "/hello/hello_new.go"),
- filepath.Join(ctrlPath, "/hello/hello_v1_req.go"),
- filepath.Join(ctrlPath, "/hello/hello_v2_req.go"),
- })
-
- expectCtrlPath := gtest.DataPath("issue", "3460", "controller")
- expectFiles := []string{
- filepath.Join(expectCtrlPath, "/hello/hello.go"),
- filepath.Join(expectCtrlPath, "/hello/hello_new.go"),
- filepath.Join(expectCtrlPath, "/hello/hello_v1_req.go"),
- filepath.Join(expectCtrlPath, "/hello/hello_v2_req.go"),
- }
-
- // Line Feed maybe \r\n or \n
- for i, expectFile := range expectFiles {
- val := gfile.GetContents(files[i])
- expect := gfile.GetContents(expectFile)
- t.Assert(val, expect)
- }
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_dao_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_dao_test.go
deleted file mode 100644
index 4947c79..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_dao_test.go
+++ /dev/null
@@ -1,841 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "fmt"
- "path/filepath"
- "testing"
-
- "github.com/gogf/gf/v2/database/gdb"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/gcfg"
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/test/gtest"
- "github.com/gogf/gf/v2/text/gstr"
- "github.com/gogf/gf/v2/util/guid"
- "github.com/gogf/gf/v2/util/gutil"
- "hotgo/internal/library/hggen/internal/cmd/gendao"
-)
-
-func Test_Gen_Dao_Default(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`gendao`, `user.tpl.sql`),
- table,
- )
- )
- dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: link,
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "SnakeScreaming",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: false,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: nil,
- FieldMapping: nil,
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
-
- // for go mod import path auto retrieve.
- err = gfile.Copy(
- gtest.DataPath("gendao", "go.mod.txt"),
- gfile.Join(path, "go.mod"),
- )
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.FromSlash(path + "/dao/internal/table_user.go"),
- filepath.FromSlash(path + "/dao/table_user.go"),
- filepath.FromSlash(path + "/model/do/table_user.go"),
- filepath.FromSlash(path + "/model/entity/table_user.go"),
- })
- // content
- testPath := gtest.DataPath("gendao", "generated_user")
- expectFiles := []string{
- filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
- filepath.FromSlash(testPath + "/dao/table_user.go"),
- filepath.FromSlash(testPath + "/model/do/table_user.go"),
- filepath.FromSlash(testPath + "/model/entity/table_user.go"),
- }
- for i, _ := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-func Test_Gen_Dao_TypeMapping(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`gendao`, `user.tpl.sql`),
- table,
- )
- )
- defer dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: link,
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: false,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: map[gendao.DBFieldTypeName]gendao.CustomAttributeType{
- "int": {
- Type: "int64",
- Import: "",
- },
- "decimal": {
- Type: "decimal.Decimal",
- Import: "github.com/shopspring/decimal",
- },
- },
- FieldMapping: nil,
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
-
- // for go mod import path auto retrieve.
- err = gfile.Copy(
- gtest.DataPath("gendao", "go.mod.txt"),
- gfile.Join(path, "go.mod"),
- )
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.FromSlash(path + "/dao/internal/table_user.go"),
- filepath.FromSlash(path + "/dao/table_user.go"),
- filepath.FromSlash(path + "/model/do/table_user.go"),
- filepath.FromSlash(path + "/model/entity/table_user.go"),
- })
- // content
- testPath := gtest.DataPath("gendao", "generated_user_type_mapping")
- expectFiles := []string{
- filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
- filepath.FromSlash(testPath + "/dao/table_user.go"),
- filepath.FromSlash(testPath + "/model/do/table_user.go"),
- filepath.FromSlash(testPath + "/model/entity/table_user.go"),
- }
- for i, _ := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-func Test_Gen_Dao_FieldMapping(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`gendao`, `user.tpl.sql`),
- table,
- )
- )
- defer dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: link,
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: false,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: map[gendao.DBFieldTypeName]gendao.CustomAttributeType{
- "int": {
- Type: "int64",
- Import: "",
- },
- },
- FieldMapping: map[gendao.DBTableFieldName]gendao.CustomAttributeType{
- "table_user.score": {
- Type: "decimal.Decimal",
- Import: "github.com/shopspring/decimal",
- },
- },
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
-
- // for go mod import path auto retrieve.
- err = gfile.Copy(
- gtest.DataPath("gendao", "go.mod.txt"),
- gfile.Join(path, "go.mod"),
- )
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.FromSlash(path + "/dao/internal/table_user.go"),
- filepath.FromSlash(path + "/dao/table_user.go"),
- filepath.FromSlash(path + "/model/do/table_user.go"),
- filepath.FromSlash(path + "/model/entity/table_user.go"),
- })
- // content
- testPath := gtest.DataPath("gendao", "generated_user_field_mapping")
- expectFiles := []string{
- filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
- filepath.FromSlash(testPath + "/dao/table_user.go"),
- filepath.FromSlash(testPath + "/model/do/table_user.go"),
- filepath.FromSlash(testPath + "/model/entity/table_user.go"),
- }
- for i, _ := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-func execSqlFile(db gdb.DB, filePath string, args ...any) error {
- sqlContent := fmt.Sprintf(
- gfile.GetContents(filePath),
- args...,
- )
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err := db.Exec(ctx, v); err != nil {
- return err
- }
- }
- return nil
-}
-
-// https://github.com/gogf/gf/issues/2572
-func Test_Gen_Dao_Issue2572(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table1 = "user1"
- table2 = "user2"
- issueDirPath = gtest.DataPath(`issue`, `2572`)
- )
- t.AssertNil(execSqlFile(db, gtest.DataPath(`issue`, `2572`, `sql1.sql`)))
- t.AssertNil(execSqlFile(db, gtest.DataPath(`issue`, `2572`, `sql2.sql`)))
- defer dropTableWithDb(db, table1)
- defer dropTableWithDb(db, table2)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: "",
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "SnakeScreaming",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: false,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: nil,
- FieldMapping: nil,
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Copy(issueDirPath, path)
- t.AssertNil(err)
-
- defer gfile.Remove(path)
-
- pwd := gfile.Pwd()
- err = gfile.Chdir(path)
- t.AssertNil(err)
-
- defer gfile.Chdir(pwd)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
-
- generatedFiles, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(len(generatedFiles), 8)
- for i, generatedFile := range generatedFiles {
- generatedFiles[i] = gstr.TrimLeftStr(generatedFile, path)
- }
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/internal/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/internal/user_2.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/user_2.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/do/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/do/user_2.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/entity/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/entity/user_2.go")), true)
- })
-}
-
-// https://github.com/gogf/gf/issues/2616
-func Test_Gen_Dao_Issue2616(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table1 = "user1"
- table2 = "user2"
- issueDirPath = gtest.DataPath(`issue`, `2616`)
- )
- t.AssertNil(execSqlFile(db, gtest.DataPath(`issue`, `2616`, `sql1.sql`)))
- t.AssertNil(execSqlFile(db, gtest.DataPath(`issue`, `2616`, `sql2.sql`)))
- defer dropTableWithDb(db, table1)
- defer dropTableWithDb(db, table2)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: "",
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "SnakeScreaming",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: false,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: nil,
- FieldMapping: nil,
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Copy(issueDirPath, path)
- t.AssertNil(err)
-
- defer gfile.Remove(path)
-
- pwd := gfile.Pwd()
- err = gfile.Chdir(path)
- t.AssertNil(err)
-
- defer gfile.Chdir(pwd)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
-
- generatedFiles, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(len(generatedFiles), 8)
- for i, generatedFile := range generatedFiles {
- generatedFiles[i] = gstr.TrimLeftStr(generatedFile, path)
- }
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/internal/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/internal/user_2.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/dao/user_2.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/do/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/do/user_2.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/entity/user_1.go")), true)
- t.Assert(gstr.InArray(generatedFiles,
- filepath.FromSlash("/model/entity/user_2.go")), true)
-
- // Key string to check if overwrite the dao files.
- // dao user1 is not be overwritten as configured in config.yaml.
- // dao user2 is to be overwritten as configured in config.yaml.
- var (
- keyStr = `// I am not overwritten.`
- daoUser1Content = gfile.GetContents(path + "/dao/user_1.go")
- daoUser2Content = gfile.GetContents(path + "/dao/user_2.go")
- )
- t.Assert(gstr.Contains(daoUser1Content, keyStr), true)
- t.Assert(gstr.Contains(daoUser2Content, keyStr), false)
- })
-}
-
-// https://github.com/gogf/gf/issues/2746
-func Test_Gen_Dao_Issue2746(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- mdb gdb.DB
- link2746 = "mariadb:root:12345678@tcp(127.0.0.1:3307)/test?loc=Local&parseTime=true"
- table = "issue2746"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`issue`, `2746`, `sql.sql`),
- table,
- )
- )
- mdb, err = gdb.New(gdb.ConfigNode{
- Link: link2746,
- })
- t.AssertNil(err)
-
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = mdb.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(mdb, table)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: link2746,
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "SnakeScreaming",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: true,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: nil,
- FieldMapping: nil,
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- var (
- file = filepath.FromSlash(path + "/model/entity/issue_2746.go")
- expectContent = gtest.DataContent(`issue`, `2746`, `issue_2746.go`)
- )
- t.Assert(expectContent, gfile.GetContents(file))
- })
-}
-
-// https://github.com/gogf/gf/issues/3459
-func Test_Gen_Dao_Issue3459(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`gendao`, `user.tpl.sql`),
- table,
- )
- )
- dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- confDir = gtest.DataPath("issue", "3459")
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: link,
- Tables: "",
- TablesEx: "",
- Group: group,
- Prefix: "",
- RemovePrefix: "",
- JsonCase: "SnakeScreaming",
- ImportPrefix: "",
- DaoPath: "",
- DoPath: "",
- EntityPath: "",
- TplDaoIndexPath: "",
- TplDaoInternalPath: "",
- TplDaoDoPath: "",
- TplDaoEntityPath: "",
- StdTime: false,
- WithTime: false,
- GJsonSupport: false,
- OverwriteDao: false,
- DescriptionTag: false,
- NoJsonTag: false,
- NoModelComment: false,
- Clear: false,
- TypeMapping: nil,
- }
- )
- err = g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetPath(confDir)
- t.AssertNil(err)
-
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
-
- // for go mod import path auto retrieve.
- err = gfile.Copy(
- gtest.DataPath("gendao", "go.mod.txt"),
- gfile.Join(path, "go.mod"),
- )
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.FromSlash(path + "/dao/internal/table_user.go"),
- filepath.FromSlash(path + "/dao/table_user.go"),
- filepath.FromSlash(path + "/model/do/table_user.go"),
- filepath.FromSlash(path + "/model/entity/table_user.go"),
- })
- // content
- testPath := gtest.DataPath("gendao", "generated_user")
- expectFiles := []string{
- filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
- filepath.FromSlash(testPath + "/dao/table_user.go"),
- filepath.FromSlash(testPath + "/model/do/table_user.go"),
- filepath.FromSlash(testPath + "/model/entity/table_user.go"),
- }
- for i, _ := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-// https://github.com/gogf/gf/issues/3749
-func Test_Gen_Dao_Issue3749(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`issue`, `3749`, `user.tpl.sql`),
- table,
- )
- )
- dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: link,
- Group: group,
- }
- )
-
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
-
- // for go mod import path auto retrieve.
- err = gfile.Copy(
- gtest.DataPath("gendao", "go.mod.txt"),
- gfile.Join(path, "go.mod"),
- )
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.FromSlash(path + "/dao/internal/table_user.go"),
- filepath.FromSlash(path + "/dao/table_user.go"),
- filepath.FromSlash(path + "/model/do/table_user.go"),
- filepath.FromSlash(path + "/model/entity/table_user.go"),
- })
- // content
- testPath := gtest.DataPath(`issue`, `3749`)
- expectFiles := []string{
- filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
- filepath.FromSlash(testPath + "/dao/table_user.go"),
- filepath.FromSlash(testPath + "/model/do/table_user.go"),
- filepath.FromSlash(testPath + "/model/entity/table_user.go"),
- }
- for i, _ := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-func Test_Gen_Dao_Sqlite3(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- table = "table_user"
- path = gfile.Temp(guid.S())
- linkSqlite3 = fmt.Sprintf("sqlite::@file(%s/db.sqlite3)", path)
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`gendao`, `sqlite3`, `user.sqlite3.sql`),
- table,
- )
- )
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- dbSqlite3, err := gdb.New(gdb.ConfigNode{
- Link: linkSqlite3,
- })
- t.AssertNil(err)
-
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if v == "" {
- continue
- }
- if _, err = dbSqlite3.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
-
- var (
- group = "test"
- in = gendao.CGenDaoInput{
- Path: path,
- Link: linkSqlite3,
- Group: group,
- Tables: table,
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- // for go mod import path auto retrieve.
- err = gfile.Copy(
- gtest.DataPath("gendao", "go.mod.txt"),
- gfile.Join(path, "go.mod"),
- )
- t.AssertNil(err)
-
- _, err = gendao.CGenDao{}.Dao(ctx, in)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- // files
- files, err := gfile.ScanDir(path, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- filepath.FromSlash(path + "/dao/internal/table_user.go"),
- filepath.FromSlash(path + "/dao/table_user.go"),
- filepath.FromSlash(path + "/model/do/table_user.go"),
- filepath.FromSlash(path + "/model/entity/table_user.go"),
- })
- // content
- testPath := gtest.DataPath("gendao", "generated_user_sqlite3")
- expectFiles := []string{
- filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
- filepath.FromSlash(testPath + "/dao/table_user.go"),
- filepath.FromSlash(testPath + "/model/do/table_user.go"),
- filepath.FromSlash(testPath + "/model/entity/table_user.go"),
- }
- for i, _ := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_pb_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_pb_test.go
deleted file mode 100644
index 882efe3..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_pb_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "path/filepath"
- "testing"
-
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/test/gtest"
- "github.com/gogf/gf/v2/text/gstr"
- "github.com/gogf/gf/v2/util/guid"
- "hotgo/internal/library/hggen/internal/cmd/genpb"
-)
-
-func TestGenPbIssue3882(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- outputPath = gfile.Temp(guid.S())
- outputApiPath = filepath.Join(outputPath, "api")
- outputCtrlPath = filepath.Join(outputPath, "controller")
-
- protobufFolder = gtest.DataPath("issue", "3882")
- in = genpb.CGenPbInput{
- Path: protobufFolder,
- OutputApi: outputApiPath,
- OutputCtrl: outputCtrlPath,
- }
- err error
- )
- err = gfile.Mkdir(outputApiPath)
- t.AssertNil(err)
- err = gfile.Mkdir(outputCtrlPath)
- t.AssertNil(err)
- defer gfile.Remove(outputPath)
-
- _, err = genpb.CGenPb{}.Pb(ctx, in)
- t.AssertNil(err)
-
- var (
- genContent = gfile.GetContents(filepath.Join(outputApiPath, "issue3882.pb.go"))
- exceptText = `dc:"Some comment on field with 'one' 'two' 'three' in the comment."`
- )
- t.Assert(gstr.Contains(genContent, exceptText), true)
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_pbentity_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_pbentity_test.go
deleted file mode 100644
index 6516645..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_pbentity_test.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "fmt"
- "path/filepath"
- "testing"
-
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/test/gtest"
- "github.com/gogf/gf/v2/text/gstr"
- "github.com/gogf/gf/v2/util/guid"
- "github.com/gogf/gf/v2/util/gutil"
- "hotgo/internal/library/hggen/internal/cmd/genpbentity"
-)
-
-func Test_Gen_Pbentity_Default(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`genpbentity`, `user.tpl.sql`),
- table,
- )
- )
- dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- in = genpbentity.CGenPbEntityInput{
- Path: path,
- Package: "unittest",
- Link: link,
- Tables: "",
- Prefix: "",
- RemovePrefix: "",
- RemoveFieldPrefix: "",
- NameCase: "",
- JsonCase: "",
- Option: "",
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genpbentity.CGenPbEntity{}.PbEntity(ctx, in)
- t.AssertNil(err)
-
- // files
- files, err := gfile.ScanDir(path, "*.proto", false)
- t.AssertNil(err)
- t.Assert(files, []string{
- path + filepath.FromSlash("/table_user.proto"),
- })
-
- // contents
- testPath := gtest.DataPath("genpbentity", "generated")
- expectFiles := []string{
- testPath + filepath.FromSlash("/table_user.proto"),
- }
- for i := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-func Test_Gen_Pbentity_NameCase_SnakeScreaming(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`genpbentity`, `user.tpl.sql`),
- table,
- )
- )
- dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- in = genpbentity.CGenPbEntityInput{
- Path: path,
- Package: "unittest",
- Link: link,
- Tables: "",
- Prefix: "",
- RemovePrefix: "",
- RemoveFieldPrefix: "",
- NameCase: "SnakeScreaming",
- JsonCase: "",
- Option: "",
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genpbentity.CGenPbEntity{}.PbEntity(ctx, in)
- t.AssertNil(err)
-
- // files
- files, err := gfile.ScanDir(path, "*.proto", false)
- t.AssertNil(err)
- t.Assert(files, []string{
- path + filepath.FromSlash("/table_user.proto"),
- })
-
- // contents
- testPath := gtest.DataPath("genpbentity", "generated")
- expectFiles := []string{
- testPath + filepath.FromSlash("/table_user_snake_screaming.proto"),
- }
- for i := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-// https://github.com/gogf/gf/issues/3545
-func Test_Issue_3545(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- err error
- db = testDB
- table = "table_user"
- sqlContent = fmt.Sprintf(
- gtest.DataContent(`genpbentity`, `user.tpl.sql`),
- table,
- )
- )
- dropTableWithDb(db, table)
- array := gstr.SplitAndTrim(sqlContent, ";")
- for _, v := range array {
- if _, err = db.Exec(ctx, v); err != nil {
- t.AssertNil(err)
- }
- }
- defer dropTableWithDb(db, table)
-
- var (
- path = gfile.Temp(guid.S())
- in = genpbentity.CGenPbEntityInput{
- Path: path,
- Package: "",
- Link: link,
- Tables: "",
- Prefix: "",
- RemovePrefix: "",
- RemoveFieldPrefix: "",
- NameCase: "",
- JsonCase: "",
- Option: "",
- }
- )
- err = gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genpbentity.CGenPbEntity{}.PbEntity(ctx, in)
- t.AssertNil(err)
-
- // files
- files, err := gfile.ScanDir(path, "*.proto", false)
- t.AssertNil(err)
- t.Assert(files, []string{
- path + filepath.FromSlash("/table_user.proto"),
- })
-
- // contents
- testPath := gtest.DataPath("issue", "3545")
- expectFiles := []string{
- testPath + filepath.FromSlash("/table_user.proto"),
- }
- for i := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_service_test.go b/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_service_test.go
deleted file mode 100644
index c503706..0000000
--- a/server/internal/library/hggen/internal/cmd/cmd_z_unit_gen_service_test.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
-//
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file,
-// You can obtain one at https://github.com/gogf/gf.
-
-package cmd
-
-import (
- "path/filepath"
- "testing"
-
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/test/gtest"
- "github.com/gogf/gf/v2/util/guid"
- "github.com/gogf/gf/v2/util/gutil"
- "hotgo/internal/library/hggen/internal/cmd/genservice"
-)
-
-func Test_Gen_Service_Default(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- path = gfile.Temp(guid.S())
- dstFolder = path + filepath.FromSlash("/service")
- srvFolder = gtest.DataPath("genservice", "logic")
- in = genservice.CGenServiceInput{
- SrcFolder: srvFolder,
- DstFolder: dstFolder,
- DstFileNameCase: "Snake",
- WatchFile: "",
- StPattern: "",
- Packages: nil,
- ImportPrefix: "",
- Clear: false,
- }
- )
- err := gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genservice.CGenService{}.Service(ctx, in)
- t.AssertNil(err)
-
- // logic file
- var (
- genSrv = srvFolder + filepath.FromSlash("/logic.go")
- genSrvExpect = srvFolder + filepath.FromSlash("/logic_expect.go")
- )
- defer gfile.Remove(genSrv)
- t.Assert(gfile.GetContents(genSrv), gfile.GetContents(genSrvExpect))
-
- // files
- files, err := gfile.ScanDir(dstFolder, "*.go", true)
- t.AssertNil(err)
- t.Assert(files, []string{
- dstFolder + filepath.FromSlash("/article.go"),
- dstFolder + filepath.FromSlash("/delivery.go"),
- dstFolder + filepath.FromSlash("/user.go"),
- })
-
- // contents
- testPath := gtest.DataPath("genservice", "service")
- expectFiles := []string{
- testPath + filepath.FromSlash("/article.go"),
- testPath + filepath.FromSlash("/delivery.go"),
- testPath + filepath.FromSlash("/user.go"),
- }
- for i := range files {
- t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
- }
- })
-}
-
-// https://github.com/gogf/gf/issues/3328
-func Test_Issue3328(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- path = gfile.Temp(guid.S())
- dstFolder = path + filepath.FromSlash("/service")
- srvFolder = gtest.DataPath("issue", "3328", "logic")
- logicGoPath = srvFolder + filepath.FromSlash("/logic.go")
- in = genservice.CGenServiceInput{
- SrcFolder: srvFolder,
- DstFolder: dstFolder,
- DstFileNameCase: "Snake",
- WatchFile: "",
- StPattern: "",
- Packages: nil,
- ImportPrefix: "",
- Clear: false,
- }
- )
- gfile.Remove(logicGoPath)
- defer gfile.Remove(logicGoPath)
-
- err := gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genservice.CGenService{}.Service(ctx, in)
- t.AssertNil(err)
-
- files, err := gfile.ScanDir(srvFolder, "*", true)
- for _, file := range files {
- if file == logicGoPath {
- if gfile.IsDir(logicGoPath) {
- t.Fatalf("%s should not is folder", logicGoPath)
- }
- }
- }
- })
-}
-
-// https://github.com/gogf/gf/issues/3835
-func Test_Issue3835(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- var (
- path = gfile.Temp(guid.S())
- dstFolder = path + filepath.FromSlash("/service")
- srvFolder = gtest.DataPath("issue", "3835", "logic")
- in = genservice.CGenServiceInput{
- SrcFolder: srvFolder,
- DstFolder: dstFolder,
- DstFileNameCase: "Snake",
- WatchFile: "",
- StPattern: "",
- Packages: nil,
- ImportPrefix: "",
- Clear: false,
- }
- )
- err := gutil.FillStructWithDefault(&in)
- t.AssertNil(err)
-
- err = gfile.Mkdir(path)
- t.AssertNil(err)
- defer gfile.Remove(path)
-
- _, err = genservice.CGenService{}.Service(ctx, in)
- t.AssertNil(err)
-
- // contents
- var (
- genFile = dstFolder + filepath.FromSlash("/issue_3835.go")
- expectFile = gtest.DataPath("issue", "3835", "service", "issue_3835.go")
- )
- t.Assert(gfile.GetContents(genFile), gfile.GetContents(expectFile))
- })
-}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go
index b495e26..c502e3e 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go
@@ -6,7 +6,11 @@
package genctrl
-import "github.com/gogf/gf/v2/text/gstr"
+import (
+ "fmt"
+
+ "github.com/gogf/gf/v2/text/gstr"
+)
type apiItem struct {
Import string `eg:"demo.com/api/user/v1"`
@@ -14,6 +18,7 @@ type apiItem struct {
Module string `eg:"user"`
Version string `eg:"v1"`
MethodName string `eg:"GetList"`
+ Comment string `eg:"GetList get list"`
}
func (a apiItem) String() string {
@@ -21,3 +26,12 @@ func (a apiItem) String() string {
a.Import, a.Module, a.Version, a.MethodName,
}, ",")
}
+
+// GetComment returns the comment of apiItem.
+func (a apiItem) GetComment() string {
+ if a.Comment == "" {
+ return ""
+ }
+ // format for handling comments
+ return fmt.Sprintf("\n// %s %s", a.MethodName, a.Comment)
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_ast_parse.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_ast_parse.go
index cf27089..9f87bf5 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_ast_parse.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_ast_parse.go
@@ -17,9 +17,14 @@ import (
"github.com/gogf/gf/v2/text/gstr"
)
-// getStructsNameInSrc retrieves all struct names
+type structInfo struct {
+ structName string
+ comment string
+}
+
+// getStructsNameInSrc retrieves all struct names and comment
// that end in "Req" and have "g.Meta" in their body.
-func (c CGenCtrl) getStructsNameInSrc(filePath string) (structsName []string, err error) {
+func (c CGenCtrl) getStructsNameInSrc(filePath string) (structInfos []*structInfo, err error) {
var (
fileContent = gfile.GetContents(filePath)
fileSet = token.NewFileSet()
@@ -32,8 +37,8 @@ func (c CGenCtrl) getStructsNameInSrc(filePath string) (structsName []string, er
ast.Inspect(node, func(n ast.Node) bool {
if typeSpec, ok := n.(*ast.TypeSpec); ok {
- methodName := typeSpec.Name.Name
- if !gstr.HasSuffix(methodName, "Req") {
+ structName := typeSpec.Name.Name
+ if !gstr.HasSuffix(structName, "Req") {
// ignore struct name that do not end in "Req"
return true
}
@@ -46,7 +51,19 @@ func (c CGenCtrl) getStructsNameInSrc(filePath string) (structsName []string, er
if !gstr.Contains(buf.String(), `g.Meta`) {
return true
}
- structsName = append(structsName, methodName)
+
+ comment := typeSpec.Doc.Text()
+ // remove the struct name from the comment
+ if gstr.HasPrefix(comment, structName) {
+ comment = gstr.TrimLeftStr(comment, structName, 1)
+ }
+ // remove the comment \n or space
+ comment = gstr.Trim(comment)
+
+ structInfos = append(structInfos, &structInfo{
+ structName: structName,
+ comment: comment,
+ })
}
}
return true
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go
index 841e49a..62818a4 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go
@@ -10,6 +10,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/utility/utils"
)
@@ -38,15 +39,16 @@ func (c CGenCtrl) getApiItemsInSrc(apiModuleFolderPath string) (items []apiItem,
if err != nil {
return nil, err
}
- for _, methodName := range structsInfo {
+ for _, s := range structsInfo {
// remove end "Req"
- methodName = gstr.TrimRightStr(methodName, "Req", 1)
+ methodName := gstr.TrimRightStr(s.structName, "Req", 1)
item := apiItem{
Import: gstr.Trim(importPath, `"`),
FileName: gfile.Name(apiFileFolderPath),
Module: gfile.Basename(apiModuleFolderPath),
Version: gfile.Basename(apiVersionFolderPath),
MethodName: methodName,
+ Comment: s.comment,
}
items = append(items, item)
}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go
index 2c54af4..08cb33e 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go
@@ -15,6 +15,7 @@ import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
)
@@ -137,10 +138,11 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite
if gfile.Exists(methodFilePath) {
content = gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFuncMerge, g.MapStrStr{
- "{Module}": item.Module,
- "{CtrlName}": ctrlName,
- "{Version}": item.Version,
- "{MethodName}": item.MethodName,
+ "{Module}": item.Module,
+ "{CtrlName}": ctrlName,
+ "{Version}": item.Version,
+ "{MethodName}": item.MethodName,
+ "{MethodComment}": item.GetComment(),
})
if gstr.Contains(gfile.GetContents(methodFilePath), fmt.Sprintf(`func (c *%v) %v(`, ctrlName, item.MethodName)) {
@@ -151,11 +153,12 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite
}
} else {
content = gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFunc, g.MapStrStr{
- "{Module}": item.Module,
- "{ImportPath}": item.Import,
- "{CtrlName}": ctrlName,
- "{Version}": item.Version,
- "{MethodName}": item.MethodName,
+ "{Module}": item.Module,
+ "{ImportPath}": item.Import,
+ "{CtrlName}": ctrlName,
+ "{Version}": item.Version,
+ "{MethodName}": item.MethodName,
+ "{MethodComment}": item.GetComment(),
})
if err = gfile.PutContents(methodFilePath, gstr.TrimLeft(content)); err != nil {
return err
@@ -191,10 +194,11 @@ func (c *controllerGenerator) doGenerateCtrlMergeItem(dstModuleFolderPath string
}
ctrl := gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFuncMerge, g.MapStrStr{
- "{Module}": api.Module,
- "{CtrlName}": fmt.Sprintf(`Controller%s`, gstr.UcFirst(api.Version)),
- "{Version}": api.Version,
- "{MethodName}": api.MethodName,
+ "{Module}": api.Module,
+ "{CtrlName}": fmt.Sprintf(`Controller%s`, gstr.UcFirst(api.Version)),
+ "{Version}": api.Version,
+ "{MethodName}": api.MethodName,
+ "{MethodComment}": api.GetComment(),
}))
ctrlFileItem.controllers.WriteString(ctrl)
doneApiSet.Add(api.String())
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go
index aab8a78..b3fbcc8 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go
@@ -11,6 +11,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/utility/mlog"
)
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go
index 29df0e3..a6cc5eb 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go
@@ -16,6 +16,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
+
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
"hotgo/internal/library/hggen/internal/utility/utils"
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go
index 8881bac..17bb64a 100644
--- a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go
@@ -15,6 +15,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
)
@@ -179,6 +180,7 @@ func (c *apiSdkGenerator) doGenerateSdkImplementer(
"{Version}": item.Version,
"{MethodName}": item.MethodName,
"{ImplementerName}": implementerName,
+ "{MethodComment}": item.GetComment(),
}))
implementerFileContent += "\n"
}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao.go b/server/internal/library/hggen/internal/cmd/gendao/gendao.go
index 8157777..3a80122 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao.go
@@ -14,115 +14,77 @@ import (
"golang.org/x/mod/modfile"
"github.com/gogf/gf/v2/container/garray"
+ "github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/os/gtime"
+ "github.com/gogf/gf/v2/os/gview"
+ "github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
- "github.com/gogf/gf/v2/util/gtag"
- "hotgo/internal/library/hggen/internal/utility/utils"
"hotgo/internal/library/hggen/internal/utility/mlog"
+ "hotgo/internal/library/hggen/internal/utility/utils"
)
-const (
- CGenDaoConfig = `gfcli.gen.dao`
- CGenDaoUsage = `gf gen dao [OPTION]`
- CGenDaoBrief = `automatically generate go files for dao/do/entity`
- CGenDaoEg = `
-gf gen dao
-gf gen dao -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
-gf gen dao -p ./model -g user-center -t user,user_detail,user_login
-gf gen dao -r user_
-`
+type (
+ CGenDao struct{}
+ CGenDaoInput struct {
+ g.Meta `name:"dao" config:"{CGenDaoConfig}" usage:"{CGenDaoUsage}" brief:"{CGenDaoBrief}" eg:"{CGenDaoEg}" ad:"{CGenDaoAd}"`
+ Path string `name:"path" short:"p" brief:"{CGenDaoBriefPath}" d:"internal"`
+ Link string `name:"link" short:"l" brief:"{CGenDaoBriefLink}"`
+ Tables string `name:"tables" short:"t" brief:"{CGenDaoBriefTables}"`
+ TablesEx string `name:"tablesEx" short:"x" brief:"{CGenDaoBriefTablesEx}"`
+ ShardingPattern []string `name:"shardingPattern" short:"sp" brief:"{CGenDaoBriefShardingPattern}"`
+ Group string `name:"group" short:"g" brief:"{CGenDaoBriefGroup}" d:"default"`
+ Prefix string `name:"prefix" short:"f" brief:"{CGenDaoBriefPrefix}"`
+ RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenDaoBriefRemovePrefix}"`
+ RemoveFieldPrefix string `name:"removeFieldPrefix" short:"rf" brief:"{CGenDaoBriefRemoveFieldPrefix}"`
+ JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
+ ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
+ DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
+ DoPath string `name:"doPath" short:"o" brief:"{CGenDaoBriefDoPath}" d:"model/do"`
+ EntityPath string `name:"entityPath" short:"e" brief:"{CGenDaoBriefEntityPath}" d:"model/entity"`
+ TplDaoIndexPath string `name:"tplDaoIndexPath" short:"t1" brief:"{CGenDaoBriefTplDaoIndexPath}"`
+ TplDaoInternalPath string `name:"tplDaoInternalPath" short:"t2" brief:"{CGenDaoBriefTplDaoInternalPath}"`
+ TplDaoDoPath string `name:"tplDaoDoPath" short:"t3" brief:"{CGenDaoBriefTplDaoDoPathPath}"`
+ TplDaoEntityPath string `name:"tplDaoEntityPath" short:"t4" brief:"{CGenDaoBriefTplDaoEntityPath}"`
+ StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
+ WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
+ GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
+ OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
+ DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
+ NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
+ NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
+ Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
- CGenDaoAd = `
-CONFIGURATION SUPPORT
- Options are also supported by configuration file.
- It's suggested using configuration file instead of command line arguments making producing.
- The configuration node name is "gfcli.gen.dao", which also supports multiple databases, for example(config.yaml):
- gfcli:
- gen:
- dao:
- - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
- tables: "order,products"
- jsonCase: "CamelLower"
- - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/primary"
- path: "./my-app"
- prefix: "primary_"
- tables: "user, userDetail"
- typeMapping:
- decimal:
- type: decimal.Decimal
- import: github.com/shopspring/decimal
- numeric:
- type: string
- fieldMapping:
- table_name.field_name:
- type: decimal.Decimal
- import: github.com/shopspring/decimal
-`
- CGenDaoBriefPath = `directory path for generated files`
- CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
- CGenDaoBriefTables = `generate models only for given tables, multiple table names separated with ','`
- CGenDaoBriefTablesEx = `generate models excluding given tables, multiple table names separated with ','`
- CGenDaoBriefPrefix = `add prefix for all table of specified link/database tables`
- CGenDaoBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
- CGenDaoBriefRemoveFieldPrefix = `remove specified prefix of the field, multiple prefix separated with ','`
- CGenDaoBriefStdTime = `use time.Time from stdlib instead of gtime.Time for generated time/date fields of tables`
- CGenDaoBriefWithTime = `add created time for auto produced go files`
- CGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
- CGenDaoBriefImportPrefix = `custom import prefix for generated go files`
- CGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
- CGenDaoBriefDoPath = `directory path for storing generated do files under path`
- CGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
- CGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
- CGenDaoBriefModelFile = `custom file name for storing generated model content`
- CGenDaoBriefModelFileForDao = `custom file name generating model for DAO operations like Where/Data. It's empty in default`
- CGenDaoBriefDescriptionTag = `add comment to description tag for each field`
- CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
- CGenDaoBriefNoModelComment = `no model comment will be added for each field`
- CGenDaoBriefClear = `delete all generated go files that do not exist in database`
- CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
- CGenDaoBriefFieldMapping = `custom local type mapping for generated struct attributes relevant to specific fields of table`
- CGenDaoBriefGroup = `
-specifying the configuration group name of database for generated ORM instance,
-it's not necessary and the default value is "default"
-`
- CGenDaoBriefJsonCase = `
-generated json tag case for model struct, cases are as follows:
-| Case | Example |
-|---------------- |--------------------|
-| Camel | AnyKindOfString |
-| CamelLower | anyKindOfString | default
-| Snake | any_kind_of_string |
-| SnakeScreaming | ANY_KIND_OF_STRING |
-| SnakeFirstUpper | rgb_code_md5 |
-| Kebab | any-kind-of-string |
-| KebabScreaming | ANY-KIND-OF-STRING |
-`
- CGenDaoBriefTplDaoIndexPath = `template file path for dao index file`
- CGenDaoBriefTplDaoInternalPath = `template file path for dao internal file`
- CGenDaoBriefTplDaoDoPathPath = `template file path for dao do file`
- CGenDaoBriefTplDaoEntityPath = `template file path for dao entity file`
+ TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
+ FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`
- tplVarTableName = `{TplTableName}`
- tplVarTableNameCamelCase = `{TplTableNameCamelCase}`
- tplVarTableNameCamelLowerCase = `{TplTableNameCamelLowerCase}`
- tplVarPackageImports = `{TplPackageImports}`
- tplVarImportPrefix = `{TplImportPrefix}`
- tplVarStructDefine = `{TplStructDefine}`
- tplVarColumnDefine = `{TplColumnDefine}`
- tplVarColumnNames = `{TplColumnNames}`
- tplVarGroupName = `{TplGroupName}`
- tplVarDatetimeStr = `{TplDatetimeStr}`
- tplVarCreatedAtDatetimeStr = `{TplCreatedAtDatetimeStr}`
- tplVarPackageName = `{TplPackageName}`
+ // internal usage purpose.
+ genItems *CGenDaoInternalGenItems
+ }
+ CGenDaoOutput struct{}
+
+ CGenDaoInternalInput struct {
+ CGenDaoInput
+ DB gdb.DB
+ TableNames []string
+ NewTableNames []string
+ ShardingTableSet *gset.StrSet
+ }
+ DBTableFieldName = string
+ DBFieldTypeName = string
+ CustomAttributeType struct {
+ Type string `brief:"custom attribute type name"`
+ Import string `brief:"custom import for this type"`
+ }
)
var (
createdAt = gtime.Now()
+ tplView = gview.New()
defaultTypeMapping = map[DBFieldTypeName]CustomAttributeType{
"decimal": {
Type: "float64",
@@ -139,97 +101,6 @@ var (
}
)
-func init() {
- gtag.Sets(g.MapStrStr{
- `CGenDaoConfig`: CGenDaoConfig,
- `CGenDaoUsage`: CGenDaoUsage,
- `CGenDaoBrief`: CGenDaoBrief,
- `CGenDaoEg`: CGenDaoEg,
- `CGenDaoAd`: CGenDaoAd,
- `CGenDaoBriefPath`: CGenDaoBriefPath,
- `CGenDaoBriefLink`: CGenDaoBriefLink,
- `CGenDaoBriefTables`: CGenDaoBriefTables,
- `CGenDaoBriefTablesEx`: CGenDaoBriefTablesEx,
- `CGenDaoBriefPrefix`: CGenDaoBriefPrefix,
- `CGenDaoBriefRemovePrefix`: CGenDaoBriefRemovePrefix,
- `CGenDaoBriefRemoveFieldPrefix`: CGenDaoBriefRemoveFieldPrefix,
- `CGenDaoBriefStdTime`: CGenDaoBriefStdTime,
- `CGenDaoBriefWithTime`: CGenDaoBriefWithTime,
- `CGenDaoBriefDaoPath`: CGenDaoBriefDaoPath,
- `CGenDaoBriefDoPath`: CGenDaoBriefDoPath,
- `CGenDaoBriefEntityPath`: CGenDaoBriefEntityPath,
- `CGenDaoBriefGJsonSupport`: CGenDaoBriefGJsonSupport,
- `CGenDaoBriefImportPrefix`: CGenDaoBriefImportPrefix,
- `CGenDaoBriefOverwriteDao`: CGenDaoBriefOverwriteDao,
- `CGenDaoBriefModelFile`: CGenDaoBriefModelFile,
- `CGenDaoBriefModelFileForDao`: CGenDaoBriefModelFileForDao,
- `CGenDaoBriefDescriptionTag`: CGenDaoBriefDescriptionTag,
- `CGenDaoBriefNoJsonTag`: CGenDaoBriefNoJsonTag,
- `CGenDaoBriefNoModelComment`: CGenDaoBriefNoModelComment,
- `CGenDaoBriefClear`: CGenDaoBriefClear,
- `CGenDaoBriefTypeMapping`: CGenDaoBriefTypeMapping,
- `CGenDaoBriefFieldMapping`: CGenDaoBriefFieldMapping,
- `CGenDaoBriefGroup`: CGenDaoBriefGroup,
- `CGenDaoBriefJsonCase`: CGenDaoBriefJsonCase,
- `CGenDaoBriefTplDaoIndexPath`: CGenDaoBriefTplDaoIndexPath,
- `CGenDaoBriefTplDaoInternalPath`: CGenDaoBriefTplDaoInternalPath,
- `CGenDaoBriefTplDaoDoPathPath`: CGenDaoBriefTplDaoDoPathPath,
- `CGenDaoBriefTplDaoEntityPath`: CGenDaoBriefTplDaoEntityPath,
- })
-}
-
-type (
- CGenDao struct{}
- CGenDaoInput struct {
- g.Meta `name:"dao" config:"{CGenDaoConfig}" usage:"{CGenDaoUsage}" brief:"{CGenDaoBrief}" eg:"{CGenDaoEg}" ad:"{CGenDaoAd}"`
- Path string `name:"path" short:"p" brief:"{CGenDaoBriefPath}" d:"internal"`
- Link string `name:"link" short:"l" brief:"{CGenDaoBriefLink}"`
- Tables string `name:"tables" short:"t" brief:"{CGenDaoBriefTables}"`
- TablesEx string `name:"tablesEx" short:"x" brief:"{CGenDaoBriefTablesEx}"`
- Group string `name:"group" short:"g" brief:"{CGenDaoBriefGroup}" d:"default"`
- Prefix string `name:"prefix" short:"f" brief:"{CGenDaoBriefPrefix}"`
- RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenDaoBriefRemovePrefix}"`
- RemoveFieldPrefix string `name:"removeFieldPrefix" short:"rf" brief:"{CGenDaoBriefRemoveFieldPrefix}"`
- JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
- ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
- DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
- DoPath string `name:"doPath" short:"o" brief:"{CGenDaoBriefDoPath}" d:"model/do"`
- EntityPath string `name:"entityPath" short:"e" brief:"{CGenDaoBriefEntityPath}" d:"model/entity"`
- TplDaoIndexPath string `name:"tplDaoIndexPath" short:"t1" brief:"{CGenDaoBriefTplDaoIndexPath}"`
- TplDaoInternalPath string `name:"tplDaoInternalPath" short:"t2" brief:"{CGenDaoBriefTplDaoInternalPath}"`
- TplDaoDoPath string `name:"tplDaoDoPath" short:"t3" brief:"{CGenDaoBriefTplDaoDoPathPath}"`
- TplDaoEntityPath string `name:"tplDaoEntityPath" short:"t4" brief:"{CGenDaoBriefTplDaoEntityPath}"`
- StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
- WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
- GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
- OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
- DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
- NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
- NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
- Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
-
- TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
- FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`
-
- // internal usage purpose.
- genItems *CGenDaoInternalGenItems
- }
- CGenDaoOutput struct{}
-
- CGenDaoInternalInput struct {
- CGenDaoInput
- DB gdb.DB
- TableNames []string
- NewTableNames []string
- }
- DBTableFieldName = string
- DBFieldTypeName = string
- CustomAttributeType struct {
- Type string `brief:"custom attribute type name"`
- Import string `brief:"custom import for this type"`
- }
-)
-
func (c CGenDao) Dao(ctx context.Context, in CGenDaoInput) (out *CGenDaoOutput, err error) {
in.genItems = newCGenDaoInternalGenItems()
if in.Link != "" {
@@ -278,9 +149,12 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
// It uses user passed database configuration.
if in.Link != "" {
var tempGroup = gtime.TimestampNanoStr()
- gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
+ err = gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
Link: in.Link,
})
+ if err != nil {
+ mlog.Fatalf(`database configuration failed: %+v`, err)
+ }
if db, err = gdb.Instance(tempGroup); err != nil {
mlog.Fatalf(`database initialization failed: %+v`, err)
}
@@ -321,24 +195,51 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
}
// Generating dao & model go files one by one according to given table name.
- newTableNames := make([]string, len(tableNames))
+ var (
+ newTableNames = make([]string, len(tableNames))
+ shardingNewTableSet = gset.NewStrSet()
+ )
for i, tableName := range tableNames {
newTableName := tableName
for _, v := range removePrefixArray {
newTableName = gstr.TrimLeftStr(newTableName, v, 1)
}
+ if len(in.ShardingPattern) > 0 {
+ for _, pattern := range in.ShardingPattern {
+ var (
+ match []string
+ regPattern = gstr.Replace(pattern, "?", `(.+)`)
+ )
+ match, err = gregex.MatchString(regPattern, newTableName)
+ if err != nil {
+ mlog.Fatalf(`invalid sharding pattern "%s": %+v`, pattern, err)
+ }
+ if len(match) < 2 {
+ continue
+ }
+ newTableName = gstr.Replace(pattern, "?", "")
+ newTableName = gstr.Trim(newTableName, `_.-`)
+ if shardingNewTableSet.Contains(newTableName) {
+ tableNames[i] = ""
+ continue
+ }
+ shardingNewTableSet.Add(newTableName)
+ }
+ }
newTableName = in.Prefix + newTableName
newTableNames[i] = newTableName
}
+ tableNames = garray.NewStrArrayFrom(tableNames).FilterEmpty().Slice()
in.genItems.Scale()
// Dao: index and internal.
generateDao(ctx, CGenDaoInternalInput{
- CGenDaoInput: in,
- DB: db,
- TableNames: tableNames,
- NewTableNames: newTableNames,
+ CGenDaoInput: in,
+ DB: db,
+ TableNames: tableNames,
+ NewTableNames: newTableNames,
+ ShardingTableSet: shardingNewTableSet,
})
// Do.
generateDo(ctx, CGenDaoInternalInput{
@@ -411,13 +312,15 @@ func getImportPartContent(ctx context.Context, source string, isDo bool, appendI
return packageImportsStr
}
-func replaceDefaultVar(in CGenDaoInternalInput, origin string) string {
- var tplCreatedAtDatetimeStr string
- var tplDatetimeStr string = createdAt.String()
+func assignDefaultVar(view *gview.View, in CGenDaoInternalInput) {
+ var (
+ tplCreatedAtDatetimeStr string
+ tplDatetimeStr = createdAt.String()
+ )
if in.WithTime {
tplCreatedAtDatetimeStr = fmt.Sprintf(`Created at %s`, tplDatetimeStr)
}
- return gstr.ReplaceByMap(origin, g.MapStrStr{
+ view.Assigns(g.Map{
tplVarDatetimeStr: tplDatetimeStr,
tplVarCreatedAtDatetimeStr: tplCreatedAtDatetimeStr,
})
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
index 2b152fa..1e784cb 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
@@ -18,6 +18,7 @@ import (
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gview"
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/library/hggen/internal/consts"
@@ -32,22 +33,30 @@ func generateDao(ctx context.Context, in CGenDaoInternalInput) {
)
in.genItems.AppendDirPath(dirPathDao)
for i := 0; i < len(in.TableNames); i++ {
+ var (
+ realTableName = in.TableNames[i]
+ newTableName = in.NewTableNames[i]
+ )
generateDaoSingle(ctx, generateDaoSingleInput{
CGenDaoInternalInput: in,
- TableName: in.TableNames[i],
- NewTableName: in.NewTableNames[i],
+ TableName: realTableName,
+ NewTableName: newTableName,
DirPathDao: dirPathDao,
DirPathDaoInternal: dirPathDaoInternal,
+ IsSharding: in.ShardingTableSet.Contains(newTableName),
})
}
}
type generateDaoSingleInput struct {
CGenDaoInternalInput
- TableName string // TableName specifies the table name of the table.
- NewTableName string // NewTableName specifies the prefix-stripped name of the table.
+ // TableName specifies the table name of the table.
+ TableName string
+ // NewTableName specifies the prefix-stripped or custom edited name of the table.
+ NewTableName string
DirPathDao string
DirPathDaoInternal string
+ IsSharding bool
}
// generateDaoSingle generates the dao and model content of given table.
@@ -109,17 +118,26 @@ func generateDaoIndex(in generateDaoIndexInput) {
// It should add path to result slice whenever it would generate the path file or not.
in.genItems.AppendGeneratedFilePath(path)
if in.OverwriteDao || !gfile.Exists(path) {
- indexContent := gstr.ReplaceByMap(
- getTemplateFromPathOrDefault(in.TplDaoIndexPath, consts.TemplateGenDaoIndexContent),
- g.MapStrStr{
- tplVarImportPrefix: in.ImportPrefix,
- tplVarTableName: in.TableName,
- tplVarTableNameCamelCase: in.TableNameCamelCase,
- tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
- tplVarPackageName: filepath.Base(in.DaoPath),
- })
- indexContent = replaceDefaultVar(in.CGenDaoInternalInput, indexContent)
- if err := gfile.PutContents(path, strings.TrimSpace(indexContent)); err != nil {
+ var (
+ ctx = context.Background()
+ tplContent = getTemplateFromPathOrDefault(
+ in.TplDaoIndexPath, consts.TemplateGenDaoIndexContent,
+ )
+ )
+ tplView.ClearAssigns()
+ tplView.Assigns(gview.Params{
+ tplVarTableSharding: in.IsSharding,
+ tplVarImportPrefix: in.ImportPrefix,
+ tplVarTableName: in.TableName,
+ tplVarTableNameCamelCase: in.TableNameCamelCase,
+ tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
+ tplVarPackageName: filepath.Base(in.DaoPath),
+ })
+ indexContent, err := tplView.ParseContent(ctx, tplContent)
+ if err != nil {
+ mlog.Fatalf("parsing template content failed: %v", err)
+ }
+ if err = gfile.PutContents(path, strings.TrimSpace(indexContent)); err != nil {
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
} else {
utils.GoFmt(path)
@@ -138,20 +156,29 @@ type generateDaoInternalInput struct {
}
func generateDaoInternal(in generateDaoInternalInput) {
+ var (
+ ctx = context.Background()
+ removeFieldPrefixArray = gstr.SplitAndTrim(in.RemoveFieldPrefix, ",")
+ tplContent = getTemplateFromPathOrDefault(
+ in.TplDaoInternalPath, consts.TemplateGenDaoInternalContent,
+ )
+ )
+ tplView.ClearAssigns()
+ tplView.Assigns(gview.Params{
+ tplVarImportPrefix: in.ImportPrefix,
+ tplVarTableName: in.TableName,
+ tplVarGroupName: in.Group,
+ tplVarTableNameCamelCase: in.TableNameCamelCase,
+ tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
+ tplVarColumnDefine: gstr.Trim(generateColumnDefinitionForDao(in.FieldMap, removeFieldPrefixArray)),
+ tplVarColumnNames: gstr.Trim(generateColumnNamesForDao(in.FieldMap, removeFieldPrefixArray)),
+ })
+ assignDefaultVar(tplView, in.CGenDaoInternalInput)
+ modelContent, err := tplView.ParseContent(ctx, tplContent)
+ if err != nil {
+ mlog.Fatalf("parsing template content failed: %v", err)
+ }
path := filepath.FromSlash(gfile.Join(in.DirPathDaoInternal, in.FileName+".go"))
- removeFieldPrefixArray := gstr.SplitAndTrim(in.RemoveFieldPrefix, ",")
- modelContent := gstr.ReplaceByMap(
- getTemplateFromPathOrDefault(in.TplDaoInternalPath, consts.TemplateGenDaoInternalContent),
- g.MapStrStr{
- tplVarImportPrefix: in.ImportPrefix,
- tplVarTableName: in.TableName,
- tplVarGroupName: in.Group,
- tplVarTableNameCamelCase: in.TableNameCamelCase,
- tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
- tplVarColumnDefine: gstr.Trim(generateColumnDefinitionForDao(in.FieldMap, removeFieldPrefixArray)),
- tplVarColumnNames: gstr.Trim(generateColumnNamesForDao(in.FieldMap, removeFieldPrefixArray)),
- })
- modelContent = replaceDefaultVar(in.CGenDaoInternalInput, modelContent)
in.genItems.AppendGeneratedFilePath(path)
if err := gfile.PutContents(path, strings.TrimSpace(modelContent)); err != nil {
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go
index fabb4e6..0d5f791 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go
@@ -12,8 +12,8 @@ import (
"path/filepath"
"strings"
- "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gview"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
@@ -78,16 +78,23 @@ func generateDo(ctx context.Context, in CGenDaoInternalInput) {
func generateDoContent(
ctx context.Context, in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string,
) string {
- doContent := gstr.ReplaceByMap(
- getTemplateFromPathOrDefault(in.TplDaoDoPath, consts.TemplateGenDaoDoContent),
- g.MapStrStr{
- tplVarTableName: tableName,
- tplVarPackageImports: getImportPartContent(ctx, structDefine, true, nil),
- tplVarTableNameCamelCase: tableNameCamelCase,
- tplVarStructDefine: structDefine,
- tplVarPackageName: filepath.Base(in.DoPath),
- },
+ var (
+ tplContent = getTemplateFromPathOrDefault(
+ in.TplDaoDoPath, consts.TemplateGenDaoDoContent,
+ )
)
- doContent = replaceDefaultVar(in, doContent)
+ tplView.ClearAssigns()
+ tplView.Assigns(gview.Params{
+ tplVarTableName: tableName,
+ tplVarPackageImports: getImportPartContent(ctx, structDefine, true, nil),
+ tplVarTableNameCamelCase: tableNameCamelCase,
+ tplVarStructDefine: structDefine,
+ tplVarPackageName: filepath.Base(in.DoPath),
+ })
+ assignDefaultVar(tplView, in)
+ doContent, err := tplView.ParseContent(ctx, tplContent)
+ if err != nil {
+ mlog.Fatalf("parsing template content failed: %v", err)
+ }
return doContent
}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go
index d9f8675..5eeafe7 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go
@@ -11,8 +11,8 @@ import (
"path/filepath"
"strings"
- "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gview"
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/library/hggen/internal/consts"
@@ -63,16 +63,23 @@ func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
func generateEntityContent(
ctx context.Context, in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string, appendImports []string,
) string {
- entityContent := gstr.ReplaceByMap(
- getTemplateFromPathOrDefault(in.TplDaoEntityPath, consts.TemplateGenDaoEntityContent),
- g.MapStrStr{
- tplVarTableName: tableName,
- tplVarPackageImports: getImportPartContent(ctx, structDefine, false, appendImports),
- tplVarTableNameCamelCase: tableNameCamelCase,
- tplVarStructDefine: structDefine,
- tplVarPackageName: filepath.Base(in.EntityPath),
- },
+ var (
+ tplContent = getTemplateFromPathOrDefault(
+ in.TplDaoEntityPath, consts.TemplateGenDaoEntityContent,
+ )
)
- entityContent = replaceDefaultVar(in, entityContent)
+ tplView.ClearAssigns()
+ tplView.Assigns(gview.Params{
+ tplVarTableName: tableName,
+ tplVarPackageImports: getImportPartContent(ctx, structDefine, false, appendImports),
+ tplVarTableNameCamelCase: tableNameCamelCase,
+ tplVarStructDefine: structDefine,
+ tplVarPackageName: filepath.Base(in.EntityPath),
+ })
+ assignDefaultVar(tplView, in)
+ entityContent, err := tplView.ParseContent(ctx, tplContent)
+ if err != nil {
+ mlog.Fatalf("parsing template content failed: %v", err)
+ }
return entityContent
}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_gen_item.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_gen_item.go
index 09fa7fe..fcb7bf9 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_gen_item.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_gen_item.go
@@ -38,14 +38,14 @@ func (i *CGenDaoInternalGenItems) SetClear(clear bool) {
i.Items[i.index].Clear = clear
}
-func (i CGenDaoInternalGenItems) AppendDirPath(storageDirPath string) {
+func (i *CGenDaoInternalGenItems) AppendDirPath(storageDirPath string) {
i.Items[i.index].StorageDirPaths = append(
i.Items[i.index].StorageDirPaths,
storageDirPath,
)
}
-func (i CGenDaoInternalGenItems) AppendGeneratedFilePath(generatedFilePath string) {
+func (i *CGenDaoInternalGenItems) AppendGeneratedFilePath(generatedFilePath string) {
i.Items[i.index].GeneratedFilePaths = append(
i.Items[i.index].GeneratedFilePaths,
generatedFilePath,
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_tag.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_tag.go
new file mode 100644
index 0000000..0487184
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_tag.go
@@ -0,0 +1,149 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package gendao
+
+import (
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/util/gtag"
+)
+
+const (
+ CGenDaoConfig = `gfcli.gen.dao`
+ CGenDaoUsage = `gf gen dao [OPTION]`
+ CGenDaoBrief = `automatically generate go files for dao/do/entity`
+ CGenDaoEg = `
+gf gen dao
+gf gen dao -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
+gf gen dao -p ./model -g user-center -t user,user_detail,user_login
+gf gen dao -r user_
+`
+
+ CGenDaoAd = `
+CONFIGURATION SUPPORT
+ Options are also supported by configuration file.
+ It's suggested using configuration file instead of command line arguments making producing.
+ The configuration node name is "gfcli.gen.dao", which also supports multiple databases, for example(config.yaml):
+ gfcli:
+ gen:
+ dao:
+ - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
+ tables: "order,products"
+ jsonCase: "CamelLower"
+ - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/primary"
+ path: "./my-app"
+ prefix: "primary_"
+ tables: "user, userDetail"
+ typeMapping:
+ decimal:
+ type: decimal.Decimal
+ import: github.com/shopspring/decimal
+ numeric:
+ type: string
+ fieldMapping:
+ table_name.field_name:
+ type: decimal.Decimal
+ import: github.com/shopspring/decimal
+`
+ CGenDaoBriefPath = `directory path for generated files`
+ CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
+ CGenDaoBriefTables = `generate models only for given tables, multiple table names separated with ','`
+ CGenDaoBriefTablesEx = `generate models excluding given tables, multiple table names separated with ','`
+ CGenDaoBriefPrefix = `add prefix for all table of specified link/database tables`
+ CGenDaoBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
+ CGenDaoBriefRemoveFieldPrefix = `remove specified prefix of the field, multiple prefix separated with ','`
+ CGenDaoBriefStdTime = `use time.Time from stdlib instead of gtime.Time for generated time/date fields of tables`
+ CGenDaoBriefWithTime = `add created time for auto produced go files`
+ CGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
+ CGenDaoBriefImportPrefix = `custom import prefix for generated go files`
+ CGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
+ CGenDaoBriefDoPath = `directory path for storing generated do files under path`
+ CGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
+ CGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
+ CGenDaoBriefModelFile = `custom file name for storing generated model content`
+ CGenDaoBriefModelFileForDao = `custom file name generating model for DAO operations like Where/Data. It's empty in default`
+ CGenDaoBriefDescriptionTag = `add comment to description tag for each field`
+ CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
+ CGenDaoBriefNoModelComment = `no model comment will be added for each field`
+ CGenDaoBriefClear = `delete all generated go files that do not exist in database`
+ CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
+ CGenDaoBriefFieldMapping = `custom local type mapping for generated struct attributes relevant to specific fields of table`
+ CGenDaoBriefShardingPattern = `sharding pattern for table name, e.g. "users_?" will be replace tables "users_001,users_002,..." to "users" dao`
+ CGenDaoBriefGroup = `
+specifying the configuration group name of database for generated ORM instance,
+it's not necessary and the default value is "default"
+`
+ CGenDaoBriefJsonCase = `
+generated json tag case for model struct, cases are as follows:
+| Case | Example |
+|---------------- |--------------------|
+| Camel | AnyKindOfString |
+| CamelLower | anyKindOfString | default
+| Snake | any_kind_of_string |
+| SnakeScreaming | ANY_KIND_OF_STRING |
+| SnakeFirstUpper | rgb_code_md5 |
+| Kebab | any-kind-of-string |
+| KebabScreaming | ANY-KIND-OF-STRING |
+`
+ CGenDaoBriefTplDaoIndexPath = `template file path for dao index file`
+ CGenDaoBriefTplDaoInternalPath = `template file path for dao internal file`
+ CGenDaoBriefTplDaoDoPathPath = `template file path for dao do file`
+ CGenDaoBriefTplDaoEntityPath = `template file path for dao entity file`
+
+ tplVarTableName = `TplTableName`
+ tplVarTableNameCamelCase = `TplTableNameCamelCase`
+ tplVarTableNameCamelLowerCase = `TplTableNameCamelLowerCase`
+ tplVarTableSharding = `TplTableSharding`
+ tplVarPackageImports = `TplPackageImports`
+ tplVarImportPrefix = `TplImportPrefix`
+ tplVarStructDefine = `TplStructDefine`
+ tplVarColumnDefine = `TplColumnDefine`
+ tplVarColumnNames = `TplColumnNames`
+ tplVarGroupName = `TplGroupName`
+ tplVarDatetimeStr = `TplDatetimeStr`
+ tplVarCreatedAtDatetimeStr = `TplCreatedAtDatetimeStr`
+ tplVarPackageName = `TplPackageName`
+)
+
+func init() {
+ gtag.Sets(g.MapStrStr{
+ `CGenDaoConfig`: CGenDaoConfig,
+ `CGenDaoUsage`: CGenDaoUsage,
+ `CGenDaoBrief`: CGenDaoBrief,
+ `CGenDaoEg`: CGenDaoEg,
+ `CGenDaoAd`: CGenDaoAd,
+ `CGenDaoBriefPath`: CGenDaoBriefPath,
+ `CGenDaoBriefLink`: CGenDaoBriefLink,
+ `CGenDaoBriefTables`: CGenDaoBriefTables,
+ `CGenDaoBriefTablesEx`: CGenDaoBriefTablesEx,
+ `CGenDaoBriefPrefix`: CGenDaoBriefPrefix,
+ `CGenDaoBriefRemovePrefix`: CGenDaoBriefRemovePrefix,
+ `CGenDaoBriefRemoveFieldPrefix`: CGenDaoBriefRemoveFieldPrefix,
+ `CGenDaoBriefStdTime`: CGenDaoBriefStdTime,
+ `CGenDaoBriefWithTime`: CGenDaoBriefWithTime,
+ `CGenDaoBriefDaoPath`: CGenDaoBriefDaoPath,
+ `CGenDaoBriefDoPath`: CGenDaoBriefDoPath,
+ `CGenDaoBriefEntityPath`: CGenDaoBriefEntityPath,
+ `CGenDaoBriefGJsonSupport`: CGenDaoBriefGJsonSupport,
+ `CGenDaoBriefImportPrefix`: CGenDaoBriefImportPrefix,
+ `CGenDaoBriefOverwriteDao`: CGenDaoBriefOverwriteDao,
+ `CGenDaoBriefModelFile`: CGenDaoBriefModelFile,
+ `CGenDaoBriefModelFileForDao`: CGenDaoBriefModelFileForDao,
+ `CGenDaoBriefDescriptionTag`: CGenDaoBriefDescriptionTag,
+ `CGenDaoBriefNoJsonTag`: CGenDaoBriefNoJsonTag,
+ `CGenDaoBriefNoModelComment`: CGenDaoBriefNoModelComment,
+ `CGenDaoBriefClear`: CGenDaoBriefClear,
+ `CGenDaoBriefTypeMapping`: CGenDaoBriefTypeMapping,
+ `CGenDaoBriefFieldMapping`: CGenDaoBriefFieldMapping,
+ `CGenDaoBriefShardingPattern`: CGenDaoBriefShardingPattern,
+ `CGenDaoBriefGroup`: CGenDaoBriefGroup,
+ `CGenDaoBriefJsonCase`: CGenDaoBriefJsonCase,
+ `CGenDaoBriefTplDaoIndexPath`: CGenDaoBriefTplDaoIndexPath,
+ `CGenDaoBriefTplDaoInternalPath`: CGenDaoBriefTplDaoInternalPath,
+ `CGenDaoBriefTplDaoDoPathPath`: CGenDaoBriefTplDaoDoPathPath,
+ `CGenDaoBriefTplDaoEntityPath`: CGenDaoBriefTplDaoEntityPath,
+ })
+}
diff --git a/server/internal/library/hggen/internal/cmd/genenums/genenums.go b/server/internal/library/hggen/internal/cmd/genenums/genenums.go
index 962818f..18a34cd 100644
--- a/server/internal/library/hggen/internal/cmd/genenums/genenums.go
+++ b/server/internal/library/hggen/internal/cmd/genenums/genenums.go
@@ -8,12 +8,14 @@ package genenums
import (
"context"
+
"golang.org/x/tools/go/packages"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
+
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
)
@@ -22,8 +24,8 @@ type (
CGenEnums struct{}
CGenEnumsInput struct {
g.Meta `name:"enums" config:"{CGenEnumsConfig}" brief:"{CGenEnumsBrief}" eg:"{CGenEnumsEg}"`
- Src string `name:"src" short:"s" dc:"source folder path to be parsed" d:"."`
- Path string `name:"path" short:"p" dc:"output go file path storing enums content" d:"internal/boot/boot_enums.go"`
+ Src string `name:"src" short:"s" dc:"source folder path to be parsed" d:"api"`
+ Path string `name:"path" short:"p" dc:"output go file path storing enums content" d:"internal/packed/packed_enums.go"`
Prefixes []string `name:"prefixes" short:"x" dc:"only exports packages that starts with specified prefixes"`
}
CGenEnumsOutput struct{}
@@ -34,8 +36,8 @@ const (
CGenEnumsBrief = `parse go files in current project and generate enums go file`
CGenEnumsEg = `
gf gen enums
-gf gen enums -p internal/boot/boot_enums.go
-gf gen enums -p internal/boot/boot_enums.go -s .
+gf gen enums -p internal/packed/packed_enums.go
+gf gen enums -p internal/packed/packed_enums.go -s .
gf gen enums -x github.com/gogf
`
)
diff --git a/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go b/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go
index 2cacf95..21b9f96 100644
--- a/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go
+++ b/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go
@@ -9,6 +9,7 @@ package genenums
import (
"go/constant"
"go/types"
+
"golang.org/x/tools/go/packages"
"github.com/gogf/gf/v2/encoding/gjson"
diff --git a/server/internal/library/hggen/internal/cmd/genpb/genpb.go b/server/internal/library/hggen/internal/cmd/genpb/genpb.go
index 5139dc2..da4da07 100644
--- a/server/internal/library/hggen/internal/cmd/genpb/genpb.go
+++ b/server/internal/library/hggen/internal/cmd/genpb/genpb.go
@@ -13,6 +13,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/util/gtag"
+
"hotgo/internal/library/hggen/internal/utility/mlog"
)
diff --git a/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go b/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go
index f29ec5b..205e0c4 100644
--- a/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go
+++ b/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go
@@ -15,6 +15,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/utility/utils"
)
diff --git a/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go b/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go
index 6283f6a..2768dcd 100644
--- a/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go
+++ b/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go
@@ -16,6 +16,7 @@ import (
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
+
"hotgo/internal/library/hggen/internal/utility/utils"
)
@@ -71,6 +72,10 @@ func (c CGenPb) doTagReplacement(ctx context.Context, content string) (string, e
if !lineTagMap.IsEmpty() {
tagContent := c.listMapToStructTag(lineTagMap)
lineTagMap.Clear()
+ // If already have it, don't add it anymore
+ if gstr.Contains(gstr.StrTill(line, "` //"), tagContent) {
+ continue
+ }
line, _ = gregex.ReplaceString("`(.+)`", fmt.Sprintf("`$1 %s`", tagContent), line)
}
lines[index] = line
diff --git a/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go b/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go
index d4b8022..6320297 100644
--- a/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go
+++ b/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go
@@ -11,11 +11,13 @@ import (
"context"
"fmt"
"path/filepath"
+ "regexp"
"strings"
"github.com/olekukonko/tablewriter"
- "hotgo/internal/library/hggen/internal/utility/utils"
+ "github.com/gogf/gf/v2/container/garray"
+ "github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
@@ -25,8 +27,10 @@ import (
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/gtag"
+
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
+ "hotgo/internal/library/hggen/internal/utility/utils"
)
type (
@@ -35,14 +39,19 @@ type (
g.Meta `name:"pbentity" config:"{CGenPbEntityConfig}" brief:"{CGenPbEntityBrief}" eg:"{CGenPbEntityEg}" ad:"{CGenPbEntityAd}"`
Path string `name:"path" short:"p" brief:"{CGenPbEntityBriefPath}" d:"manifest/protobuf/pbentity"`
Package string `name:"package" short:"k" brief:"{CGenPbEntityBriefPackage}"`
+ GoPackage string `name:"goPackage" short:"g" brief:"{CGenPbEntityBriefGoPackage}"`
Link string `name:"link" short:"l" brief:"{CGenPbEntityBriefLink}"`
Tables string `name:"tables" short:"t" brief:"{CGenPbEntityBriefTables}"`
Prefix string `name:"prefix" short:"f" brief:"{CGenPbEntityBriefPrefix}"`
RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenPbEntityBriefRemovePrefix}"`
RemoveFieldPrefix string `name:"removeFieldPrefix" short:"rf" brief:"{CGenPbEntityBriefRemoveFieldPrefix}"`
+ TablesEx string `name:"tablesEx" short:"x" brief:"{CGenDaoBriefTablesEx}"`
NameCase string `name:"nameCase" short:"n" brief:"{CGenPbEntityBriefNameCase}" d:"Camel"`
JsonCase string `name:"jsonCase" short:"j" brief:"{CGenPbEntityBriefJsonCase}" d:"none"`
Option string `name:"option" short:"o" brief:"{CGenPbEntityBriefOption}"`
+
+ TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenPbEntityBriefTypeMapping}" orphan:"true"`
+ FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenPbEntityBriefFieldMapping}" orphan:"true"`
}
CGenPbEntityOutput struct{}
@@ -52,6 +61,13 @@ type (
TableName string // TableName specifies the table name of the table.
NewTableName string // NewTableName specifies the prefix-stripped name of the table.
}
+
+ DBTableFieldName = string
+ DBFieldTypeName = string
+ CustomAttributeType struct {
+ Type string `brief:"custom attribute type name"`
+ Import string `brief:"custom import for this type"`
+ }
)
const (
@@ -69,7 +85,7 @@ gf gen pbentity -r user_
CGenPbEntityAd = `
CONFIGURATION SUPPORT
Options are also supported by configuration file.
- It's suggested using configuration file instead of command line arguments making producing.
+ It's suggested using configuration file instead of command line arguments making producing.
The configuration node name is "gf.gen.pbentity", which also supports multiple databases, for example(config.yaml):
gfcli:
gen:
@@ -88,13 +104,22 @@ CONFIGURATION SUPPORT
option go_package = "protobuf/demos";
option java_package = "protobuf/demos";
option php_namespace = "protobuf/demos";
+ typeMapping:
+ json:
+ type: google.protobuf.Value
+ import: google/protobuf/struct.proto
+ jsonb:
+ type: google.protobuf.Value
+ import: google/protobuf/struct.proto
`
CGenPbEntityBriefPath = `directory path for generated files storing`
CGenPbEntityBriefPackage = `package path for all entity proto files`
+ CGenPbEntityBriefGoPackage = `go package path for all entity proto files`
CGenPbEntityBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
CGenPbEntityBriefTables = `generate models only for given tables, multiple table names separated with ','`
CGenPbEntityBriefPrefix = `add specified prefix for all entity names and entity proto files`
CGenPbEntityBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
+ CGenPbEntityBriefTablesEx = `generate all models exclude the specified tables, multiple prefix separated with ','`
CGenPbEntityBriefRemoveFieldPrefix = `remove specified prefix of the field, multiple prefix separated with ','`
CGenPbEntityBriefOption = `extra protobuf options`
CGenPbEntityBriefGroup = `
@@ -106,7 +131,7 @@ it's not necessary and the default value is "default"
case for message attribute names, default is "Camel":
| Case | Example |
|---------------- |--------------------|
-| Camel | AnyKindOfString |
+| Camel | AnyKindOfString |
| CamelLower | anyKindOfString | default
| Snake | any_kind_of_string |
| SnakeScreaming | ANY_KIND_OF_STRING |
@@ -119,8 +144,95 @@ case for message attribute names, default is "Camel":
case for message json tag, cases are the same as "nameCase", default "CamelLower".
set it to "none" to ignore json tag generating.
`
+
+ CGenPbEntityBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
+ CGenPbEntityBriefFieldMapping = `custom local type mapping for generated struct attributes relevant to specific fields of table`
)
+var defaultTypeMapping = map[DBFieldTypeName]CustomAttributeType{
+ // gdb.LocalTypeString
+ "string": {
+ Type: "string",
+ },
+ // gdb.LocalTypeTime
+ // "time": {
+ // Type: "google.protobuf.Duration",
+ // Import: "google/protobuf/duration.proto",
+ // },
+ // gdb.LocalTypeDate
+ "date": {
+ Type: "google.protobuf.Timestamp",
+ Import: "google/protobuf/timestamp.proto",
+ },
+ // gdb.LocalTypeDatetime
+ "datetime": {
+ Type: "google.protobuf.Timestamp",
+ Import: "google/protobuf/timestamp.proto",
+ },
+ // gdb.LocalTypeInt
+ "int": {
+ Type: "int32",
+ },
+ // gdb.LocalTypeUint
+ "uint": {
+ Type: "uint32",
+ },
+ // gdb.LocalTypeInt64
+ "int64": {
+ Type: "int64",
+ },
+ // gdb.LocalTypeUint64
+ "uint64": {
+ Type: "uint64",
+ },
+ // gdb.LocalTypeIntSlice
+ "[]int": {
+ Type: "repeated int32",
+ },
+ // gdb.LocalTypeInt64Slice
+ "[]int64": {
+ Type: "repeated int64",
+ },
+ // gdb.LocalTypeUint64Slice
+ "[]uint64": {
+ Type: "repeated uint64",
+ },
+ // gdb.LocalTypeInt64Bytes
+ "int64-bytes": {
+ Type: "repeated int64",
+ },
+ // gdb.LocalTypeUint64Bytes
+ "uint64-bytes": {
+ Type: "repeated uint64",
+ },
+ // gdb.LocalTypeFloat32
+ "float32": {
+ Type: "float",
+ },
+ // gdb.LocalTypeFloat64
+ "float64": {
+ Type: "double",
+ },
+ // gdb.LocalTypeBytes
+ "[]byte": {
+ Type: "bytes",
+ },
+ // gdb.LocalTypeBool
+ "bool": {
+ Type: "bool",
+ },
+ // gdb.LocalTypeJson
+ // "json": {
+ // Type: "google.protobuf.Value",
+ // Import: "google/protobuf/struct.proto",
+ // },
+ // gdb.LocalTypeJsonb
+ // "jsonb": {
+ // Type: "google.protobuf.Value",
+ // Import: "google/protobuf/struct.proto",
+ // },
+}
+
func init() {
gtag.Sets(g.MapStrStr{
`CGenPbEntityConfig`: CGenPbEntityConfig,
@@ -129,15 +241,19 @@ func init() {
`CGenPbEntityAd`: CGenPbEntityAd,
`CGenPbEntityBriefPath`: CGenPbEntityBriefPath,
`CGenPbEntityBriefPackage`: CGenPbEntityBriefPackage,
+ `CGenPbEntityBriefGoPackage`: CGenPbEntityBriefGoPackage,
`CGenPbEntityBriefLink`: CGenPbEntityBriefLink,
`CGenPbEntityBriefTables`: CGenPbEntityBriefTables,
`CGenPbEntityBriefPrefix`: CGenPbEntityBriefPrefix,
`CGenPbEntityBriefRemovePrefix`: CGenPbEntityBriefRemovePrefix,
+ `CGenPbEntityBriefTablesEx`: CGenPbEntityBriefTablesEx,
`CGenPbEntityBriefRemoveFieldPrefix`: CGenPbEntityBriefRemoveFieldPrefix,
`CGenPbEntityBriefGroup`: CGenPbEntityBriefGroup,
`CGenPbEntityBriefNameCase`: CGenPbEntityBriefNameCase,
`CGenPbEntityBriefJsonCase`: CGenPbEntityBriefJsonCase,
`CGenPbEntityBriefOption`: CGenPbEntityBriefOption,
+ `CGenPbEntityBriefTypeMapping`: CGenPbEntityBriefTypeMapping,
+ `CGenPbEntityBriefFieldMapping`: CGenPbEntityBriefFieldMapping,
})
}
@@ -181,6 +297,9 @@ func doGenPbEntityForArray(ctx context.Context, index int, in CGenPbEntityInput)
in.Package = modName + "/" + defaultPackageSuffix
}
removePrefixArray := gstr.SplitAndTrim(in.RemovePrefix, ",")
+
+ excludeTables := gset.NewStrSetFrom(gstr.SplitAndTrim(in.TablesEx, ","))
+
// It uses user passed database configuration.
if in.Link != "" {
var (
@@ -210,8 +329,21 @@ func doGenPbEntityForArray(ctx context.Context, index int, in CGenPbEntityInput)
mlog.Fatalf("fetching tables failed: \n %v", err)
}
}
+ // merge default typeMapping to input typeMapping.
+ if in.TypeMapping == nil {
+ in.TypeMapping = defaultTypeMapping
+ } else {
+ for key, typeMapping := range defaultTypeMapping {
+ if _, ok := in.TypeMapping[key]; !ok {
+ in.TypeMapping[key] = typeMapping
+ }
+ }
+ }
for _, tableName := range tableNames {
+ if excludeTables.Contains(tableName) {
+ continue
+ }
newTableName := tableName
for _, v := range removePrefixArray {
newTableName = gstr.TrimLeftStr(newTableName, v, 1)
@@ -234,20 +366,29 @@ func generatePbEntityContentFile(ctx context.Context, in CGenPbEntityInternalInp
// Change the `newTableName` if `Prefix` is given.
newTableName := in.Prefix + in.NewTableName
var (
- imports string
- tableNameCamelCase = gstr.CaseCamel(newTableName)
- tableNameSnakeCase = gstr.CaseSnake(newTableName)
- entityMessageDefine = generateEntityMessageDefinition(tableNameCamelCase, fieldMap, in)
- fileName = gstr.Trim(tableNameSnakeCase, "-_.")
- path = filepath.FromSlash(gfile.Join(in.Path, fileName+".proto"))
+ tableNameCamelCase = gstr.CaseCamel(newTableName)
+ tableNameSnakeCase = gstr.CaseSnake(newTableName)
+ entityMessageDefine, appendImports = generateEntityMessageDefinition(tableNameCamelCase, fieldMap, in)
+ fileName = gstr.Trim(tableNameSnakeCase, "-_.")
+ path = filepath.FromSlash(gfile.Join(in.Path, fileName+".proto"))
)
- if gstr.Contains(entityMessageDefine, "google.protobuf.Timestamp") {
- imports = `import "google/protobuf/timestamp.proto";`
+ packageImportStr := ""
+ var packageImportsArray = garray.NewStrArray()
+ if len(appendImports) > 0 {
+ for _, appendImport := range appendImports {
+ packageImportStr = fmt.Sprintf(`import "%s";`, appendImport)
+ if packageImportsArray.Search(packageImportStr) == -1 {
+ packageImportsArray.Append(packageImportStr)
+ }
+ }
+ }
+ if in.GoPackage == "" {
+ in.GoPackage = in.Package
}
entityContent := gstr.ReplaceByMap(getTplPbEntityContent(""), g.MapStrStr{
- "{Imports}": imports,
+ "{Imports}": packageImportsArray.Join("\n"),
"{PackageName}": gfile.Basename(in.Package),
- "{GoPackage}": in.Package,
+ "{GoPackage}": in.GoPackage,
"{OptionContent}": in.Option,
"{EntityMessage}": entityMessageDefine,
})
@@ -259,14 +400,19 @@ func generatePbEntityContentFile(ctx context.Context, in CGenPbEntityInternalInp
}
// generateEntityMessageDefinition generates and returns the message definition for specified table.
-func generateEntityMessageDefinition(entityName string, fieldMap map[string]*gdb.TableField, in CGenPbEntityInternalInput) string {
+func generateEntityMessageDefinition(entityName string, fieldMap map[string]*gdb.TableField, in CGenPbEntityInternalInput) (string, []string) {
var (
- buffer = bytes.NewBuffer(nil)
- array = make([][]string, len(fieldMap))
- names = sortFieldKeyForPbEntity(fieldMap)
+ appendImports []string
+ buffer = bytes.NewBuffer(nil)
+ array = make([][]string, len(fieldMap))
+ names = sortFieldKeyForPbEntity(fieldMap)
)
for index, name := range names {
- array[index] = generateMessageFieldForPbEntity(index+1, fieldMap[name], in)
+ var imports string
+ array[index], imports = generateMessageFieldForPbEntity(index+1, fieldMap[name], in)
+ if imports != "" {
+ appendImports = append(appendImports, imports)
+ }
}
tw := tablewriter.NewWriter(buffer)
tw.SetBorder(false)
@@ -277,48 +423,38 @@ func generateEntityMessageDefinition(entityName string, fieldMap map[string]*gdb
tw.Render()
stContent := buffer.String()
// Let's do this hack of table writer for indent!
- stContent = gstr.Replace(stContent, " #", "")
+ stContent = regexp.MustCompile(`\s+\n`).ReplaceAllString(gstr.Replace(stContent, " #", ""), "\n")
buffer.Reset()
buffer.WriteString(fmt.Sprintf("message %s {\n", entityName))
buffer.WriteString(stContent)
buffer.WriteString("}")
- return buffer.String()
+ return buffer.String(), appendImports
}
// generateMessageFieldForPbEntity generates and returns the message definition for specified field.
-func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in CGenPbEntityInternalInput) []string {
+func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in CGenPbEntityInternalInput) (attrLines []string, appendImport string) {
var (
- localTypeName gdb.LocalType
- comment string
- jsonTagStr string
- err error
- ctx = gctx.GetInitCtx()
+ localTypeNameStr string
+ localTypeName gdb.LocalType
+ comment string
+ jsonTagStr string
+ err error
+ ctx = gctx.GetInitCtx()
)
- localTypeName, err = in.DB.CheckLocalTypeForField(ctx, field.Type, nil)
- if err != nil {
- panic(err)
+
+ if in.TypeMapping != nil && len(in.TypeMapping) > 0 {
+ localTypeName, err = in.DB.CheckLocalTypeForField(ctx, field.Type, nil)
+ if err != nil {
+ panic(err)
+ }
+ if localTypeName != "" {
+ if typeMapping, ok := in.TypeMapping[strings.ToLower(string(localTypeName))]; ok {
+ localTypeNameStr = typeMapping.Type
+ appendImport = typeMapping.Import
+ }
+ }
}
- var typeMapping = map[gdb.LocalType]string{
- gdb.LocalTypeString: "string",
- gdb.LocalTypeDate: "google.protobuf.Timestamp",
- gdb.LocalTypeDatetime: "google.protobuf.Timestamp",
- gdb.LocalTypeInt: "int32",
- gdb.LocalTypeUint: "uint32",
- gdb.LocalTypeInt64: "int64",
- gdb.LocalTypeUint64: "uint64",
- gdb.LocalTypeIntSlice: "repeated int32",
- gdb.LocalTypeInt64Slice: "repeated int64",
- gdb.LocalTypeUint64Slice: "repeated uint64",
- gdb.LocalTypeInt64Bytes: "repeated int64",
- gdb.LocalTypeUint64Bytes: "repeated uint64",
- gdb.LocalTypeFloat32: "float",
- gdb.LocalTypeFloat64: "double",
- gdb.LocalTypeBytes: "bytes",
- gdb.LocalTypeBool: "bool",
- gdb.LocalTypeJson: "string",
- gdb.LocalTypeJsonb: "string",
- }
- localTypeNameStr := typeMapping[localTypeName]
+
if localTypeNameStr == "" {
localTypeNameStr = "string"
}
@@ -351,12 +487,19 @@ func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in CGenPb
newFiledName = gstr.TrimLeftStr(newFiledName, v, 1)
}
+ if in.FieldMapping != nil && len(in.FieldMapping) > 0 {
+ if typeMapping, ok := in.FieldMapping[fmt.Sprintf("%s.%s", in.TableName, newFiledName)]; ok {
+ localTypeNameStr = typeMapping.Type
+ appendImport = typeMapping.Import
+ }
+ }
+
return []string{
" #" + localTypeNameStr,
" #" + formatCase(newFiledName, in.NameCase),
" #= " + gconv.String(index) + jsonTagStr + ";",
" #" + fmt.Sprintf(`// %s`, comment),
- }
+ }, appendImport
}
func getTplPbEntityContent(tplEntityPath string) string {
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice.go b/server/internal/library/hggen/internal/cmd/genservice/genservice.go
index fad6326..f412c06 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice.go
@@ -94,6 +94,20 @@ const (
genServiceFileLockSeconds = 10
)
+type fileInfo struct {
+ PkgItems []pkgItem
+ FuncItems []funcItem
+}
+
+type folderInfo struct {
+ SrcPackageName string
+ SrcImportedPackages *garray.SortedStrArray
+ SrcStructFunctions *gmap.ListMap
+ DstFilePath string
+
+ FileInfos []*fileInfo
+}
+
func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGenServiceOutput, err error) {
in.SrcFolder = filepath.ToSlash(in.SrcFolder)
in.SrcFolder = gstr.TrimRight(in.SrcFolder, `/`)
@@ -163,7 +177,12 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
return nil, err
}
// it will use goroutine to generate service files for each package.
- var wg = sync.WaitGroup{}
+ var (
+ folderInfos []folderInfo
+ wg = sync.WaitGroup{}
+ allStructItems = make(map[string][]string)
+ )
+
for _, srcFolderPath := range srcFolderPaths {
if !gfile.IsDir(srcFolderPath) {
continue
@@ -175,7 +194,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
if len(files) == 0 {
continue
}
- // Parse single logic package folder.
+
var (
srcPackageName = gfile.Basename(srcFolderPath)
srcImportedPackages = garray.NewSortedStrArray().SetUnique(true)
@@ -184,14 +203,46 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
c.getDstFileNameCase(srcPackageName, in.DstFileNameCase)+".go",
)
)
- generatedDstFilePathSet.Add(dstFilePath)
- // if it were to use goroutine,
- // it would cause the order of the generated functions in the file to be disordered.
+
+ folder := folderInfo{
+ SrcPackageName: srcPackageName,
+ SrcImportedPackages: srcImportedPackages,
+ SrcStructFunctions: srcStructFunctions,
+ DstFilePath: dstFilePath,
+ }
+
for _, file := range files {
- pkgItems, funcItems, err := c.parseItemsInSrc(file)
+ pkgItems, structItems, funcItems, err := c.parseItemsInSrc(file)
if err != nil {
return nil, err
}
+ for k, v := range structItems {
+ allStructItems[k] = v
+ }
+ folder.FileInfos = append(folder.FileInfos, &fileInfo{
+ PkgItems: pkgItems,
+ FuncItems: funcItems,
+ })
+ }
+
+ folderInfos = append(folderInfos, folder)
+ }
+
+ folderInfos = c.calculateStructEmbeddedFuncInfos(folderInfos, allStructItems)
+
+ for _, folder := range folderInfos {
+ // Parse single logic package folder.
+ var (
+ srcPackageName = folder.SrcPackageName
+ srcImportedPackages = folder.SrcImportedPackages
+ srcStructFunctions = folder.SrcStructFunctions
+ dstFilePath = folder.DstFilePath
+ )
+ generatedDstFilePathSet.Add(dstFilePath)
+ // if it were to use goroutine,
+ // it would cause the order of the generated functions in the file to be disordered.
+ for _, file := range folder.FileInfos {
+ pkgItems, funcItems := file.PkgItems, file.FuncItems
// Calculate imported packages for service generating.
err = c.calculateImportedItems(in, pkgItems, funcItems, srcImportedPackages)
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice_ast_parse.go b/server/internal/library/hggen/internal/cmd/genservice/genservice_ast_parse.go
index c4205cc..974ec7e 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice_ast_parse.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice_ast_parse.go
@@ -10,8 +10,10 @@ import (
"go/ast"
"go/parser"
"go/token"
+ "strings"
"github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gstructs"
"github.com/gogf/gf/v2/text/gstr"
)
@@ -32,7 +34,7 @@ type funcItem struct {
// parseItemsInSrc parses the pkgItem and funcItem from the specified file.
// It can't skip the private methods.
// It can't skip the imported packages of import alias equal to `_`.
-func (c CGenService) parseItemsInSrc(filePath string) (pkgItems []pkgItem, funcItems []funcItem, err error) {
+func (c CGenService) parseItemsInSrc(filePath string) (pkgItems []pkgItem, structItems map[string][]string, funcItems []funcItem, err error) {
var (
fileContent = gfile.GetContents(filePath)
fileSet = token.NewFileSet()
@@ -43,11 +45,107 @@ func (c CGenService) parseItemsInSrc(filePath string) (pkgItems []pkgItem, funcI
return
}
+ structItems = make(map[string][]string)
+ pkg := node.Name.Name
+ pkgAliasMap := make(map[string]string)
ast.Inspect(node, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.ImportSpec:
// parse the imported packages.
- pkgItems = append(pkgItems, c.parseImportPackages(x))
+ pkgItem := c.parseImportPackages(x)
+ pkgItems = append(pkgItems, pkgItem)
+ pkgPath := strings.Trim(pkgItem.Path, "\"")
+ pkgPath = strings.ReplaceAll(pkgPath, "\\", "/")
+ tmp := strings.Split(pkgPath, "/")
+ srcPkg := tmp[len(tmp)-1]
+ if srcPkg != pkgItem.Alias {
+ pkgAliasMap[pkgItem.Alias] = srcPkg
+ }
+ case *ast.TypeSpec: // type define
+ switch xType := x.Type.(type) {
+ case *ast.StructType: // define struct
+ // parse the struct declaration.
+ var structName = pkg + "." + x.Name.Name
+ var structEmbeddedStruct []string
+ for _, field := range xType.Fields.List {
+ if len(field.Names) > 0 || field.Tag == nil { // not anonymous field
+ continue
+ }
+
+ tagValue := strings.Trim(field.Tag.Value, "`")
+ tagValue = strings.TrimSpace(tagValue)
+ if len(tagValue) == 0 { // not set tag
+ continue
+ }
+ tags := gstructs.ParseTag(tagValue)
+
+ if v, ok := tags["gen"]; !ok || v != "extend" {
+ continue
+ }
+
+ var embeddedStruct string
+ switch v := field.Type.(type) {
+ case *ast.Ident:
+ if embeddedStruct, err = c.astExprToString(v); err != nil {
+ embeddedStruct = ""
+ break
+ }
+ embeddedStruct = pkg + "." + embeddedStruct
+ case *ast.StarExpr:
+ if embeddedStruct, err = c.astExprToString(v.X); err != nil {
+ embeddedStruct = ""
+ break
+ }
+ embeddedStruct = pkg + "." + embeddedStruct
+ case *ast.SelectorExpr:
+ var pkg string
+ if pkg, err = c.astExprToString(v.X); err != nil {
+ embeddedStruct = ""
+ break
+ }
+ if v, ok := pkgAliasMap[pkg]; ok {
+ pkg = v
+ }
+ if embeddedStruct, err = c.astExprToString(v.Sel); err != nil {
+ embeddedStruct = ""
+ break
+ }
+ embeddedStruct = pkg + "." + embeddedStruct
+ }
+
+ if embeddedStruct == "" {
+ continue
+ }
+ structEmbeddedStruct = append(structEmbeddedStruct, embeddedStruct)
+
+ }
+ if len(structEmbeddedStruct) > 0 {
+ structItems[structName] = structEmbeddedStruct
+ }
+ case *ast.Ident: // define ident
+ var (
+ structName = pkg + "." + x.Name.Name
+ typeName = pkg + "." + xType.Name
+ )
+ structItems[structName] = []string{typeName}
+ case *ast.SelectorExpr: // define selector
+ var (
+ structName = pkg + "." + x.Name.Name
+ selecotrPkg string
+ typeName string
+ )
+ if selecotrPkg, err = c.astExprToString(xType.X); err != nil {
+ break
+ }
+ if v, ok := pkgAliasMap[selecotrPkg]; ok {
+ selecotrPkg = v
+ }
+ if typeName, err = c.astExprToString(xType.Sel); err != nil {
+ break
+ }
+ typeName = selecotrPkg + "." + typeName
+ structItems[structName] = []string{typeName}
+ }
case *ast.FuncDecl:
// parse the function items.
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go b/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go
index 95b42da..4225fd9 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go
@@ -15,6 +15,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/utility/mlog"
)
@@ -150,3 +151,78 @@ func (c CGenService) tidyResult(resultSlice []map[string]string) (resultStr stri
}
return
}
+
+func (c CGenService) getStructFuncItems(structName string, allStructItems map[string][]string, funcItemsWithoutEmbed map[string][]*funcItem) (funcItems []*funcItem) {
+ funcItemNameSet := map[string]struct{}{}
+
+ if items, ok := funcItemsWithoutEmbed[structName]; ok {
+ funcItems = append(funcItems, items...)
+ for _, item := range items {
+ funcItemNameSet[item.MethodName] = struct{}{}
+ }
+ }
+
+ embeddedStructNames, ok := allStructItems[structName]
+ if !ok {
+ return
+ }
+
+ for _, embeddedStructName := range embeddedStructNames {
+ items := c.getStructFuncItems(embeddedStructName, allStructItems, funcItemsWithoutEmbed)
+
+ for _, item := range items {
+ if _, ok := funcItemNameSet[item.MethodName]; ok {
+ continue
+ }
+ funcItemNameSet[item.MethodName] = struct{}{}
+ funcItems = append(funcItems, item)
+ }
+ }
+
+ return
+}
+
+func (c CGenService) calculateStructEmbeddedFuncInfos(folderInfos []folderInfo, allStructItems map[string][]string) (newFolerInfos []folderInfo) {
+ funcItemsWithoutEmbed := make(map[string][]*funcItem)
+ funcItemMap := make(map[string]*([]funcItem))
+ funcItemsWithoutEmbedMap := make(map[string]*funcItem)
+
+ newFolerInfos = append(newFolerInfos, folderInfos...)
+
+ for _, folder := range newFolerInfos {
+ for k := range folder.FileInfos {
+ fi := folder.FileInfos[k]
+ for k := range fi.FuncItems {
+ item := &fi.FuncItems[k]
+ receiver := folder.SrcPackageName + "." + strings.ReplaceAll(item.Receiver, "*", "")
+ funcItemMap[receiver] = &fi.FuncItems
+ funcItemsWithoutEmbed[receiver] = append(funcItemsWithoutEmbed[receiver], item)
+ funcItemsWithoutEmbedMap[fmt.Sprintf("%s:%s", receiver, item.MethodName)] = item
+ }
+ }
+ }
+
+ for receiver, structItems := range allStructItems {
+ receiverName := strings.ReplaceAll(receiver, "*", "")
+ for _, structName := range structItems {
+ // Get the list of methods for the corresponding structName.
+ for _, funcItem := range c.getStructFuncItems(structName, allStructItems, funcItemsWithoutEmbed) {
+ if _, ok := funcItemsWithoutEmbedMap[fmt.Sprintf("%s:%s", receiverName, funcItem.MethodName)]; ok {
+ continue
+ }
+ if funcItemsPtr, ok := funcItemMap[receiverName]; ok {
+ newFuncItem := *funcItem
+ newFuncItem.Receiver = getReceiverName(receiver)
+ (*funcItemsPtr) = append((*funcItemsPtr), newFuncItem)
+ }
+ }
+ }
+ }
+
+ return
+}
+
+func getReceiverName(receiver string) string {
+ ss := strings.Split(receiver, ".")
+ return ss[len(ss)-1]
+}
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go b/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go
index 8b50bc7..c18249a 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go
@@ -14,6 +14,7 @@ import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
"hotgo/internal/library/hggen/internal/utility/utils"
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice_generate_template.go b/server/internal/library/hggen/internal/cmd/genservice/genservice_generate_template.go
index 0e384cf..47ac06d 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice_generate_template.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice_generate_template.go
@@ -14,6 +14,7 @@ import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
+
"hotgo/internal/library/hggen/internal/consts"
)
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go
index da0429e..ac6ee7d 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go
@@ -45,7 +45,7 @@ import (
"{ImportPath}"
)
-
+{MethodComment}
func (c *{CtrlName}) {MethodName}(ctx context.Context, req *{Version}.{MethodName}Req) (res *{Version}.{MethodName}Res, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}
@@ -66,7 +66,7 @@ import (
`
const TemplateGenCtrlControllerMethodFuncMerge = `
-
+{MethodComment}
func (c *{CtrlName}) {MethodName}(ctx context.Context, req *{Version}.{MethodName}Req) (res *{Version}.{MethodName}Res, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go
index 09f3795..f2c4670 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go
@@ -81,7 +81,7 @@ func (i *implementer) {ImplementerName}() {Module}.I{ImplementerName} {
`
-const TemplateGenCtrlSdkImplementerFunc = `
+const TemplateGenCtrlSdkImplementerFunc = `{MethodComment}
func (i *implementer{ImplementerName}) {MethodName}(ctx context.Context, req *{Version}.{MethodName}Req) (res *{Version}.{MethodName}Res, err error) {
err = i.Request(ctx, req, &res)
return
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go
index 5af47e4..d1a82bc 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go
@@ -8,38 +8,57 @@ package consts
const TemplateGenDaoIndexContent = `
// =================================================================================
-// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
-package {TplPackageName}
+package {{.TplPackageName}}
import (
- "{TplImportPrefix}/internal"
+ "{{.TplImportPrefix}}/internal"
)
-// internal{TplTableNameCamelCase}Dao is internal type for wrapping internal DAO implements.
-type internal{TplTableNameCamelCase}Dao = *internal.{TplTableNameCamelCase}Dao
-
-// {TplTableNameCamelLowerCase}Dao is the data access object for table {TplTableName}.
-// You can define custom methods on it to extend its functionality as you wish.
-type {TplTableNameCamelLowerCase}Dao struct {
- internal{TplTableNameCamelCase}Dao
+// {{.TplTableNameCamelLowerCase}}Dao is the data access object for the table {{.TplTableName}}.
+// You can define custom methods on it to extend its functionality as needed.
+type {{.TplTableNameCamelLowerCase}}Dao struct {
+ *internal.{{.TplTableNameCamelCase}}Dao
}
var (
- // {TplTableNameCamelCase} is globally public accessible object for table {TplTableName} operations.
- {TplTableNameCamelCase} = {TplTableNameCamelLowerCase}Dao{
- internal.New{TplTableNameCamelCase}Dao(),
+ // {{.TplTableNameCamelCase}} is a globally accessible object for table {{.TplTableName}} operations.
+ {{.TplTableNameCamelCase}} = {{.TplTableNameCamelLowerCase}}Dao{
+{{- if .TplTableSharding -}}
+ internal.New{{.TplTableNameCamelCase}}Dao(userShardingHandler),
+{{- else -}}
+ internal.New{{.TplTableNameCamelCase}}Dao(),
+{{- end -}}
}
)
-// Fill with you ideas below.
+{{if .TplTableSharding -}}
+// userShardingHandler is the handler for sharding operations.
+// You can fill this sharding handler with your custom implementation.
+func userShardingHandler(m *gdb.Model) *gdb.Model {
+ m = m.Sharding(gdb.ShardingConfig{
+ Table: gdb.ShardingTableConfig{
+ Enable: true,
+ Prefix: "",
+ // Replace Rule field with your custom sharding rule.
+ // Or you can use "&gdb.DefaultShardingRule{}" for default sharding rule.
+ Rule: nil,
+ },
+ Schema: gdb.ShardingSchemaConfig{},
+ })
+ return m
+}
+{{- end}}
+
+// Add your custom methods and functionality below.
`
const TemplateGenDaoInternalContent = `
// ==========================================================================
-// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {{.TplCreatedAtDatetimeStr}}
// ==========================================================================
package internal
@@ -51,64 +70,70 @@ import (
"github.com/gogf/gf/v2/frame/g"
)
-// {TplTableNameCamelCase}Dao is the data access object for table {TplTableName}.
-type {TplTableNameCamelCase}Dao struct {
+// {{.TplTableNameCamelCase}}Dao is the data access object for the table {{.TplTableName}}.
+type {{.TplTableNameCamelCase}}Dao struct {
table string // table is the underlying table name of the DAO.
- group string // group is the database configuration group name of current DAO.
- columns {TplTableNameCamelCase}Columns // columns contains all the column names of Table for convenient usage.
+ group string // group is the database configuration group name of the current DAO.
+ columns {{.TplTableNameCamelCase}}Columns // columns contains all the column names of Table for convenient usage.
+ handlers []gdb.ModelHandler // handlers for customized model modification.
}
-// {TplTableNameCamelCase}Columns defines and stores column names for table {TplTableName}.
-type {TplTableNameCamelCase}Columns struct {
- {TplColumnDefine}
+// {{.TplTableNameCamelCase}}Columns defines and stores column names for the table {{.TplTableName}}.
+type {{.TplTableNameCamelCase}}Columns struct {
+ {{.TplColumnDefine}}
}
-// {TplTableNameCamelLowerCase}Columns holds the columns for table {TplTableName}.
-var {TplTableNameCamelLowerCase}Columns = {TplTableNameCamelCase}Columns{
- {TplColumnNames}
+// {{.TplTableNameCamelLowerCase}}Columns holds the columns for the table {{.TplTableName}}.
+var {{.TplTableNameCamelLowerCase}}Columns = {{.TplTableNameCamelCase}}Columns{
+ {{.TplColumnNames}}
}
-// New{TplTableNameCamelCase}Dao creates and returns a new DAO object for table data access.
-func New{TplTableNameCamelCase}Dao() *{TplTableNameCamelCase}Dao {
- return &{TplTableNameCamelCase}Dao{
- group: "{TplGroupName}",
- table: "{TplTableName}",
- columns: {TplTableNameCamelLowerCase}Columns,
+// New{{.TplTableNameCamelCase}}Dao creates and returns a new DAO object for table data access.
+func New{{.TplTableNameCamelCase}}Dao(handlers ...gdb.ModelHandler) *{{.TplTableNameCamelCase}}Dao {
+ return &{{.TplTableNameCamelCase}}Dao{
+ group: "{{.TplGroupName}}",
+ table: "{{.TplTableName}}",
+ columns: {{.TplTableNameCamelLowerCase}}Columns,
+ handlers: handlers,
}
}
-// DB retrieves and returns the underlying raw database management object of current DAO.
-func (dao *{TplTableNameCamelCase}Dao) DB() gdb.DB {
+// DB retrieves and returns the underlying raw database management object of the current DAO.
+func (dao *{{.TplTableNameCamelCase}}Dao) DB() gdb.DB {
return g.DB(dao.group)
}
-// Table returns the table name of current dao.
-func (dao *{TplTableNameCamelCase}Dao) Table() string {
+// Table returns the table name of the current DAO.
+func (dao *{{.TplTableNameCamelCase}}Dao) Table() string {
return dao.table
}
-// Columns returns all column names of current dao.
-func (dao *{TplTableNameCamelCase}Dao) Columns() {TplTableNameCamelCase}Columns {
+// Columns returns all column names of the current DAO.
+func (dao *{{.TplTableNameCamelCase}}Dao) Columns() {{.TplTableNameCamelCase}}Columns {
return dao.columns
}
-// Group returns the configuration group name of database of current dao.
-func (dao *{TplTableNameCamelCase}Dao) Group() string {
+// Group returns the database configuration group name of the current DAO.
+func (dao *{{.TplTableNameCamelCase}}Dao) Group() string {
return dao.group
}
-// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
-func (dao *{TplTableNameCamelCase}Dao) Ctx(ctx context.Context) *gdb.Model {
- return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
+func (dao *{{.TplTableNameCamelCase}}Dao) Ctx(ctx context.Context) *gdb.Model {
+ model := dao.DB().Model(dao.table)
+ for _, handler := range dao.handlers {
+ model = handler(model)
+ }
+ return model.Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
-// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
-// Note that, you should not Commit or Rollback the transaction in function f
+// Note: Do not commit or roll back the transaction in function f,
// as it is automatically handled by this function.
-func (dao *{TplTableNameCamelCase}Dao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+func (dao *{{.TplTableNameCamelCase}}Dao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}
`
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go
index 320aaa9..97a404e 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go
@@ -8,13 +8,13 @@ package consts
const TemplateGenDaoDoContent = `
// =================================================================================
-// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {{.TplCreatedAtDatetimeStr}}
// =================================================================================
-package {TplPackageName}
+package {{.TplPackageName}}
-{TplPackageImports}
+{{.TplPackageImports}}
-// {TplTableNameCamelCase} is the golang structure of table {TplTableName} for DAO operations like Where/Data.
-{TplStructDefine}
+// {{.TplTableNameCamelCase}} is the golang structure of table {{.TplTableName}} for DAO operations like Where/Data.
+{{.TplStructDefine}}
`
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go
index 67a868e..c54713a 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go
@@ -8,13 +8,13 @@ package consts
const TemplateGenDaoEntityContent = `
// =================================================================================
-// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {{.TplCreatedAtDatetimeStr}}
// =================================================================================
-package {TplPackageName}
+package {{.TplPackageName}}
-{TplPackageImports}
+{{.TplPackageImports}}
-// {TplTableNameCamelCase} is the golang structure for table {TplTableName}.
-{TplStructDefine}
+// {{.TplTableNameCamelCase}} is the golang structure for table {{.TplTableName}}.
+{{.TplStructDefine}}
`
diff --git a/server/internal/library/hggen/internal/service/install.go b/server/internal/library/hggen/internal/service/install.go
index ebda00e..0c901b1 100644
--- a/server/internal/library/hggen/internal/service/install.go
+++ b/server/internal/library/hggen/internal/service/install.go
@@ -162,8 +162,14 @@ func (s serviceInstall) getGoPathBin() string {
func (s serviceInstall) getAvailablePaths() []serviceInstallAvailablePath {
var (
folderPaths []serviceInstallAvailablePath
- binaryFileName = "gf" + gfile.Ext(gfile.SelfPath())
+ binaryFileName = "gf"
)
+
+ // Windows binary file name suffix.
+ if runtime.GOOS == "windows" {
+ binaryFileName += ".exe"
+ }
+
// $GOPATH/bin
if goPathBin := s.getGoPathBin(); goPathBin != "" {
folderPaths = s.checkAndAppendToAvailablePath(
diff --git a/server/internal/library/hggen/internal/utility/utils/utils_http_download.go b/server/internal/library/hggen/internal/utility/utils/utils_http_download.go
index 3210d1d..ecedc00 100644
--- a/server/internal/library/hggen/internal/utility/utils/utils_http_download.go
+++ b/server/internal/library/hggen/internal/utility/utils/utils_http_download.go
@@ -7,13 +7,13 @@
package utils
import (
- "fmt"
"io"
"net/http"
"os"
- "strconv"
"time"
+ "github.com/schollz/progressbar/v3"
+
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/utility/mlog"
@@ -34,26 +34,16 @@ func HTTPDownloadFileWithPercent(url string, localSaveFilePath string) error {
}
defer headResp.Body.Close()
- size, err := strconv.Atoi(headResp.Header.Get("Content-Length"))
- if err != nil {
- return gerror.Wrap(err, "retrieve Content-Length failed")
- }
- doneCh := make(chan int64)
-
- go doPrintDownloadPercent(doneCh, localSaveFilePath, int64(size))
-
resp, err := http.Get(url)
if err != nil {
return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath)
}
defer resp.Body.Close()
- wroteBytesCount, err := io.Copy(out, resp.Body)
- if err != nil {
- return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath)
- }
+ bar := progressbar.NewOptions(int(resp.ContentLength), progressbar.OptionShowBytes(true), progressbar.OptionShowCount())
+ writer := io.MultiWriter(out, bar)
+ _, err = io.Copy(writer, resp.Body)
- doneCh <- wroteBytesCount
elapsed := time.Since(start)
if elapsed > time.Minute {
mlog.Printf(`download completed in %.0fm`, float64(elapsed)/float64(time.Minute))
@@ -63,45 +53,3 @@ func HTTPDownloadFileWithPercent(url string, localSaveFilePath string) error {
return nil
}
-
-func doPrintDownloadPercent(doneCh chan int64, localSaveFilePath string, total int64) {
- var (
- stop = false
- lastPercentFmt string
- )
- file, err := os.Open(localSaveFilePath)
- if err != nil {
- mlog.Fatal(err)
- }
- defer file.Close()
-
- for {
- select {
- case <-doneCh:
- stop = true
-
- default:
- fi, err := file.Stat()
- if err != nil {
- mlog.Fatal(err)
- }
- size := fi.Size()
- if size == 0 {
- size = 1
- }
- var (
- percent = float64(size) / float64(total) * 100
- percentFmt = fmt.Sprintf(`%.0f`, percent) + "%"
- )
- if lastPercentFmt != percentFmt {
- lastPercentFmt = percentFmt
- mlog.Print(percentFmt)
- }
- }
-
- if stop {
- break
- }
- time.Sleep(time.Second)
- }
-}
diff --git a/server/internal/library/hggen/internal/utility/utils/utils_test.go b/server/internal/library/hggen/internal/utility/utils/utils_test.go
index 6136870..eb20f4c 100644
--- a/server/internal/library/hggen/internal/utility/utils/utils_test.go
+++ b/server/internal/library/hggen/internal/utility/utils/utils_test.go
@@ -11,6 +11,7 @@ import (
"testing"
"github.com/gogf/gf/v2/test/gtest"
+
"hotgo/internal/library/hggen/internal/utility/utils"
)
diff --git a/server/internal/library/hggen/views/curd.go b/server/internal/library/hggen/views/curd.go
index 697d919..2c81e66 100644
--- a/server/internal/library/hggen/views/curd.go
+++ b/server/internal/library/hggen/views/curd.go
@@ -403,7 +403,7 @@ func (l *gCurd) loadView(ctx context.Context, in *CurdPreviewInput) (err error)
"importWebApi": in.options.ImportWebApi, // 导入webApi
"apiPrefix": in.options.ApiPrefix, // api前缀
"componentPrefix": componentPrefix, // vue子组件前缀
- "in": in.In, // 在模版中使用`in`参数,如:插件目录名称
+ "in": in.In, // 在模版中使用`in`参数,如:插件目录名称
})
in.view = view
@@ -453,7 +453,7 @@ func (l *gCurd) DoBuild(ctx context.Context, in *CurdBuildInput) (err error) {
// 导入失败,将sql文件删除
if err = ImportSql(ctx, vi.Path); err != nil {
- _ = gfile.Remove(vi.Path)
+ _ = gfile.RemoveAll(vi.Path)
}
return
}
diff --git a/server/internal/library/hgorm/hook/member.go b/server/internal/library/hgorm/hook/member.go
index 7d4b9d5..1cf99a8 100644
--- a/server/internal/library/hgorm/hook/member.go
+++ b/server/internal/library/hgorm/hook/member.go
@@ -109,7 +109,7 @@ var MemberSummary = gdb.HookHandler{
}
var members []*MemberSumma
- if err = g.Model("admin_member").Ctx(ctx).WhereIn("id", memberIds).Scan(&members); err != nil {
+ if err = g.Model("admin_member").Ctx(ctx).Fields(MemberSumma{}).WhereIn("id", memberIds).Scan(&members); err != nil {
return nil, err
}
diff --git a/server/internal/library/storager/mime.go b/server/internal/library/storager/mime.go
index ac77ebe..5d9ad57 100644
--- a/server/internal/library/storager/mime.go
+++ b/server/internal/library/storager/mime.go
@@ -158,26 +158,26 @@ func IsZipType(ext string) bool {
// 如果文件类型没有加入系统映射类型,默认认为不是合法的文件类型。建议将常用的上传文件类型加入映射关系。
// 当然你也可以不做限制,可以上传任意文件。但需要谨慎处理和设置相应的安全措施。
// 获取任意扩展名的扩展类型:mime.TypeByExtension(".xls")
-func GetFileMimeType(ext string) (string, error) {
+func GetFileMimeType(ext string) string {
if mime, ok := imgType[ext]; ok {
- return mime, nil
+ return mime
}
if mime, ok := docType[ext]; ok {
- return mime, nil
+ return mime
}
if mime, ok := audioType[ext]; ok {
- return mime, nil
+ return mime
}
if mime, ok := videoType[ext]; ok {
- return mime, nil
+ return mime
}
if mime, ok := zipType[ext]; ok {
- return mime, nil
+ return mime
}
if mime, ok := otherType[ext]; ok {
- return mime, nil
+ return mime
}
- return "", gerror.Newf("Invalid file type:%v", ext)
+ return "application/octet-stream"
}
// GetFileKind 获取文件上传类型
diff --git a/server/internal/library/storager/upload.go b/server/internal/library/storager/upload.go
index a2683c9..b51def8 100644
--- a/server/internal/library/storager/upload.go
+++ b/server/internal/library/storager/upload.go
@@ -103,10 +103,6 @@ func DoUpload(ctx context.Context, typ string, file *ghttp.UploadFile) (result *
// ValidateFileMeta 验证文件元数据
func ValidateFileMeta(typ string, meta *FileMeta) (err error) {
- if _, err = GetFileMimeType(meta.Ext); err != nil {
- return
- }
-
switch typ {
case KindImg:
if !IsImgType(meta.Ext) {
@@ -152,7 +148,7 @@ func ValidateFileMeta(typ string, meta *FileMeta) (err error) {
}
if len(config.FileType) > 0 && !validate.InSlice(strings.Split(config.FileType, `,`), meta.Ext) {
- err = gerror.New("上传文件类型未经允许")
+ err = gerror.Newf("上传文件类型未经允许:%v", meta.Ext)
return
}
}
@@ -190,10 +186,7 @@ func GetFileMeta(file *ghttp.UploadFile) (meta *FileMeta, err error) {
meta.Size = file.Size
meta.Ext = Ext(file.Filename)
meta.Kind = GetFileKind(meta.Ext)
- meta.MimeType, err = GetFileMimeType(meta.Ext)
- if err != nil {
- return
- }
+ meta.MimeType = GetFileMimeType(meta.Ext)
// 兼容naiveUI
naiveType := meta.MimeType
@@ -272,10 +265,7 @@ func CheckMultipart(ctx context.Context, in *CheckMultipartParams) (res *CheckMu
meta.Size = in.Size
meta.Ext = Ext(in.FileName)
meta.Kind = GetFileKind(meta.Ext)
- meta.MimeType, err = GetFileMimeType(meta.Ext)
- if err != nil {
- return
- }
+ meta.MimeType = GetFileMimeType(meta.Ext)
// 兼容naiveUI
naiveType := "text/plain"
diff --git a/server/internal/logic/admin/cash.go b/server/internal/logic/admin/cash.go
index 9e6faba..01b3b7b 100644
--- a/server/internal/logic/admin/cash.go
+++ b/server/internal/logic/admin/cash.go
@@ -17,6 +17,7 @@ import (
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
+ "hotgo/internal/library/hgorm/hook"
"hotgo/internal/library/location"
"hotgo/internal/model"
"hotgo/internal/model/entity"
@@ -80,6 +81,18 @@ func (s *sAdminCash) List(ctx context.Context, in *adminin.CashListInp) (list []
mod = mod.Where("member_id", in.MemberId)
}
+ // 用户筛选
+ if len(in.ComplexMemberId) == 2 && len(in.ComplexMemberId[0]) > 0 {
+ memberIds, err := service.AdminMember().GetComplexMemberIds(ctx, in.ComplexMemberId[0], in.ComplexMemberId[1])
+ if err != nil {
+ return nil, 0, err
+ }
+ if len(memberIds) == 0 {
+ return nil, 0, nil
+ }
+ mod = mod.WhereIn(dao.AdminOrder.Columns().MemberId, memberIds)
+ }
+
if len(in.CreatedAt) == 2 {
mod = mod.WhereBetween("created_at", gtime.New(in.CreatedAt[0]), gtime.New(in.CreatedAt[1]))
}
@@ -93,6 +106,9 @@ func (s *sAdminCash) List(ctx context.Context, in *adminin.CashListInp) (list []
mod = mod.Where("member_id", opMemberId)
}
+ // 申请人摘要信息
+ mod = mod.Hook(hook.MemberSummary)
+
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -107,19 +123,6 @@ func (s *sAdminCash) List(ctx context.Context, in *adminin.CashListInp) (list []
err = gerror.Wrap(err, consts.ErrorORM)
return
}
-
- for _, v := range list {
- var member *entity.AdminMember
- if err = dao.AdminMember.Ctx(ctx).Fields("real_name", "username").Where("id", v.MemberId).Scan(&member); err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
- return list, totalCount, err
- }
-
- if member != nil {
- v.MemberName = member.RealName
- v.MemberUser = member.Username
- }
- }
return
}
diff --git a/server/internal/logic/admin/credits_log.go b/server/internal/logic/admin/credits_log.go
index 3f5c61f..d06b66c 100644
--- a/server/internal/logic/admin/credits_log.go
+++ b/server/internal/logic/admin/credits_log.go
@@ -14,6 +14,7 @@ import (
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/hgorm/handler"
+ "hotgo/internal/library/hgorm/hook"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
@@ -174,6 +175,18 @@ func (s *sAdminCreditsLog) List(ctx context.Context, in *adminin.CreditsLogListI
mod = mod.Where(dao.AdminCreditsLog.Columns().MemberId, in.MemberId)
}
+ // 用户筛选
+ if len(in.ComplexMemberId) == 2 && len(in.ComplexMemberId[0]) > 0 {
+ memberIds, err := service.AdminMember().GetComplexMemberIds(ctx, in.ComplexMemberId[0], in.ComplexMemberId[1])
+ if err != nil {
+ return nil, 0, err
+ }
+ if len(memberIds) == 0 {
+ return nil, 0, nil
+ }
+ mod = mod.WhereIn(dao.AdminOrder.Columns().MemberId, memberIds)
+ }
+
// 查询应用id
if in.AppId != "" {
mod = mod.WhereLike(dao.AdminCreditsLog.Columns().AppId, in.AppId)
@@ -209,7 +222,10 @@ func (s *sAdminCreditsLog) List(ctx context.Context, in *adminin.CreditsLogListI
mod = mod.WhereBetween(dao.AdminCreditsLog.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
}
- totalCount, err = mod.Clone().Count(1)
+ // 操作人摘要信息
+ mod = mod.Hook(hook.MemberSummary)
+
+ totalCount, err = mod.Clone().Count()
if err != nil {
return
}
diff --git a/server/internal/logic/admin/member.go b/server/internal/logic/admin/member.go
index d4b7977..1efcd0a 100644
--- a/server/internal/logic/admin/member.go
+++ b/server/internal/logic/admin/member.go
@@ -16,6 +16,7 @@ import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
+ "github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"hotgo/internal/consts"
"hotgo/internal/dao"
@@ -28,6 +29,7 @@ import (
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
+ "hotgo/utility/convert"
"hotgo/utility/tree"
"hotgo/utility/validate"
"sync"
@@ -764,6 +766,52 @@ func (s *sAdminMember) Select(ctx context.Context, in *adminin.MemberSelectInp)
return
}
+// GetLowerIds 获取指定用户的所有下级ID集合
+func (s *sAdminMember) GetLowerIds(ctx context.Context, memberId int64) (ids []int64, err error) {
+ array, err := dao.AdminMember.Ctx(ctx).
+ Fields("id").
+ WhereLike("tree", "%"+tree.GenLabel("", memberId)+"%").
+ Array()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, v := range array {
+ ids = append(ids, v.Int64())
+ }
+ return
+}
+
+// GetComplexMemberIds 组合查找符合条件的用户ID
+func (s *sAdminMember) GetComplexMemberIds(ctx context.Context, memberIdx, opt string) (ids []int64, err error) {
+ memberId := gconv.Int64(memberIdx)
+ count, err := s.FilterAuthModel(ctx, contexts.GetUserId(ctx)).WherePri(memberId).Count()
+ if err != nil {
+ return nil, err
+ }
+ if count == 0 {
+ return
+ }
+
+ switch opt {
+ case "1": // 仅查自己
+ ids = append(ids, memberId)
+ case "2": // 仅查下级
+ ids, err = s.GetLowerIds(ctx, memberId)
+ if err != nil {
+ return nil, err
+ }
+ default: // 查全部
+ ids, err = s.GetLowerIds(ctx, memberId)
+ if err != nil {
+ return nil, err
+ }
+ ids = append(ids, memberId)
+ }
+ ids = convert.UniqueSlice(ids)
+ return
+}
+
// GetIdsByKeyword 根据关键词查找符合条件的用户ID
func (s *sAdminMember) GetIdsByKeyword(ctx context.Context, ks string) (res []int64, err error) {
ks = gstr.Trim(ks)
diff --git a/server/internal/logic/admin/order.go b/server/internal/logic/admin/order.go
index e0edd5e..f77dadf 100644
--- a/server/internal/logic/admin/order.go
+++ b/server/internal/logic/admin/order.go
@@ -13,6 +13,7 @@ import (
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm"
"hotgo/internal/library/hgorm/handler"
+ "hotgo/internal/library/hgorm/hook"
"hotgo/internal/library/payment"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
@@ -276,11 +277,26 @@ func (s *sAdminOrder) List(ctx context.Context, in *adminin.OrderListInp) (list
mod = mod.Where(dao.AdminOrder.Columns().MemberId, in.MemberId)
}
+ // 下单用户筛选
+ if len(in.ComplexMemberId) == 2 && len(in.ComplexMemberId[0]) > 0 {
+ memberIds, err := service.AdminMember().GetComplexMemberIds(ctx, in.ComplexMemberId[0], in.ComplexMemberId[1])
+ if err != nil {
+ return nil, 0, err
+ }
+ if len(memberIds) == 0 {
+ return nil, 0, nil
+ }
+ mod = mod.WhereIn(dao.AdminOrder.Columns().MemberId, memberIds)
+ }
+
mod = mod.LeftJoin(hgorm.GenJoinOnRelation(
dao.AdminOrder.Table(), dao.AdminOrder.Columns().OrderSn, // 主表表名,关联条件
dao.PayLog.Table(), "payLog", dao.PayLog.Columns().OrderSn, // 关联表表名,别名,关联条件
)...)
+ // 操作人摘要信息
+ mod = mod.Hook(hook.MemberSummary)
+
totalCount, err = mod.Clone().Count(1)
if err != nil {
return
diff --git a/server/internal/logic/sys/log.go b/server/internal/logic/sys/log.go
index 2288df4..4b71578 100644
--- a/server/internal/logic/sys/log.go
+++ b/server/internal/logic/sys/log.go
@@ -357,6 +357,18 @@ func (s *sSysLog) List(ctx context.Context, in *sysin.LogListInp) (list []*sysin
mod = mod.Where("member_id", in.MemberId)
}
+ // 操作人筛选
+ if len(in.ComplexMemberId) == 2 && len(in.ComplexMemberId[0]) > 0 {
+ memberIds, err := service.AdminMember().GetComplexMemberIds(ctx, in.ComplexMemberId[0], in.ComplexMemberId[1])
+ if err != nil {
+ return nil, 0, err
+ }
+ if len(memberIds) == 0 {
+ return nil, 0, nil
+ }
+ mod = mod.WhereIn("member_id", memberIds)
+ }
+
// 访问IP
if in.Ip != "" {
mod = mod.Where("ip", in.Ip)
diff --git a/server/internal/model/input/adminin/cash.go b/server/internal/model/input/adminin/cash.go
index 4b7e25d..bb8dfee 100644
--- a/server/internal/model/input/adminin/cash.go
+++ b/server/internal/model/input/adminin/cash.go
@@ -6,6 +6,7 @@
package adminin
import (
+ "hotgo/internal/library/hgorm/hook"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
)
@@ -24,13 +25,13 @@ type CashViewModel struct {
type CashListInp struct {
form.PageReq
form.StatusReq
- MemberId int64 `json:"memberId"`
- CreatedAt []int64 `json:"created_at"`
+ MemberId int64 `json:"memberId"`
+ CreatedAt []int64 `json:"created_at"`
+ ComplexMemberId []string `json:"complexMemberId" dc:"申请人"`
}
type CashListModel struct {
- MemberUser string `json:"memberUser"`
- MemberName string `json:"memberName"`
+ MemberBySumma *hook.MemberSumma `json:"memberBySumma" dc:"申请人信息"`
entity.AdminCash
}
diff --git a/server/internal/model/input/adminin/credits_log.go b/server/internal/model/input/adminin/credits_log.go
index ef13558..bf69297 100644
--- a/server/internal/model/input/adminin/credits_log.go
+++ b/server/internal/model/input/adminin/credits_log.go
@@ -13,6 +13,7 @@ import (
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/internal/consts"
"hotgo/internal/library/contexts"
+ "hotgo/internal/library/hgorm/hook"
"hotgo/internal/library/location"
"hotgo/internal/model/input/form"
@@ -98,15 +99,16 @@ type CreditsLogSaveIntegralModel struct {
// CreditsLogListInp 获取资产变动列表
type CreditsLogListInp struct {
form.PageReq
- Id int64 `json:"id" dc:"变动ID"`
- MemberId int64 `json:"memberId" dc:"管理员ID"`
- AppId string `json:"appId" dc:"应用id"`
- CreditType string `json:"creditType" dc:"变动类型"`
- CreditGroup string `json:"creditGroup" dc:"变动的组别"`
- Remark string `json:"remark" dc:"备注"`
- Ip string `json:"ip" dc:"操作人IP"`
- Status int `json:"status" dc:"状态"`
- CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
+ Id int64 `json:"id" dc:"变动ID"`
+ MemberId int64 `json:"memberId" dc:"管理员ID"`
+ AppId string `json:"appId" dc:"应用id"`
+ CreditType string `json:"creditType" dc:"变动类型"`
+ CreditGroup string `json:"creditGroup" dc:"变动的组别"`
+ Remark string `json:"remark" dc:"备注"`
+ Ip string `json:"ip" dc:"操作人IP"`
+ Status int `json:"status" dc:"状态"`
+ CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
+ ComplexMemberId []string `json:"complexMemberId" dc:"用户"`
}
func (in *CreditsLogListInp) Filter(ctx context.Context) (err error) {
@@ -114,21 +116,22 @@ func (in *CreditsLogListInp) Filter(ctx context.Context) (err error) {
}
type CreditsLogListModel struct {
- Id int64 `json:"id" dc:"变动ID"`
- MemberId int64 `json:"memberId" dc:"管理员ID"`
- AppId string `json:"appId" dc:"应用id"`
- AddonsName string `json:"addonsName" dc:"插件名称"`
- CreditType string `json:"creditType" dc:"变动类型"`
- CreditGroup string `json:"creditGroup" dc:"变动的组别"`
- BeforeNum float64 `json:"beforeNum" dc:"变动前"`
- Num float64 `json:"num" dc:"变动数据"`
- AfterNum float64 `json:"afterNum" dc:"变动后"`
- Remark string `json:"remark" dc:"备注"`
- Ip string `json:"ip" dc:"操作人IP"`
- MapId int64 `json:"mapId" dc:"关联ID"`
- Status int `json:"status" dc:"状态"`
- CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
- UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
+ Id int64 `json:"id" dc:"变动ID"`
+ MemberId int64 `json:"memberId" dc:"管理员ID"`
+ AppId string `json:"appId" dc:"应用id"`
+ AddonsName string `json:"addonsName" dc:"插件名称"`
+ CreditType string `json:"creditType" dc:"变动类型"`
+ CreditGroup string `json:"creditGroup" dc:"变动的组别"`
+ BeforeNum float64 `json:"beforeNum" dc:"变动前"`
+ Num float64 `json:"num" dc:"变动数据"`
+ AfterNum float64 `json:"afterNum" dc:"变动后"`
+ Remark string `json:"remark" dc:"备注"`
+ Ip string `json:"ip" dc:"操作人IP"`
+ MapId int64 `json:"mapId" dc:"关联ID"`
+ Status int `json:"status" dc:"状态"`
+ CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
+ UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
+ MemberBySumma *hook.MemberSumma `json:"memberBySumma" dc:"用户信息"`
}
// CreditsLogExportModel 导出资产变动
diff --git a/server/internal/model/input/adminin/order.go b/server/internal/model/input/adminin/order.go
index d8ed5b3..bbc2763 100644
--- a/server/internal/model/input/adminin/order.go
+++ b/server/internal/model/input/adminin/order.go
@@ -11,6 +11,7 @@ import (
"github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
"hotgo/internal/library/dict"
+ "hotgo/internal/library/hgorm/hook"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/payin"
@@ -114,6 +115,7 @@ type OrderListInp struct {
Status int `json:"status" dc:"状态"`
CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
PayLogOutTradeNo string `json:"payLogOutTradeNo" dc:"商户订单号"`
+ ComplexMemberId []string `json:"complexMemberId" dc:"下单用户"`
}
func (in *OrderListInp) Filter(ctx context.Context) (err error) {
@@ -122,8 +124,9 @@ func (in *OrderListInp) Filter(ctx context.Context) (err error) {
type OrderListModel struct {
entity.AdminOrder
- OutTradeNo string `json:"payLogOutTradeNo" dc:"商户订单号"`
- PayType string `json:"payLogPayType" dc:"支付类型"`
+ OutTradeNo string `json:"payLogOutTradeNo" dc:"商户订单号"`
+ PayType string `json:"payLogPayType" dc:"支付类型"`
+ MemberBySumma *hook.MemberSumma `json:"memberBySumma" dc:"下单用户信息"`
}
// OrderExportModel 导出充值订单
diff --git a/server/internal/model/input/sysin/log.go b/server/internal/model/input/sysin/log.go
index 6f222d7..6dd318e 100644
--- a/server/internal/model/input/sysin/log.go
+++ b/server/internal/model/input/sysin/log.go
@@ -14,16 +14,17 @@ import (
type LogListInp struct {
form.PageReq
form.StatusReq
- ReqId string `json:"reqId" dc:"对外ID"`
- Module string `json:"module" dc:"应用端口"`
- MemberId int `json:"memberId" dc:"用户ID"`
- TakeUpTime string `json:"takeUpTime" dc:"请求耗时"`
- Method string `json:"method" dc:"请求方式"`
- Url string `json:"url" dc:"请求路径"`
- Ip string `json:"ip" dc:"访问IP"`
- ErrorCode string `json:"errorCode" dc:"状态码"`
- CreatedAt []int64 `json:"createdAt" dc:"创建时间"`
- Keyword string `json:"keyword" dc:"关键词"`
+ ReqId string `json:"reqId" dc:"对外ID"`
+ Module string `json:"module" dc:"应用端口"`
+ MemberId int `json:"memberId" dc:"用户ID"`
+ TakeUpTime string `json:"takeUpTime" dc:"请求耗时"`
+ Method string `json:"method" dc:"请求方式"`
+ Url string `json:"url" dc:"请求路径"`
+ Ip string `json:"ip" dc:"访问IP"`
+ ErrorCode string `json:"errorCode" dc:"状态码"`
+ CreatedAt []int64 `json:"createdAt" dc:"创建时间"`
+ Keyword string `json:"keyword" dc:"关键词"`
+ ComplexMemberId []string `json:"complexMemberId" dc:"操作人筛选"`
}
type LogListModel struct {
diff --git a/server/internal/service/admin.go b/server/internal/service/admin.go
index 93bd730..b025d33 100644
--- a/server/internal/service/admin.go
+++ b/server/internal/service/admin.go
@@ -106,6 +106,10 @@ type (
GetIdByCode(ctx context.Context, in *adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error)
// Select 获取可选的用户选项
Select(ctx context.Context, in *adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error)
+ // GetLowerIds 获取指定用户的所有下级ID集合
+ GetLowerIds(ctx context.Context, memberId int64) (ids []int64, err error)
+ // GetComplexMemberIds 组合查找符合条件的用户ID
+ GetComplexMemberIds(ctx context.Context, memberIdx string, opt string) (ids []int64, err error)
// GetIdsByKeyword 根据关键词查找符合条件的用户ID
GetIdsByKeyword(ctx context.Context, ks string) (res []int64, err error)
// VerifySuperId 验证是否为超管
diff --git a/server/resource/generate/default/curd/logic.go.template b/server/resource/generate/default/curd/logic.go.template
index 5fd823f..8cf4ad4 100644
--- a/server/resource/generate/default/curd/logic.go.template
+++ b/server/resource/generate/default/curd/logic.go.template
@@ -31,7 +31,8 @@ import (
@{ if eq .options.Step.IsAddon true }isc "hotgo/internal/service"@{end}
@{ if eq .options.Step.IsTreeTable true }"hotgo/utility/tree"@{end}
@{ if eq .options.Step.HasFuncDict true }"hotgo/internal/library/dict"@{end}
- @{ if eq .options.Step.HasFuncDict true }"hotgo/internal/model"@{end}
+ @{ if and (eq .options.Step.HasFuncDict true) (eq .options.Step.IsAddon false) }"hotgo/internal/model"@{end}
+ @{ if and (eq .options.Step.HasFuncDict true) (eq .options.Step.IsAddon true) }imodel "hotgo/internal/model"@{end}
)
type s@{.servFunName} struct{}
@@ -238,7 +239,7 @@ func (s *s@{.servFunName}) TreeOption(ctx context.Context) (nodes []tree.Node, e
@{ if eq .options.Step.HasFuncDict true }
// Option 获取@{.tableComment}选项
-func (s *s@{.servFunName}) Option(ctx context.Context) (opts []*model.Option, err error) {
+func (s *s@{.servFunName}) Option(ctx context.Context) (opts []*@{ if eq .options.Step.IsAddon false }model@{end}@{ if eq .options.Step.IsAddon true }imodel@{end}.Option, err error) {
var models []*entity.@{.daoName}
if err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).Fields(dao.@{.daoName}.Columns().@{.options.FuncDict.Value.GoName},dao.@{.daoName}.Columns().@{.options.FuncDict.Label.GoName}).
@{.listOrder}.Scan(&models); err != nil {
@@ -246,7 +247,7 @@ func (s *s@{.servFunName}) Option(ctx context.Context) (opts []*model.Option, er
return
}
- opts = make([]*model.Option, len(models))
+ opts = make([]*@{ if eq .options.Step.IsAddon false }model@{end}@{ if eq .options.Step.IsAddon true }imodel@{end}.Option, len(models))
for k, v := range models {
opts[k] = dict.GenHashOption(v.@{.options.FuncDict.Value.GoName}, gconv.String(v.@{.options.FuncDict.Label.GoName}))
}
diff --git a/server/storage/data/hotgo.sql b/server/storage/data/hotgo.sql
index 7f629c5..1e8e4ba 100644
--- a/server/storage/data/hotgo.sql
+++ b/server/storage/data/hotgo.sql
@@ -248,7 +248,7 @@ CREATE TABLE IF NOT EXISTS `hg_admin_member` (
INSERT INTO `hg_admin_member` (`id`, `dept_id`, `role_id`, `real_name`, `username`, `password_hash`, `salt`, `password_reset_token`, `integral`, `balance`, `avatar`, `sex`, `qq`, `email`, `mobile`, `birthday`, `city_id`, `address`, `pid`, `level`, `tree`, `invite_code`, `cash`, `last_active_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
(1, 100, 1, '孟帅', 'admin', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '88.00', '99289.78', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '133814250', '133814250@qq.com', '15303830571', '2016-04-16', 410172, '莲花街001号', 0, 1, '', '111', '{"name": "孟帅", "account": "15303830571", "payeeCode": "http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8mqal5isvcb58g.jpg"}', '2024-08-27 19:02:49', NULL, 1, '2021-02-12 17:59:45', '2024-08-27 19:02:49'),
-(3, 100, 2, '测试管理员', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '0.00', '4.00', 'http://alioss.qvnidaye.com//images/2021/03/12/image_1615529198_vMK4kwq2.jpg', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', '222', NULL, '2024-04-24 11:47:48', '', 1, '2022-02-11 17:59:45', '2024-04-24 11:47:48'),
+(3, 100, 2, '测试管理员', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '0.00', '4.00', '', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', '222', NULL, '2024-04-24 11:47:48', '', 1, '2022-02-11 17:59:45', '2024-04-24 11:47:48'),
(8, 102, 200, '阿萌', 'ameng', '382df3b083a27886edb94e669a857c33', 'hfuUEb', '', '11.00', '4.22', '', 2, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', '333', NULL, '2024-04-16 18:56:00', '', 1, '2023-02-03 17:34:31', '2024-04-16 18:56:00'),
(9, 100, 206, '黄敏', 'test_finance', '151f5f6bb8b223fc7b589a32effb6f91', 'FhShzw', '', '0.00', '0.00', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', '5jZUI3uWLfcj', NULL, NULL, '', 1, '2023-08-02 11:30:45', '2023-08-02 11:31:09'),
(11, 111, 209, '刘芳', 'abai', '5787c7a121190011fac8376b1d3e0396', 'puUFvx', '', '0.00', '0.00', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '', '', '', NULL, 0, '', 8, 3, 'tr_1 tr_8 ', 'SH5akjqInb2p', NULL, '2024-04-16 18:56:02', '', 1, '2023-08-02 14:24:50', '2024-04-16 18:56:02'),
@@ -1460,8 +1460,8 @@ INSERT INTO `hg_sys_config` (`id`, `group`, `name`, `type`, `key`, `value`, `def
(51, 'smtp', '最小发送间隔', 'int', 'smtpMinInterval', '60', '', 150, '同地址', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
(52, 'smtp', 'IP最大发送次数', 'int', 'smtpMaxIpLimit', '10', '', 160, '同IP每天最大允许发送次数', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
(53, 'smtp', '验证码有效期', 'int', 'smtpCodeExpire', '600', '', 170, '单位:秒', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
-(54, 'basic', '网站域名', 'string', 'basicDomain', 'https://hotgo.facms.cn', 'https://hotgo.facms.cn', 45, '', 1, 1, '2021-01-30 13:27:43', '2024-04-21 22:58:30'),
-(55, 'basic', 'websocket地址', 'string', 'basicWsAddr', 'wss://hotgo.facms.cn/socket', 'wss://hotgo.facms.cn/socket', 48, '', 1, 1, '2021-01-30 13:27:43', '2024-04-21 22:58:30'),
+(54, 'basic', '网站域名', 'string', 'basicDomain', 'http://127.0.0.1:8000', 'http://127.0.0.1:8000', 45, '', 1, 1, '2021-01-30 13:27:43', '2024-04-21 22:58:30'),
+(55, 'basic', 'websocket地址', 'string', 'basicWsAddr', 'ws://127.0.0.1:8000/socket', 'ws://127.0.0.1:8000/socket', 48, '', 1, 1, '2021-01-30 13:27:43', '2024-04-21 22:58:30'),
(56, 'upload', 'COS存储路径', 'string', 'uploadCosPath', 'hotgo/attachment/', 'hotgo/attachment/', 450, 'COS对象存储中的相对路径', 1, 1, '2021-01-30 13:27:43', '2024-02-28 16:56:35'),
(57, 'upload', 'COS秘钥ID', 'string', 'uploadCosSecretId', '', '', 460, '子账号密钥获取可参考 https://cloud.tencent.com/document/product/598/37140', 1, 1, '2021-01-30 13:27:43', '2024-02-28 16:56:35'),
(58, 'upload', 'COS秘钥', 'string', 'uploadCosSecretKey', '', '', 470, '', 1, 1, '2021-01-30 13:27:43', '2024-02-28 16:56:35'),
diff --git a/server/storage/data/sqlite/data.sql b/server/storage/data/sqlite/data.sql
index 0dada1d..e19855f 100644
--- a/server/storage/data/sqlite/data.sql
+++ b/server/storage/data/sqlite/data.sql
@@ -36,7 +36,7 @@ INSERT INTO `hg_admin_dept` (`id`, `pid`, `name`, `code`, `type`, `leader`, `pho
INSERT INTO `hg_admin_member` (`id`, `dept_id`, `role_id`, `real_name`, `username`, `password_hash`, `salt`, `password_reset_token`, `integral`, `balance`, `avatar`, `sex`, `qq`, `email`, `mobile`, `birthday`, `city_id`, `address`, `pid`, `level`, `tree`, `invite_code`, `cash`, `last_active_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
(1, 100, 1, '孟帅', 'admin', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', 89.00, 99290.78, 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '133814250', '133814250@qq.com', '15303830571', '2016-04-16', 410172, '莲花街001号', 0, 1, '', '111', '{\"name\": \"孟帅\", \"account\": \"15303830571\", \"payeeCode\": \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8mqal5isvcb58g.jpg\"}', '2024-04-21 22:58:56', NULL, 1, '2021-02-12 17:59:45', '2024-04-21 22:58:56'),
-(3, 100, 2, '测试管理员', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', 0.00, 4.00, 'http://alioss.qvnidaye.com//images/2021/03/12/image_1615529198_vMK4kwq2.jpg', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', '222', NULL, '2024-04-12 12:44:18', '', 1, '2022-02-11 17:59:45', '2024-04-12 12:44:18'),
+(3, 100, 2, '测试管理员', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', 0.00, 4.00, '', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', '222', NULL, '2024-04-12 12:44:18', '', 1, '2022-02-11 17:59:45', '2024-04-12 12:44:18'),
(8, 102, 200, '阿萌', 'ameng', '382df3b083a27886edb94e669a857c33', 'hfuUEb', '', 11.00, 4.22, '', 2, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', '333', NULL, '2024-04-16 18:56:00', '', 1, '2023-02-03 17:34:31', '2024-04-16 18:56:00'),
(9, 100, 206, '黄敏', 'test_finance', '151f5f6bb8b223fc7b589a32effb6f91', 'FhShzw', '', 0.00, 0.00, 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', '5jZUI3uWLfcj', NULL, NULL, '', 1, '2023-08-02 11:30:45', '2023-08-02 11:31:09'),
(11, 111, 209, '刘芳', 'abai', '5787c7a121190011fac8376b1d3e0396', 'puUFvx', '', 0.00, 0.00, 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '', '', '', NULL, 0, '', 8, 3, 'tr_1 tr_8 ', 'SH5akjqInb2p', NULL, '2024-04-16 18:56:02', '', 1, '2023-08-02 14:24:50', '2024-04-16 18:56:02'),
diff --git a/web/package.json b/web/package.json
index 9630be0..688136a 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,7 +1,7 @@
{
"name": "hotgo",
"type": "module",
- "version": "2.15.11",
+ "version": "2.16.10",
"author": {
"name": "MengShuai",
"email": "133814250@qq.com",
@@ -44,7 +44,7 @@
"lodash-es": "^4.17.21",
"mint-filter": "^4.0.3",
"mitt": "^3.0.1",
- "naive-ui": "^2.39.0",
+ "naive-ui": "^2.41.0",
"pinia": "^2.2.2",
"pinyin-pro": "^3.24.2",
"print-js": "^1.6.0",
diff --git a/web/src/components/ComplexMemberPicker/index.vue b/web/src/components/ComplexMemberPicker/index.vue
new file mode 100644
index 0000000..ca9a58f
--- /dev/null
+++ b/web/src/components/ComplexMemberPicker/index.vue
@@ -0,0 +1,144 @@
+
+