mirror of
https://github.com/flipped-aurora/gin-vue-admin.git
synced 2026-09-25 13:51:00 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23952c5f5f | ||
|
|
02fc5036d7 | ||
|
|
a6a65ed9f4 | ||
|
|
369f657aa6 | ||
|
|
1801e5b30f | ||
|
|
b10d5103f3 | ||
|
|
9964bfef8b | ||
|
|
9945a19f2c | ||
|
|
a5d43e6f14 | ||
|
|
b61b9a06dd | ||
|
|
f28570fa98 | ||
|
|
fb53d639be | ||
|
|
42de9257c3 | ||
|
|
0fba597a61 | ||
|
|
d0393c4e9f | ||
|
|
a21d2a591e | ||
|
|
de54688c56 | ||
|
|
3c486d9117 | ||
|
|
e8128250f4 | ||
|
|
58a1b72910 | ||
|
|
ee00d29afd | ||
|
|
5cfcc538a8 | ||
|
|
e7c8a9d420 | ||
|
|
6b07ffe8f7 | ||
|
|
0d17340445 | ||
|
|
2a0b92713b | ||
|
|
fb22eb4178 | ||
|
|
136fb2f394 | ||
|
|
c515805f0a | ||
|
|
613ba9ba20 | ||
|
|
f6314d3581 | ||
|
|
043f5c78c2 | ||
|
|
0f9e519b0e | ||
|
|
0d17a2351f | ||
|
|
1b388664cb | ||
|
|
1edb0c529f | ||
|
|
f07a58bff4 | ||
|
|
c054840aec | ||
|
|
e259418398 | ||
|
|
df1d68a724 | ||
|
|
9d58390e11 | ||
|
|
db4c7a8bda | ||
|
|
ab163fc0ef | ||
|
|
0265801830 | ||
|
|
5fa7bbbc0f | ||
|
|
e15351e1c5 | ||
|
|
5eb0133b5c | ||
|
|
ff8344d671 | ||
|
|
d9a43ea1d6 | ||
|
|
6c62d73afb | ||
|
|
d23d6c342a | ||
|
|
90549a09e1 | ||
|
|
17d3639443 | ||
|
|
e8a096b8fe | ||
|
|
fea136e513 | ||
|
|
f3a4095462 | ||
|
|
d7d25cf69b | ||
|
|
3b33fe83e6 | ||
|
|
56f4d223ab | ||
|
|
c07317a619 | ||
|
|
4798f7688b | ||
|
|
24db0eb5aa | ||
|
|
1ece13c43d | ||
|
|
48268309b9 | ||
|
|
4074a52b1b | ||
|
|
61dd524c26 | ||
|
|
61a678a318 | ||
|
|
8ecec6a14f | ||
|
|
e3f8b8a394 | ||
|
|
eebddbafcc | ||
|
|
50cbce0f7a | ||
|
|
f9974a8971 | ||
|
|
baa48a1679 | ||
|
|
032910f87a | ||
|
|
773ef95b70 | ||
|
|
18c2f84771 | ||
|
|
ea721a71b5 | ||
|
|
b1b7427c6e | ||
|
|
7bc7c30510 | ||
|
|
d1e055430d | ||
|
|
736534379a | ||
|
|
f6b71e157c | ||
|
|
53e9f931f2 | ||
|
|
c226a9476f | ||
|
|
8ca5600286 | ||
|
|
9729bc00a0 | ||
|
|
f9c9af8261 | ||
|
|
c9e64373fb | ||
|
|
262febf486 | ||
|
|
eca9c4d7f8 | ||
|
|
a20083bb9c | ||
|
|
d31b01415b | ||
|
|
26cdb472f0 | ||
|
|
3c2595aaf9 | ||
|
|
ad323a0dff | ||
|
|
9a0417b1a7 | ||
|
|
3324a816ee | ||
|
|
cc4135a2d7 | ||
|
|
2d884c83cc | ||
|
|
619c5b5e1d | ||
|
|
33afa9adfc | ||
|
|
0c141cc6f7 | ||
|
|
efdff2ab0c | ||
|
|
ebefb0eba4 | ||
|
|
d4b9c2c97b | ||
|
|
d4db16b501 | ||
|
|
a5cbd7387b | ||
|
|
99d6b4a361 | ||
|
|
18365689e6 | ||
|
|
8ea827412a | ||
|
|
4d8979c4ad | ||
|
|
236357baa8 | ||
|
|
5ef4b21858 | ||
|
|
3b3441851c | ||
|
|
5517987e14 | ||
|
|
7e98f61bec | ||
|
|
e2d360e8b1 | ||
|
|
57cfedfd7c | ||
|
|
50b1d21d13 | ||
|
|
7b79ec6c66 | ||
|
|
7a5b31530f | ||
|
|
e9100a9542 | ||
|
|
421304d4a3 | ||
|
|
10d61bbbb3 | ||
|
|
095709fb19 | ||
|
|
725f4150fc | ||
|
|
93ac2e70d2 | ||
|
|
f4c2b50ca5 | ||
|
|
3354edbb1c | ||
|
|
d3600499af | ||
|
|
35e2c2cfe8 | ||
|
|
6bbb4f577e |
@@ -48,7 +48,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21]
|
||||
go-version: [1.22]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v1
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.8.0]
|
||||
go-version: [1.21]
|
||||
go-version: [1.22]
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ['16.x']
|
||||
go-version: ['1.21']
|
||||
go-version: ['1.22']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: tag major and minor versions
|
||||
|
||||
@@ -25,6 +25,7 @@ yarn-error.log*
|
||||
/server/log/
|
||||
/server/gva
|
||||
/server/latest_log
|
||||
/server/__debug_bin*
|
||||
|
||||
*.iml
|
||||
web/.pnpm-debug.log
|
||||
|
||||
@@ -16,10 +16,6 @@ English | [简体中文](./README.md)
|
||||
|
||||
[github](https://github.com/flipped-aurora/gin-vue-admin): https://github.com/flipped-aurora/gin-vue-admin
|
||||
|
||||
[Vue3 version branch address](https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop): https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop
|
||||
|
||||
[Approval flow branch](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow): https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow
|
||||
|
||||
# Project Guidelines
|
||||
[Online Documentation](https://www.gin-vue-admin.com/) : https://www.gin-vue-admin.com/
|
||||
|
||||
|
||||
@@ -12,15 +12,6 @@
|
||||
|
||||
[English](./README-en.md) | 简体中文
|
||||
|
||||
## 不同版本
|
||||
|
||||
我们会对以下四个版本持续维护,请选择适合自己的版本使用。最新技术栈为组合式api版本,已支持多语言(I18N)
|
||||
|
||||
[组合式API版(主)](https://github.com/flipped-aurora/gin-vue-admin) |
|
||||
[组合式API多语言(i18n)版](https://github.com/flipped-aurora/gin-vue-admin/tree/i18n-dev-new) |
|
||||
[声明式API版](https://github.com/flipped-aurora/gin-vue-admin/tree/v2.4.x) |
|
||||
[声明式API多语言(i18n)版](https://github.com/flipped-aurora/gin-vue-admin/tree/i18n-dev)
|
||||
|
||||
# 项目文档
|
||||
[在线文档](https://www.gin-vue-admin.com) : https://www.gin-vue-admin.com
|
||||
|
||||
@@ -42,9 +33,11 @@
|
||||
|
||||
3.您完全可以通过我们的教程和文档完成一切操作,因此我们不再提供免费的技术服务,如需服务请进行[付费支持](https://www.gin-vue-admin.com/coffee/payment.html)
|
||||
|
||||
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,其余信息功能不做任何限制。如需剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html)
|
||||
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,以及日志和代码中所包含的版权声明信息。所需保留信息均为文案性质,不会影响任何业务内容,如决定商用且必须剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html)
|
||||
|
||||
<img src="https://qmplusimg.henrongyi.top/%E6%8E%88%E6%9D%83.png" width="1000">
|
||||
<img src="https://qmplusimg.henrongyi.top/openSource/login.jpg" width="1000">
|
||||
|
||||
<img src="https://qmplusimg.henrongyi.top/openSource/dashboard.jpg" width="1000">
|
||||
|
||||
## 1. 基本介绍
|
||||
|
||||
@@ -83,7 +76,7 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm
|
||||
|
||||
```
|
||||
- node版本 > v16.8.3
|
||||
- golang版本 >= v1.16
|
||||
- golang版本 >= v1.22
|
||||
- IDE推荐:Goland
|
||||
```
|
||||
|
||||
@@ -331,10 +324,7 @@ swag init
|
||||
|
||||
### 7.1 技术群
|
||||
|
||||
### QQ交流群:622360840
|
||||
| QQ 群 |
|
||||
| :---: |
|
||||
| <img src="http://qmplusimg.henrongyi.top/qq.jpg" width="180"/> |
|
||||
### QQ交流群:470239250
|
||||
|
||||
### 微信交流群
|
||||
| 微信 |
|
||||
|
||||
@@ -41,8 +41,10 @@ services:
|
||||
ports:
|
||||
- '8888:8888'
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ../../server:/server
|
||||
working_dir: /server # 如果docker 设置了workdir 则此处不需要设置
|
||||
@@ -67,6 +69,11 @@ services:
|
||||
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
|
||||
MYSQL_USER: 'gva'
|
||||
MYSQL_PASSWORD: 'Aa@6447985'
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "gva", "-pAa@6447985"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
networks:
|
||||
@@ -80,6 +87,11 @@ services:
|
||||
restart: always
|
||||
ports:
|
||||
- '16379:6379'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- redis:/data
|
||||
networks:
|
||||
|
||||
@@ -38,8 +38,10 @@ services:
|
||||
ports:
|
||||
- '8888:8888'
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
links:
|
||||
- mysql
|
||||
- redis
|
||||
@@ -59,6 +61,11 @@ services:
|
||||
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
|
||||
MYSQL_USER: 'gva'
|
||||
MYSQL_PASSWORD: 'Aa@6447985'
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "gva", "-pAa@6447985"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
networks:
|
||||
@@ -71,6 +78,11 @@ services:
|
||||
restart: always
|
||||
ports:
|
||||
- '16379:6379'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- redis:/data
|
||||
networks:
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
@@ -63,6 +61,7 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
|
||||
}
|
||||
a.Pretreatment()
|
||||
var apiIds []uint
|
||||
var menuId uint
|
||||
if a.AutoCreateApiToSql {
|
||||
if ids, err := autoCodeService.AutoCreateApi(&a); err != nil {
|
||||
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err))
|
||||
@@ -73,24 +72,24 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
|
||||
apiIds = ids
|
||||
}
|
||||
}
|
||||
a.PackageT = utils.FirstUpper(a.Package)
|
||||
err := autoCodeService.CreateTemp(a, apiIds...)
|
||||
if err != nil {
|
||||
if errors.Is(err, system.ErrAutoMove) {
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
|
||||
} else {
|
||||
if a.AutoCreateMenuToSql {
|
||||
if id, err := autoCodeService.AutoCreateMenu(&a); err != nil {
|
||||
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err))
|
||||
c.Writer.Header().Add("success", "false")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
|
||||
_ = os.Remove("./ginvueadmin.zip")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
|
||||
} else {
|
||||
menuId = id
|
||||
}
|
||||
} else {
|
||||
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "ginvueadmin.zip")) // fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名
|
||||
c.Writer.Header().Add("Content-Type", "application/json")
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File("./ginvueadmin.zip")
|
||||
_ = os.Remove("./ginvueadmin.zip")
|
||||
}
|
||||
a.PackageT = utils.FirstUpper(a.Package)
|
||||
err := autoCodeService.CreateTemp(a, menuId, apiIds...)
|
||||
if err != nil {
|
||||
c.Writer.Header().Add("success", "false")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("Content-Type", "application/json")
|
||||
c.Writer.Header().Add("success", "true")
|
||||
}
|
||||
|
||||
// GetDB
|
||||
@@ -178,6 +177,12 @@ func (autoApi *AutoCodeApi) CreatePackage(c *gin.Context) {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// PackageName可能导致路径穿越的问题 / 和 \ 都要防止
|
||||
if strings.Contains(a.PackageName, "\\") || strings.Contains(a.PackageName, "/") || strings.Contains(a.PackageName, "..") {
|
||||
response.FailWithMessage("包名不合法", c)
|
||||
return
|
||||
}
|
||||
|
||||
err := autoCodeService.CreateAutoCode(&a)
|
||||
if err != nil {
|
||||
|
||||
@@ -243,6 +248,11 @@ func (autoApi *AutoCodeApi) AutoPlug(c *gin.Context) {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if strings.Contains(a.PlugName, "\\") || strings.Contains(a.PlugName, "/") || strings.Contains(a.PlugName, "..") {
|
||||
response.FailWithMessage("插件名称不合法", c)
|
||||
return
|
||||
}
|
||||
|
||||
a.Snake = strings.ToLower(a.PlugName)
|
||||
a.NeedModel = a.HasRequest || a.HasResponse
|
||||
err = autoCodeService.CreatePlug(a)
|
||||
|
||||
@@ -44,7 +44,7 @@ func (b *BaseApi) Captcha(c *gin.Context) {
|
||||
driver := base64Captcha.NewDriverDigit(global.GVA_CONFIG.Captcha.ImgHeight, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.KeyLong, 0.7, 80)
|
||||
// cp := base64Captcha.NewCaptcha(driver, store.UseWithCtx(c)) // v8下使用redis
|
||||
cp := base64Captcha.NewCaptcha(driver, store)
|
||||
id, b64s, err := cp.Generate()
|
||||
id, b64s, _, err := cp.Generate()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("验证码获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("验证码获取失败", c)
|
||||
|
||||
@@ -191,11 +191,12 @@ func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gi
|
||||
// @Router /sysExportTemplate/exportExcel [get]
|
||||
func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) {
|
||||
templateID := c.Query("templateID")
|
||||
queryParams := c.Request.URL.Query()
|
||||
if templateID == "" {
|
||||
response.FailWithMessage("模板ID不能为空", c)
|
||||
return
|
||||
}
|
||||
if file, name, err := sysExportTemplateService.ExportExcel(templateID); err != nil {
|
||||
if file, name, err := sysExportTemplateService.ExportExcel(templateID, queryParams); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
+13
-1
@@ -19,9 +19,17 @@ zap:
|
||||
|
||||
# redis configuration
|
||||
redis:
|
||||
db: 0
|
||||
#是否使用redis集群模式
|
||||
useCluster: false
|
||||
#使用集群模式addr和db默认无效
|
||||
addr: 127.0.0.1:6379
|
||||
password: ""
|
||||
db: 0
|
||||
clusterAddrs:
|
||||
- "172.21.0.3:7000"
|
||||
- "172.21.0.4:7001"
|
||||
- "172.21.0.2:7002"
|
||||
|
||||
|
||||
# mongo configuration
|
||||
mongo:
|
||||
@@ -225,6 +233,10 @@ hua-wei-obs:
|
||||
excel:
|
||||
dir: ./resource/excel/
|
||||
|
||||
# disk usage configuration
|
||||
disk-list:
|
||||
- mount-point: "/"
|
||||
|
||||
# 跨域配置
|
||||
# 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用
|
||||
cors:
|
||||
|
||||
@@ -27,6 +27,8 @@ type Server struct {
|
||||
|
||||
Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"`
|
||||
|
||||
DiskList []DiskList `mapstructure:"disk-list" json:"disk-list" yaml:"disk-list"`
|
||||
|
||||
// 跨域配置
|
||||
Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"`
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"gorm.io/gorm/logger"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DsnProvider interface {
|
||||
Dsn() string
|
||||
}
|
||||
@@ -16,14 +21,29 @@ type GeneralDB struct {
|
||||
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库密码
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
|
||||
Path string `mapstructure:"path" json:"path" yaml:"path"`
|
||||
Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` //数据库引擎,默认InnoDB
|
||||
Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` // 数据库引擎,默认InnoDB
|
||||
LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志
|
||||
MaxIdleConns int `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数
|
||||
MaxOpenConns int `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
|
||||
Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` //是否开启全局禁用复数,true表示开启
|
||||
Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` // 是否开启全局禁用复数,true表示开启
|
||||
LogZap bool `mapstructure:"log-zap" json:"log-zap" yaml:"log-zap"` // 是否通过zap写入日志文件
|
||||
}
|
||||
|
||||
func (c GeneralDB) LogLevel() logger.LogLevel {
|
||||
switch strings.ToLower(c.LogMode) {
|
||||
case "silent", "Silent":
|
||||
return logger.Silent
|
||||
case "error", "Error":
|
||||
return logger.Error
|
||||
case "warn", "Warn":
|
||||
return logger.Warn
|
||||
case "info", "Info":
|
||||
return logger.Info
|
||||
default:
|
||||
return logger.Info
|
||||
}
|
||||
}
|
||||
|
||||
type SpecializedDB struct {
|
||||
Type string `mapstructure:"type" json:"type" yaml:"type"`
|
||||
AliasName string `mapstructure:"alias-name" json:"alias-name" yaml:"alias-name"`
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
type Disk struct {
|
||||
MountPoint string `mapstructure:"mount-point" json:"mount-point" yaml:"mount-point"`
|
||||
}
|
||||
|
||||
type DiskList struct {
|
||||
Disk `yaml:",inline" mapstructure:",squash"`
|
||||
}
|
||||
@@ -3,11 +3,8 @@ package config
|
||||
type Mssql struct {
|
||||
GeneralDB `yaml:",inline" mapstructure:",squash"`
|
||||
}
|
||||
//dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
|
||||
|
||||
// Dsn "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
|
||||
func (m *Mssql) Dsn() string {
|
||||
return "sqlserver://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "?database=" + m.Dbname + "&encrypt=disable"
|
||||
}
|
||||
|
||||
func (m *Mssql) GetLogMode() string {
|
||||
return m.LogMode
|
||||
}
|
||||
|
||||
@@ -7,7 +7,3 @@ type Mysql struct {
|
||||
func (m *Mysql) Dsn() string {
|
||||
return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config
|
||||
}
|
||||
|
||||
func (m *Mysql) GetLogMode() string {
|
||||
return m.LogMode
|
||||
}
|
||||
|
||||
@@ -8,7 +8,3 @@ func (m *Oracle) Dsn() string {
|
||||
return "oracle://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "/" + m.Dbname + "?" + m.Config
|
||||
|
||||
}
|
||||
|
||||
func (m *Oracle) GetLogMode() string {
|
||||
return m.LogMode
|
||||
}
|
||||
|
||||
@@ -15,7 +15,3 @@ func (p *Pgsql) Dsn() string {
|
||||
func (p *Pgsql) LinkDsn(dbname string) string {
|
||||
return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + dbname + " port=" + p.Port + " " + p.Config
|
||||
}
|
||||
|
||||
func (m *Pgsql) GetLogMode() string {
|
||||
return m.LogMode
|
||||
}
|
||||
|
||||
@@ -11,7 +11,3 @@ type Sqlite struct {
|
||||
func (s *Sqlite) Dsn() string {
|
||||
return filepath.Join(s.Path, s.Dbname+".db")
|
||||
}
|
||||
|
||||
func (s *Sqlite) GetLogMode() string {
|
||||
return s.LogMode
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package config
|
||||
|
||||
type Redis struct {
|
||||
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
|
||||
DB int `mapstructure:"db" json:"db" yaml:"db"` // redis的哪个数据库
|
||||
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
|
||||
DB int `mapstructure:"db" json:"db" yaml:"db"` // 单实例模式下redis的哪个数据库
|
||||
UseCluster bool `mapstructure:"useCluster" json:"useCluster" yaml:"useCluster"` // 是否使用集群模式
|
||||
ClusterAddrs []string `mapstructure:"clusterAddrs" json:"clusterAddrs" yaml:"clusterAddrs"` // 集群模式下的节点地址列表
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package config
|
||||
|
||||
type System struct {
|
||||
Env string `mapstructure:"env" json:"env" yaml:"env"` // 环境值
|
||||
DbType string `mapstructure:"db-type" json:"db-type" yaml:"db-type"` // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql
|
||||
OssType string `mapstructure:"oss-type" json:"oss-type" yaml:"oss-type"` // Oss类型
|
||||
RouterPrefix string `mapstructure:"router-prefix" json:"router-prefix" yaml:"router-prefix"`
|
||||
|
||||
+45
-35
@@ -2,7 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"go.uber.org/zap/zapcore"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Zap struct {
|
||||
@@ -12,49 +12,59 @@ type Zap struct {
|
||||
Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹
|
||||
EncodeLevel string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"` // 编码级
|
||||
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名
|
||||
|
||||
MaxAge int `mapstructure:"max-age" json:"max-age" yaml:"max-age"` // 日志留存时间
|
||||
ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行
|
||||
LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
|
||||
ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行
|
||||
LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
|
||||
}
|
||||
|
||||
// ZapEncodeLevel 根据 EncodeLevel 返回 zapcore.LevelEncoder
|
||||
// Levels 根据字符串转化为 zapcore.Levels
|
||||
func (c *Zap) Levels() []zapcore.Level {
|
||||
levels := make([]zapcore.Level, 0, 7)
|
||||
level, err := zapcore.ParseLevel(c.Level)
|
||||
if err != nil {
|
||||
level = zapcore.DebugLevel
|
||||
}
|
||||
for ; level <= zapcore.FatalLevel; level++ {
|
||||
levels = append(levels, level)
|
||||
}
|
||||
return levels
|
||||
}
|
||||
|
||||
func (c *Zap) Encoder() zapcore.Encoder {
|
||||
config := zapcore.EncoderConfig{
|
||||
TimeKey: "time",
|
||||
NameKey: "name",
|
||||
LevelKey: "level",
|
||||
CallerKey: "caller",
|
||||
MessageKey: "message",
|
||||
StacktraceKey: c.StacktraceKey,
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
|
||||
encoder.AppendString(c.Prefix + t.Format("2006-01-02 15:04:05.000"))
|
||||
},
|
||||
EncodeLevel: c.LevelEncoder(),
|
||||
EncodeCaller: zapcore.FullCallerEncoder,
|
||||
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||
}
|
||||
if c.Format == "json" {
|
||||
return zapcore.NewJSONEncoder(config)
|
||||
}
|
||||
return zapcore.NewConsoleEncoder(config)
|
||||
|
||||
}
|
||||
|
||||
// LevelEncoder 根据 EncodeLevel 返回 zapcore.LevelEncoder
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *Zap) ZapEncodeLevel() zapcore.LevelEncoder {
|
||||
func (c *Zap) LevelEncoder() zapcore.LevelEncoder {
|
||||
switch {
|
||||
case z.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
|
||||
case c.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
|
||||
return zapcore.LowercaseLevelEncoder
|
||||
case z.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
|
||||
case c.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
|
||||
return zapcore.LowercaseColorLevelEncoder
|
||||
case z.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
|
||||
case c.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
|
||||
return zapcore.CapitalLevelEncoder
|
||||
case z.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
|
||||
case c.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
|
||||
return zapcore.CapitalColorLevelEncoder
|
||||
default:
|
||||
return zapcore.LowercaseLevelEncoder
|
||||
}
|
||||
}
|
||||
|
||||
// TransportLevel 根据字符串转化为 zapcore.Level
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *Zap) TransportLevel() zapcore.Level {
|
||||
z.Level = strings.ToLower(z.Level)
|
||||
switch z.Level {
|
||||
case "debug":
|
||||
return zapcore.DebugLevel
|
||||
case "info":
|
||||
return zapcore.InfoLevel
|
||||
case "warn":
|
||||
return zapcore.WarnLevel
|
||||
case "error":
|
||||
return zapcore.ErrorLevel
|
||||
case "dpanic":
|
||||
return zapcore.DPanicLevel
|
||||
case "panic":
|
||||
return zapcore.PanicLevel
|
||||
case "fatal":
|
||||
return zapcore.FatalLevel
|
||||
default:
|
||||
return zapcore.DebugLevel
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,33 +3,43 @@ package internal
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Cutter 实现 io.Writer 接口
|
||||
// 用于日志切割, strings.Join([]string{director,layout, formats..., level+".log"}, os.PathSeparator)
|
||||
type Cutter struct {
|
||||
level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal)
|
||||
format string // 时间格式(2006-01-02)
|
||||
Director string // 日志文件夹
|
||||
layout string // 时间格式 2006-01-02 15:04:05
|
||||
formats []string // 自定义参数([]string{Director,"2006-01-02", "business"(此参数可不写), level+".log"}
|
||||
director string // 日志文件夹
|
||||
file *os.File // 文件句柄
|
||||
mutex *sync.RWMutex // 读写锁
|
||||
}
|
||||
|
||||
type CutterOption func(*Cutter)
|
||||
|
||||
// WithCutterFormat 设置时间格式
|
||||
func WithCutterFormat(format string) CutterOption {
|
||||
// CutterWithLayout 时间格式
|
||||
func CutterWithLayout(layout string) CutterOption {
|
||||
return func(c *Cutter) {
|
||||
c.format = format
|
||||
c.layout = layout
|
||||
}
|
||||
}
|
||||
|
||||
// CutterWithFormats 格式化参数
|
||||
func CutterWithFormats(format ...string) CutterOption {
|
||||
return func(c *Cutter) {
|
||||
if len(format) > 0 {
|
||||
c.formats = format
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewCutter(director string, level string, options ...CutterOption) *Cutter {
|
||||
rotate := &Cutter{
|
||||
level: level,
|
||||
Director: director,
|
||||
director: director,
|
||||
mutex: new(sync.RWMutex),
|
||||
}
|
||||
for i := 0; i < len(options); i++ {
|
||||
@@ -51,41 +61,19 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) {
|
||||
}
|
||||
c.mutex.Unlock()
|
||||
}()
|
||||
var business string
|
||||
if strings.Contains(string(bytes), "business") {
|
||||
var compile *regexp.Regexp
|
||||
compile, err = regexp.Compile(`{"business": "([^,]+)"}`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if compile.Match(bytes) {
|
||||
finds := compile.FindSubmatch(bytes)
|
||||
business = string(finds[len(finds)-1])
|
||||
bytes = compile.ReplaceAll(bytes, []byte(""))
|
||||
}
|
||||
compile, err = regexp.Compile(`"business": "([^,]+)"`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if compile.Match(bytes) {
|
||||
finds := compile.FindSubmatch(bytes)
|
||||
business = string(finds[len(finds)-1])
|
||||
bytes = compile.ReplaceAll(bytes, []byte(""))
|
||||
}
|
||||
length := len(c.formats)
|
||||
values := make([]string, 0, 3+length)
|
||||
values = append(values, c.director)
|
||||
if c.layout != "" {
|
||||
values = append(values, time.Now().Format(c.layout))
|
||||
}
|
||||
format := time.Now().Format(c.format)
|
||||
formats := make([]string, 0, 4)
|
||||
formats = append(formats, c.Director)
|
||||
if format != "" {
|
||||
formats = append(formats, format)
|
||||
for i := 0; i < length; i++ {
|
||||
values = append(values, c.formats[i])
|
||||
}
|
||||
if business != "" {
|
||||
formats = append(formats, business)
|
||||
}
|
||||
formats = append(formats, c.level+".log")
|
||||
filename := filepath.Join(formats...)
|
||||
dirname := filepath.Dir(filename)
|
||||
err = os.MkdirAll(dirname, 0755)
|
||||
values = append(values, c.level+".log")
|
||||
filename := filepath.Join(values...)
|
||||
director := filepath.Dir(filename)
|
||||
err = os.MkdirAll(director, os.ModePerm)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -95,3 +83,13 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) {
|
||||
}
|
||||
return c.file.Write(bytes)
|
||||
}
|
||||
|
||||
func (c *Cutter) Sync() error {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
if c.file != nil {
|
||||
return c.file.Sync()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"os"
|
||||
)
|
||||
|
||||
var FileRotatelogs = new(fileRotatelogs)
|
||||
|
||||
type fileRotatelogs struct{}
|
||||
|
||||
// GetWriteSyncer 获取 zapcore.WriteSyncer
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (r *fileRotatelogs) GetWriteSyncer(level string) zapcore.WriteSyncer {
|
||||
fileWriter := NewCutter(global.GVA_CONFIG.Zap.Director, level, WithCutterFormat("2006-01-02"))
|
||||
if global.GVA_CONFIG.Zap.LogInConsole {
|
||||
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter))
|
||||
}
|
||||
return zapcore.AddSync(fileWriter)
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Zap = new(_zap)
|
||||
|
||||
type _zap struct{}
|
||||
|
||||
// GetEncoder 获取 zapcore.Encoder
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) GetEncoder() zapcore.Encoder {
|
||||
if global.GVA_CONFIG.Zap.Format == "json" {
|
||||
return zapcore.NewJSONEncoder(z.GetEncoderConfig())
|
||||
}
|
||||
return zapcore.NewConsoleEncoder(z.GetEncoderConfig())
|
||||
}
|
||||
|
||||
// GetEncoderConfig 获取zapcore.EncoderConfig
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) GetEncoderConfig() zapcore.EncoderConfig {
|
||||
return zapcore.EncoderConfig{
|
||||
MessageKey: "message",
|
||||
LevelKey: "level",
|
||||
TimeKey: "time",
|
||||
NameKey: "logger",
|
||||
CallerKey: "caller",
|
||||
StacktraceKey: global.GVA_CONFIG.Zap.StacktraceKey,
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
EncodeLevel: global.GVA_CONFIG.Zap.ZapEncodeLevel(),
|
||||
EncodeTime: z.CustomTimeEncoder,
|
||||
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||
EncodeCaller: zapcore.FullCallerEncoder,
|
||||
}
|
||||
}
|
||||
|
||||
// GetEncoderCore 获取Encoder的 zapcore.Core
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) GetEncoderCore(l zapcore.Level, level zap.LevelEnablerFunc) zapcore.Core {
|
||||
writer := FileRotatelogs.GetWriteSyncer(l.String()) // 日志分割
|
||||
return zapcore.NewCore(z.GetEncoder(), writer, level)
|
||||
}
|
||||
|
||||
// CustomTimeEncoder 自定义日志输出时间格式
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) CustomTimeEncoder(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
|
||||
encoder.AppendString(global.GVA_CONFIG.Zap.Prefix + t.Format("2006/01/02 - 15:04:05.000"))
|
||||
}
|
||||
|
||||
// GetZapCores 根据配置文件的Level获取 []zapcore.Core
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) GetZapCores() []zapcore.Core {
|
||||
cores := make([]zapcore.Core, 0, 7)
|
||||
for level := global.GVA_CONFIG.Zap.TransportLevel(); level <= zapcore.FatalLevel; level++ {
|
||||
cores = append(cores, z.GetEncoderCore(level, z.GetLevelPriority(level)))
|
||||
}
|
||||
return cores
|
||||
}
|
||||
|
||||
// GetLevelPriority 根据 zapcore.Level 获取 zap.LevelEnablerFunc
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) GetLevelPriority(level zapcore.Level) zap.LevelEnablerFunc {
|
||||
switch level {
|
||||
case zapcore.DebugLevel:
|
||||
return func(level zapcore.Level) bool { // 调试级别
|
||||
return level == zap.DebugLevel
|
||||
}
|
||||
case zapcore.InfoLevel:
|
||||
return func(level zapcore.Level) bool { // 日志级别
|
||||
return level == zap.InfoLevel
|
||||
}
|
||||
case zapcore.WarnLevel:
|
||||
return func(level zapcore.Level) bool { // 警告级别
|
||||
return level == zap.WarnLevel
|
||||
}
|
||||
case zapcore.ErrorLevel:
|
||||
return func(level zapcore.Level) bool { // 错误级别
|
||||
return level == zap.ErrorLevel
|
||||
}
|
||||
case zapcore.DPanicLevel:
|
||||
return func(level zapcore.Level) bool { // dpanic级别
|
||||
return level == zap.DPanicLevel
|
||||
}
|
||||
case zapcore.PanicLevel:
|
||||
return func(level zapcore.Level) bool { // panic级别
|
||||
return level == zap.PanicLevel
|
||||
}
|
||||
case zapcore.FatalLevel:
|
||||
return func(level zapcore.Level) bool { // 终止级别
|
||||
return level == zap.FatalLevel
|
||||
}
|
||||
default:
|
||||
return func(level zapcore.Level) bool { // 调试级别
|
||||
return level == zap.DebugLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ZapCore struct {
|
||||
level zapcore.Level
|
||||
zapcore.Core
|
||||
}
|
||||
|
||||
func NewZapCore(level zapcore.Level) *ZapCore {
|
||||
entity := &ZapCore{level: level}
|
||||
syncer := entity.WriteSyncer()
|
||||
levelEnabler := zap.LevelEnablerFunc(func(l zapcore.Level) bool {
|
||||
return l == level
|
||||
})
|
||||
entity.Core = zapcore.NewCore(global.GVA_CONFIG.Zap.Encoder(), syncer, levelEnabler)
|
||||
return entity
|
||||
}
|
||||
|
||||
func (z *ZapCore) WriteSyncer(formats ...string) zapcore.WriteSyncer {
|
||||
cutter := NewCutter(
|
||||
global.GVA_CONFIG.Zap.Director,
|
||||
z.level.String(),
|
||||
CutterWithLayout(time.DateOnly),
|
||||
CutterWithFormats(formats...),
|
||||
)
|
||||
if global.GVA_CONFIG.Zap.LogInConsole {
|
||||
multiSyncer := zapcore.NewMultiWriteSyncer(os.Stdout, cutter)
|
||||
return zapcore.AddSync(multiSyncer)
|
||||
}
|
||||
return zapcore.AddSync(cutter)
|
||||
}
|
||||
|
||||
func (z *ZapCore) Enabled(level zapcore.Level) bool {
|
||||
return z.level == level
|
||||
}
|
||||
|
||||
func (z *ZapCore) With(fields []zapcore.Field) zapcore.Core {
|
||||
return z.Core.With(fields)
|
||||
}
|
||||
|
||||
func (z *ZapCore) Check(entry zapcore.Entry, check *zapcore.CheckedEntry) *zapcore.CheckedEntry {
|
||||
if z.Enabled(entry.Level) {
|
||||
return check.AddCore(entry, z)
|
||||
}
|
||||
return check
|
||||
}
|
||||
|
||||
func (z *ZapCore) Write(entry zapcore.Entry, fields []zapcore.Field) error {
|
||||
for i := 0; i < len(fields); i++ {
|
||||
if fields[i].Key == "business" || fields[i].Key == "folder" || fields[i].Key == "directory" {
|
||||
syncer := z.WriteSyncer(fields[i].String)
|
||||
z.Core = zapcore.NewCore(global.GVA_CONFIG.Zap.Encoder(), syncer, z.level)
|
||||
}
|
||||
}
|
||||
return z.Core.Write(entry, fields)
|
||||
}
|
||||
|
||||
func (z *ZapCore) Sync() error {
|
||||
return z.Core.Sync()
|
||||
}
|
||||
@@ -38,13 +38,17 @@ func RunWindowsServer() {
|
||||
|
||||
fmt.Printf(`
|
||||
欢迎使用 gin-vue-admin
|
||||
当前版本:v2.6.1
|
||||
加群方式:微信号:shouzi_1994 QQ群:622360840
|
||||
当前版本:v2.6.5
|
||||
加群方式:微信号:shouzi_1994 QQ群:470239250
|
||||
项目地址:https://github.com/flipped-aurora/gin-vue-admin
|
||||
插件市场:https://plugin.gin-vue-admin.com
|
||||
GVA讨论社区:https://support.qq.com/products/371961
|
||||
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
|
||||
默认前端文件运行地址:http://127.0.0.1:8080
|
||||
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/coffee/index.html
|
||||
--------------------------------------版权声明--------------------------------------
|
||||
** 版权所有方:flipped-aurora开源团队 **
|
||||
** 版权持有公司:北京翻转极光科技有限责任公司 **
|
||||
** 剔除授权标识需购买商用授权:https://gin-vue-admin.com/empower/index.html **
|
||||
`, address)
|
||||
global.GVA_LOG.Error(s.ListenAndServe().Error())
|
||||
}
|
||||
|
||||
@@ -29,13 +29,13 @@ func Viper(path ...string) *viper.Viper {
|
||||
switch gin.Mode() {
|
||||
case gin.DebugMode:
|
||||
config = internal.ConfigDefaultFile
|
||||
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.EnvGinMode, internal.ConfigDefaultFile)
|
||||
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigDefaultFile)
|
||||
case gin.ReleaseMode:
|
||||
config = internal.ConfigReleaseFile
|
||||
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.EnvGinMode, internal.ConfigReleaseFile)
|
||||
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigReleaseFile)
|
||||
case gin.TestMode:
|
||||
config = internal.ConfigTestFile
|
||||
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.EnvGinMode, internal.ConfigTestFile)
|
||||
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigTestFile)
|
||||
}
|
||||
} else { // internal.ConfigEnv 常量存储的环境变量不为空 将值赋值于config
|
||||
config = configEnv
|
||||
|
||||
+7
-3
@@ -17,10 +17,14 @@ func Zap() (logger *zap.Logger) {
|
||||
fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director)
|
||||
_ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm)
|
||||
}
|
||||
|
||||
cores := internal.Zap.GetZapCores()
|
||||
levels := global.GVA_CONFIG.Zap.Levels()
|
||||
length := len(levels)
|
||||
cores := make([]zapcore.Core, 0, length)
|
||||
for i := 0; i < length; i++ {
|
||||
core := internal.NewZapCore(levels[i])
|
||||
cores = append(cores, core)
|
||||
}
|
||||
logger = zap.New(zapcore.NewTee(cores...))
|
||||
|
||||
if global.GVA_CONFIG.Zap.ShowLine {
|
||||
logger = logger.WithOptions(zap.AddCaller())
|
||||
}
|
||||
|
||||
+1
-5
@@ -6918,10 +6918,6 @@ const docTemplate = `{
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"activeColor": {
|
||||
"description": "活跃颜色",
|
||||
"type": "string"
|
||||
},
|
||||
"authorities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -7001,7 +6997,7 @@ const docTemplate = `{
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "v2.6.1",
|
||||
Version: "v2.6.5",
|
||||
Host: "",
|
||||
BasePath: "",
|
||||
Schemes: []string{},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"description": "使用gin+vue进行极速开发的全栈开发基础平台",
|
||||
"title": "Gin-Vue-Admin Swagger API接口文档",
|
||||
"contact": {},
|
||||
"version": "v2.6.1"
|
||||
"version": "v2.6.5"
|
||||
},
|
||||
"paths": {
|
||||
"/api/createApi": {
|
||||
@@ -6910,10 +6910,6 @@
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"activeColor": {
|
||||
"description": "活跃颜色",
|
||||
"type": "string"
|
||||
},
|
||||
"authorities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
@@ -1530,9 +1530,6 @@ definitions:
|
||||
ID:
|
||||
description: 主键ID
|
||||
type: integer
|
||||
activeColor:
|
||||
description: 活跃颜色
|
||||
type: string
|
||||
authorities:
|
||||
items:
|
||||
$ref: '#/definitions/system.SysAuthority'
|
||||
@@ -1585,7 +1582,7 @@ info:
|
||||
contact: {}
|
||||
description: 使用gin+vue进行极速开发的全栈开发基础平台
|
||||
title: Gin-Vue-Admin Swagger API接口文档
|
||||
version: v2.6.1
|
||||
version: v2.6.5
|
||||
paths:
|
||||
/api/createApi:
|
||||
post:
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
var (
|
||||
GVA_DB *gorm.DB
|
||||
GVA_DBList map[string]*gorm.DB
|
||||
GVA_REDIS *redis.Client
|
||||
GVA_REDIS redis.UniversalClient
|
||||
GVA_MONGO *qmgo.QmgoClient
|
||||
GVA_CONFIG config.Server
|
||||
GVA_VP *viper.Viper
|
||||
|
||||
+33
-16
@@ -1,11 +1,11 @@
|
||||
module github.com/flipped-aurora/gin-vue-admin/server
|
||||
|
||||
go 1.20
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible
|
||||
github.com/aws/aws-sdk-go v1.44.307
|
||||
github.com/casbin/casbin/v2 v2.71.1
|
||||
github.com/casbin/casbin/v2 v2.87.1
|
||||
github.com/casbin/gorm-adapter/v3 v3.18.0
|
||||
github.com/flipped-aurora/ws v1.0.2
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
@@ -18,7 +18,7 @@ require (
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible
|
||||
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/mojocn/base64Captcha v1.3.6
|
||||
github.com/otiai10/copy v1.7.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/qiniu/api.v7/v7 v7.4.1
|
||||
@@ -36,26 +36,33 @@ require (
|
||||
github.com/unrolled/secure v1.13.0
|
||||
github.com/xuri/excelize/v2 v2.8.0
|
||||
go.mongodb.org/mongo-driver v1.12.1
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.16.0
|
||||
golang.org/x/crypto v0.22.0
|
||||
golang.org/x/sync v0.5.0
|
||||
golang.org/x/text v0.14.0
|
||||
gorm.io/driver/mysql v1.5.1
|
||||
gorm.io/driver/postgres v1.5.2
|
||||
gorm.io/driver/mysql v1.5.6
|
||||
gorm.io/driver/postgres v1.5.7
|
||||
gorm.io/driver/sqlserver v1.5.1
|
||||
gorm.io/gorm v1.25.2
|
||||
gorm.io/gorm v1.25.10
|
||||
nhooyr.io/websocket v1.8.7
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/bodgit/plumbing v1.2.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.3.0 // indirect
|
||||
github.com/bodgit/windows v1.0.0 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/casbin/govaluate v1.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/connesc/cipherio v0.2.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dsnet/compress v0.0.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
@@ -72,25 +79,30 @@ require (
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.1 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
|
||||
github.com/jackc/pgx/v5 v5.5.5 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/klauspost/compress v1.15.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8 // indirect
|
||||
github.com/microsoft/go-mssqldb v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
@@ -98,7 +110,9 @@ require (
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/montanaflynn/stats v0.7.0 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.2.1 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
@@ -110,10 +124,12 @@ require (
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
@@ -124,13 +140,14 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/image v0.11.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/image v0.15.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/tools v0.16.1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/datatypes v1.2.0 // indirect
|
||||
|
||||
+91
-29
@@ -42,25 +42,37 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aov
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible h1:KpbJFXwhVeuxNtBJ74MCGbIoaBok2uZvkD7QXp2+Wis=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/aws/aws-sdk-go v1.44.307 h1:2R0/EPgpZcFSUwZhYImq/srjaOrOfLv5MNRzrFyAM38=
|
||||
github.com/aws/aws-sdk-go v1.44.307/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bodgit/plumbing v1.2.0 h1:gg4haxoKphLjml+tgnecR4yLBV5zo4HAZGCtAh3xCzM=
|
||||
github.com/bodgit/plumbing v1.2.0/go.mod h1:b9TeRi7Hvc6Y05rjm8VML3+47n4XTZPtQ/5ghqic2n8=
|
||||
github.com/bodgit/sevenzip v1.3.0 h1:1ljgELgtHqvgIp8W8kgeEGHIWP4ch3xGI8uOBZgLVKY=
|
||||
github.com/bodgit/sevenzip v1.3.0/go.mod h1:omwNcgZTEooWM8gA/IJ2Nk/+ZQ94+GsytRzOJJ8FBlM=
|
||||
github.com/bodgit/windows v1.0.0 h1:rLQ/XjsleZvx4fR1tB/UxQrK+SJ2OFHzfPjLWWOhDIA=
|
||||
github.com/bodgit/windows v1.0.0/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM=
|
||||
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
|
||||
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
|
||||
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
|
||||
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/casbin/casbin/v2 v2.71.1 h1:LRHyqM0S1LzM/K59PmfUIN0ZJfLgcOjL4OhOQI/FNXU=
|
||||
github.com/casbin/casbin/v2 v2.71.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/casbin/casbin/v2 v2.87.1 h1:7H+ENAfYt3HmZJVw++tJsxx/ko7WEHsfNzpOdYTkpYo=
|
||||
github.com/casbin/casbin/v2 v2.87.1/go.mod h1:jX8uoN4veP85O/n2674r2qtfSXI6myvxW85f6TH50fw=
|
||||
github.com/casbin/gorm-adapter/v3 v3.18.0 h1:0td7v030eK3H5ftXRHx1d5wVPbuYEJP2ObMSUHtA0Ek=
|
||||
github.com/casbin/gorm-adapter/v3 v3.18.0/go.mod h1:ekufPNBgVIQvv9JffVGsg7KUv4DjnevTh6AQnBNkoK8=
|
||||
github.com/casbin/govaluate v1.1.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
|
||||
github.com/casbin/govaluate v1.1.1 h1:J1rFKIBhiC5xr0APd5HP6rDL+xt+BRoyq1pa4o2i/5c=
|
||||
github.com/casbin/govaluate v1.1.1/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -76,6 +88,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/connesc/cipherio v0.2.1 h1:FGtpTPMbKNNWByNrr9aEBtaJtXjqOzkIXNYJp6OEycw=
|
||||
github.com/connesc/cipherio v0.2.1/go.mod h1:ukY0MWJDFnJEbXMQtOcn2VmTpRfzcTz4OoVrWGGJZcA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -83,6 +97,9 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
||||
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@@ -94,6 +111,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||
github.com/flipped-aurora/ws v1.0.2 h1:oEUz7sgrbPENvgli7Q4QpC0NIEbJucgR4yjcDMg/AjY=
|
||||
github.com/flipped-aurora/ws v1.0.2/go.mod h1:RdyM2Fnvxx7f7A6WSmU1aAhDrQIAVW7LS/0LsAUE5mE=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
|
||||
@@ -101,6 +119,7 @@ github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yH
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
@@ -125,6 +144,7 @@ github.com/go-openapi/swag v0.22.5 h1:fVS63IE3M0lsuWRzuom3RLwUMVI2peDH01s6M70ugy
|
||||
github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
@@ -184,10 +204,12 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -199,7 +221,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
@@ -220,6 +241,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -234,6 +256,11 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@@ -246,10 +273,12 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
|
||||
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
|
||||
@@ -275,23 +304,32 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
@@ -303,6 +341,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrSSDunscGsRM=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A=
|
||||
github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu2lKYc=
|
||||
github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk=
|
||||
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
@@ -317,13 +357,15 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
||||
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
|
||||
github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew03H+Tw=
|
||||
github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU=
|
||||
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
|
||||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q0rDaRO0MPaOk=
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
|
||||
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
|
||||
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
@@ -333,6 +375,8 @@ github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI=
|
||||
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -342,6 +386,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/qiniu/api.v7/v7 v7.4.1 h1:BnNUBimLk6nrA/mIwsww9yJRupmViSsb1ndLMC7a9OY=
|
||||
github.com/qiniu/api.v7/v7 v7.4.1/go.mod h1:VE5oC5rkE1xul0u1S2N0b2Uxq9/6hZzhyqjgK25XDcM=
|
||||
@@ -361,6 +407,8 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/shirou/gopsutil/v3 v3.23.6 h1:5y46WPI9QBKBbK7EEccUPNXpJpNrvPuTD0O2zHEHT08=
|
||||
github.com/shirou/gopsutil/v3 v3.23.6/go.mod h1:j7QX50DrXYggrpN30W0Mo+I4/8U2UUIQrnrhqUeWrAU=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
@@ -408,6 +456,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.42 h1:Up1704BJjI5orycXKjpVpvuOInt9GC5pqY4knyE9Uds=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.42/go.mod h1:LUFnaqRmGk6pEHOaRmdn2dCZR2j0cSsM5xowWFPTPao=
|
||||
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
|
||||
github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
@@ -419,6 +469,9 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk=
|
||||
github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
@@ -459,7 +512,10 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
@@ -467,6 +523,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
@@ -483,8 +541,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -496,10 +554,11 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
|
||||
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
|
||||
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -524,6 +583,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -563,8 +623,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -639,8 +699,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.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=
|
||||
@@ -662,6 +722,7 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.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 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -814,12 +875,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -837,10 +898,10 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco=
|
||||
gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04=
|
||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
||||
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
||||
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
|
||||
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
|
||||
gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
|
||||
gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
|
||||
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/driver/sqlserver v1.5.1 h1:wpyW/pR26U94uaujltiFGXY7fd2Jw5hC9PB1ZF/Y5s4=
|
||||
@@ -848,8 +909,9 @@ gorm.io/driver/sqlserver v1.5.1/go.mod h1:AYHzzte2msKTmYBYsSIq8ZUsznLJwBdkB2wpI+
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
|
||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
|
||||
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/plugin/dbresolver v1.4.1 h1:Ug4LcoPhrvqq71UhxtF346f+skTYoCa/nEsdjvHwEzk=
|
||||
gorm.io/plugin/dbresolver v1.4.1/go.mod h1:CTbCtMWhsjXSiJqiW2R8POvJ2cq18RVOl4WGyT5nhNc=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -49,6 +49,8 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error
|
||||
sysModel.SysAuthorityBtn{},
|
||||
sysModel.SysAutoCode{},
|
||||
sysModel.SysExportTemplate{},
|
||||
sysModel.Condition{},
|
||||
sysModel.JoinTemplate{},
|
||||
|
||||
adapter.CasbinRule{},
|
||||
|
||||
@@ -85,6 +87,8 @@ func (e *ensureTables) TableCreated(ctx context.Context) bool {
|
||||
sysModel.SysAuthorityBtn{},
|
||||
sysModel.SysAutoCode{},
|
||||
sysModel.SysExportTemplate{},
|
||||
sysModel.Condition{},
|
||||
sysModel.JoinTemplate{},
|
||||
|
||||
adapter.CasbinRule{},
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ func RegisterTables() {
|
||||
system.SysAuthorityBtn{},
|
||||
system.SysAutoCode{},
|
||||
system.SysExportTemplate{},
|
||||
system.Condition{},
|
||||
system.JoinTemplate{},
|
||||
|
||||
example.ExaFile{},
|
||||
example.ExaCustomer{},
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/config"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
type DBBASE interface {
|
||||
GetLogMode() string
|
||||
}
|
||||
|
||||
var Gorm = new(_gorm)
|
||||
|
||||
type _gorm struct{}
|
||||
@@ -22,41 +18,31 @@ type _gorm struct{}
|
||||
// Config gorm 自定义配置
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (g *_gorm) Config(prefix string, singular bool) *gorm.Config {
|
||||
config := &gorm.Config{
|
||||
var general config.GeneralDB
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
general = global.GVA_CONFIG.Mysql.GeneralDB
|
||||
case "pgsql":
|
||||
general = global.GVA_CONFIG.Pgsql.GeneralDB
|
||||
case "oracle":
|
||||
general = global.GVA_CONFIG.Oracle.GeneralDB
|
||||
case "sqlite":
|
||||
general = global.GVA_CONFIG.Sqlite.GeneralDB
|
||||
case "mssql":
|
||||
general = global.GVA_CONFIG.Mssql.GeneralDB
|
||||
default:
|
||||
general = global.GVA_CONFIG.Mysql.GeneralDB
|
||||
}
|
||||
return &gorm.Config{
|
||||
Logger: logger.New(NewWriter(general, log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{
|
||||
SlowThreshold: 200 * time.Millisecond,
|
||||
LogLevel: general.LogLevel(),
|
||||
Colorful: true,
|
||||
}),
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
TablePrefix: prefix,
|
||||
SingularTable: singular,
|
||||
},
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
}
|
||||
_default := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{
|
||||
SlowThreshold: 200 * time.Millisecond,
|
||||
LogLevel: logger.Warn,
|
||||
Colorful: true,
|
||||
})
|
||||
var logMode DBBASE
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
logMode = &global.GVA_CONFIG.Mysql
|
||||
case "pgsql":
|
||||
logMode = &global.GVA_CONFIG.Pgsql
|
||||
case "oracle":
|
||||
logMode = &global.GVA_CONFIG.Oracle
|
||||
default:
|
||||
logMode = &global.GVA_CONFIG.Mysql
|
||||
}
|
||||
|
||||
switch logMode.GetLogMode() {
|
||||
case "silent", "Silent":
|
||||
config.Logger = _default.LogMode(logger.Silent)
|
||||
case "error", "Error":
|
||||
config.Logger = _default.LogMode(logger.Error)
|
||||
case "warn", "Warn":
|
||||
config.Logger = _default.LogMode(logger.Warn)
|
||||
case "info", "Info":
|
||||
config.Logger = _default.LogMode(logger.Info)
|
||||
default:
|
||||
config.Logger = _default.LogMode(logger.Info)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/config"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
type Writer struct {
|
||||
config config.GeneralDB
|
||||
writer logger.Writer
|
||||
}
|
||||
|
||||
func NewWriter(config config.GeneralDB, writer logger.Writer) *Writer {
|
||||
return &Writer{config: config, writer: writer}
|
||||
}
|
||||
|
||||
// Printf 格式化打印日志
|
||||
func (c *Writer) Printf(message string, data ...any) {
|
||||
if c.config.LogZap {
|
||||
switch c.config.LogLevel() {
|
||||
case logger.Silent:
|
||||
zap.L().Debug(fmt.Sprintf(message, data...))
|
||||
case logger.Error:
|
||||
zap.L().Error(fmt.Sprintf(message, data...))
|
||||
case logger.Warn:
|
||||
zap.L().Warn(fmt.Sprintf(message, data...))
|
||||
case logger.Info:
|
||||
zap.L().Info(fmt.Sprintf(message, data...))
|
||||
default:
|
||||
zap.L().Info(fmt.Sprintf(message, data...))
|
||||
}
|
||||
return
|
||||
}
|
||||
c.writer.Printf(message, data...)
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
type writer struct {
|
||||
logger.Writer
|
||||
}
|
||||
|
||||
// NewWriter writer 构造函数
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func NewWriter(w logger.Writer) *writer {
|
||||
return &writer{Writer: w}
|
||||
}
|
||||
|
||||
// Printf 格式化打印日志
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (w *writer) Printf(message string, data ...interface{}) {
|
||||
var logZap bool
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
logZap = global.GVA_CONFIG.Mysql.LogZap
|
||||
case "pgsql":
|
||||
logZap = global.GVA_CONFIG.Pgsql.LogZap
|
||||
}
|
||||
if logZap {
|
||||
global.GVA_LOG.Info(fmt.Sprintf(message+"\n", data...))
|
||||
} else {
|
||||
w.Writer.Printf(message, data...)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/middleware"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/email"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/utils/plugin"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -17,12 +16,10 @@ func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) {
|
||||
}
|
||||
}
|
||||
|
||||
func InstallPlugin(Router *gin.Engine) {
|
||||
PublicGroup := Router.Group("")
|
||||
fmt.Println("无鉴权插件安装==》", PublicGroup)
|
||||
PrivateGroup := Router.Group("")
|
||||
func InstallPlugin(PrivateGroup *gin.RouterGroup, PublicRouter *gin.RouterGroup) {
|
||||
fmt.Println("无鉴权插件安装==》", PublicRouter)
|
||||
|
||||
fmt.Println("鉴权插件安装==》", PrivateGroup)
|
||||
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
|
||||
// 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
|
||||
PluginInit(PrivateGroup, email.CreateEmailPlug(
|
||||
global.GVA_CONFIG.Email.To,
|
||||
|
||||
@@ -11,11 +11,21 @@ import (
|
||||
|
||||
func Redis() {
|
||||
redisCfg := global.GVA_CONFIG.Redis
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: redisCfg.Addr,
|
||||
Password: redisCfg.Password, // no password set
|
||||
DB: redisCfg.DB, // use default DB
|
||||
})
|
||||
var client redis.UniversalClient
|
||||
// 使用集群模式
|
||||
if redisCfg.UseCluster {
|
||||
client = redis.NewClusterClient(&redis.ClusterOptions{
|
||||
Addrs: redisCfg.ClusterAddrs,
|
||||
Password: redisCfg.Password,
|
||||
})
|
||||
} else {
|
||||
// 使用单例模式
|
||||
client = redis.NewClient(&redis.Options{
|
||||
Addr: redisCfg.Addr,
|
||||
Password: redisCfg.Password,
|
||||
DB: redisCfg.DB,
|
||||
})
|
||||
}
|
||||
pong, err := client.Ping(context.Background()).Result()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("redis connect ping failed, err:", zap.Error(err))
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/docs"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/middleware"
|
||||
@@ -8,8 +11,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type justFilesFilesystem struct {
|
||||
@@ -33,19 +34,12 @@ func (fs justFilesFilesystem) Open(name string) (http.File, error) {
|
||||
// 初始化总路由
|
||||
|
||||
func Routers() *gin.Engine {
|
||||
|
||||
// 设置为发布模式
|
||||
if global.GVA_CONFIG.System.Env == "public" {
|
||||
gin.SetMode(gin.ReleaseMode) //DebugMode ReleaseMode TestMode
|
||||
}
|
||||
|
||||
Router := gin.New()
|
||||
Router.Use(gin.Recovery())
|
||||
if global.GVA_CONFIG.System.Env != "public" {
|
||||
if gin.Mode() == gin.DebugMode {
|
||||
Router.Use(gin.Logger())
|
||||
}
|
||||
|
||||
InstallPlugin(Router) // 安装插件
|
||||
systemRouter := router.RouterGroupApp.System
|
||||
exampleRouter := router.RouterGroupApp.Example
|
||||
// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
|
||||
@@ -99,6 +93,9 @@ func Routers() *gin.Engine {
|
||||
|
||||
}
|
||||
|
||||
//插件路由安装
|
||||
InstallPlugin(PrivateGroup, PublicGroup)
|
||||
|
||||
global.GVA_LOG.Info("router register success")
|
||||
return Router
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "go.uber.org/automaxprocs"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/core"
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
//go:generate go mod download
|
||||
|
||||
// @title Gin-Vue-Admin Swagger API接口文档
|
||||
// @version v2.6.1
|
||||
// @version v2.6.5
|
||||
// @description 使用gin+vue进行极速开发的全栈开发基础平台
|
||||
// @securityDefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
|
||||
@@ -16,22 +16,20 @@ var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
|
||||
// CasbinHandler 拦截器
|
||||
func CasbinHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if global.GVA_CONFIG.System.Env != "develop" {
|
||||
waitUse, _ := utils.GetClaims(c)
|
||||
//获取请求的PATH
|
||||
path := c.Request.URL.Path
|
||||
obj := strings.TrimPrefix(path, global.GVA_CONFIG.System.RouterPrefix)
|
||||
// 获取请求方法
|
||||
act := c.Request.Method
|
||||
// 获取用户的角色
|
||||
sub := strconv.Itoa(int(waitUse.AuthorityId))
|
||||
e := casbinService.Casbin() // 判断策略中是否存在
|
||||
success, _ := e.Enforce(sub, obj, act)
|
||||
if !success {
|
||||
response.FailWithDetailed(gin.H{}, "权限不足", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
waitUse, _ := utils.GetClaims(c)
|
||||
//获取请求的PATH
|
||||
path := c.Request.URL.Path
|
||||
obj := strings.TrimPrefix(path, global.GVA_CONFIG.System.RouterPrefix)
|
||||
// 获取请求方法
|
||||
act := c.Request.Method
|
||||
// 获取用户的角色
|
||||
sub := strconv.Itoa(int(waitUse.AuthorityId))
|
||||
e := casbinService.Casbin() // 判断策略中是否存在
|
||||
success, _ := e.Enforce(sub, obj, act)
|
||||
if !success {
|
||||
response.FailWithDetailed(gin.H{}, "权限不足", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ func JWTAuth() gin.HandlerFunc {
|
||||
// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
|
||||
token := utils.GetToken(c)
|
||||
if token == "" {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
|
||||
response.NoAuth("未登录或非法访问", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
if jwtService.IsBlacklist(token) {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
|
||||
response.NoAuth("您的帐户异地登陆或令牌失效", c)
|
||||
utils.ClearToken(c)
|
||||
c.Abort()
|
||||
return
|
||||
@@ -38,12 +38,12 @@ func JWTAuth() gin.HandlerFunc {
|
||||
claims, err := j.ParseToken(token)
|
||||
if err != nil {
|
||||
if errors.Is(err, utils.TokenExpired) {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
|
||||
response.NoAuth("授权已过期", c)
|
||||
utils.ClearToken(c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
|
||||
response.NoAuth(err.Error(), c)
|
||||
utils.ClearToken(c)
|
||||
c.Abort()
|
||||
return
|
||||
@@ -58,7 +58,6 @@ func JWTAuth() gin.HandlerFunc {
|
||||
// c.Abort()
|
||||
//}
|
||||
c.Set("claims", claims)
|
||||
c.Next()
|
||||
if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime {
|
||||
dr, _ := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
|
||||
claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(dr))
|
||||
@@ -78,5 +77,13 @@ func JWTAuth() gin.HandlerFunc {
|
||||
_ = jwtService.SetRedisJWT(newToken, newClaims.Username)
|
||||
}
|
||||
}
|
||||
c.Next()
|
||||
|
||||
if newToken, exists := c.Get("new-token"); exists {
|
||||
c.Header("new-token", newToken.(string))
|
||||
}
|
||||
if newExpiresAt, exists := c.Get("new-expires-at"); exists {
|
||||
c.Header("new-expires-at", newExpiresAt.(string))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,14 @@ func FailWithMessage(message string, c *gin.Context) {
|
||||
Result(ERROR, map[string]interface{}{}, message, c)
|
||||
}
|
||||
|
||||
func NoAuth(message string, c *gin.Context) {
|
||||
c.JSON(http.StatusUnauthorized, Response{
|
||||
7,
|
||||
nil,
|
||||
message,
|
||||
})
|
||||
}
|
||||
|
||||
func FailWithDetailed(data interface{}, message string, c *gin.Context) {
|
||||
Result(ERROR, data, message, c)
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@ import (
|
||||
)
|
||||
|
||||
type InitDB struct {
|
||||
DBType string `json:"dbType"` // 数据库类型
|
||||
Host string `json:"host"` // 服务器地址
|
||||
Port string `json:"port"` // 数据库连接端口
|
||||
UserName string `json:"userName"` // 数据库用户名
|
||||
Password string `json:"password"` // 数据库密码
|
||||
DBName string `json:"dbName" binding:"required"` // 数据库名
|
||||
DBPath string `json:"dbPath"` // sqlite数据库文件路径
|
||||
AdminPassword string `json:"adminPassword" binding:"required"`
|
||||
DBType string `json:"dbType"` // 数据库类型
|
||||
Host string `json:"host"` // 服务器地址
|
||||
Port string `json:"port"` // 数据库连接端口
|
||||
UserName string `json:"userName"` // 数据库用户名
|
||||
Password string `json:"password"` // 数据库密码
|
||||
DBName string `json:"dbName" binding:"required"` // 数据库名
|
||||
DBPath string `json:"dbPath"` // sqlite数据库文件路径
|
||||
}
|
||||
|
||||
// MysqlEmptyDsn msyql 空数据库 建库链接
|
||||
|
||||
@@ -14,7 +14,7 @@ type AddMenuAuthorityInfo struct {
|
||||
func DefaultMenu() []system.SysBaseMenu {
|
||||
return []system.SysBaseMenu{{
|
||||
GVA_MODEL: global.GVA_MODEL{ID: 1},
|
||||
ParentId: "0",
|
||||
ParentId: 0,
|
||||
Path: "dashboard",
|
||||
Name: "dashboard",
|
||||
Component: "view/dashboard/index.vue",
|
||||
|
||||
@@ -2,7 +2,7 @@ package system
|
||||
|
||||
type SysMenu struct {
|
||||
SysBaseMenu
|
||||
MenuId string `json:"menuId" gorm:"comment:菜单ID"`
|
||||
MenuId uint `json:"menuId" gorm:"comment:菜单ID"`
|
||||
AuthorityId uint `json:"-" gorm:"comment:角色ID"`
|
||||
Children []SysMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters" gorm:"foreignKey:SysBaseMenuID;references:MenuId"`
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/token"
|
||||
"strings"
|
||||
|
||||
@@ -10,29 +9,39 @@ import (
|
||||
|
||||
// AutoCodeStruct 初始版本自动化代码工具
|
||||
type AutoCodeStruct struct {
|
||||
StructName string `json:"structName"` // Struct名称
|
||||
TableName string `json:"tableName"` // 表名
|
||||
PackageName string `json:"packageName"` // 文件名称
|
||||
HumpPackageName string `json:"humpPackageName"` // go文件名称
|
||||
Abbreviation string `json:"abbreviation"` // Struct简称
|
||||
Description string `json:"description"` // Struct中文名称
|
||||
AutoCreateApiToSql bool `json:"autoCreateApiToSql"` // 是否自动创建api
|
||||
AutoCreateResource bool `json:"autoCreateResource"` // 是否自动创建资源标识
|
||||
AutoMoveFile bool `json:"autoMoveFile"` // 是否自动移动文件
|
||||
BusinessDB string `json:"businessDB"` // 业务数据库
|
||||
GvaModel bool `json:"gvaModel"` // 是否使用gva默认Model
|
||||
Fields []*Field `json:"fields"`
|
||||
PrimaryField *Field `json:"primaryField"`
|
||||
HasTimer bool `json:"-"`
|
||||
HasSearchTimer bool `json:"-"`
|
||||
DictTypes []string `json:"-"`
|
||||
Package string `json:"package"`
|
||||
PackageT string `json:"-"`
|
||||
NeedSort bool `json:"-"`
|
||||
HasPic bool `json:"-"`
|
||||
HasRichText bool `json:"-"`
|
||||
HasFile bool `json:"-"`
|
||||
NeedJSON bool `json:"-"`
|
||||
StructName string `json:"structName"` // Struct名称
|
||||
TableName string `json:"tableName"` // 表名
|
||||
PackageName string `json:"packageName"` // 文件名称
|
||||
HumpPackageName string `json:"humpPackageName"` // go文件名称
|
||||
Abbreviation string `json:"abbreviation"` // Struct简称
|
||||
Description string `json:"description"` // Struct中文名称
|
||||
AutoCreateApiToSql bool `json:"autoCreateApiToSql"` // 是否自动创建api
|
||||
AutoCreateMenuToSql bool `json:"autoCreateMenuToSql"` // 是否自动创建menu
|
||||
AutoCreateResource bool `json:"autoCreateResource"` // 是否自动创建资源标识
|
||||
BusinessDB string `json:"businessDB"` // 业务数据库
|
||||
GvaModel bool `json:"gvaModel"` // 是否使用gva默认Model
|
||||
Fields []*Field `json:"fields"`
|
||||
PrimaryField *Field `json:"primaryField"`
|
||||
HasTimer bool `json:"-"`
|
||||
HasSearchTimer bool `json:"-"`
|
||||
DictTypes []string `json:"-"`
|
||||
Package string `json:"package"`
|
||||
PackageT string `json:"-"`
|
||||
NeedSort bool `json:"-"`
|
||||
HasPic bool `json:"-"`
|
||||
HasRichText bool `json:"-"`
|
||||
HasFile bool `json:"-"`
|
||||
NeedJSON bool `json:"-"`
|
||||
FrontFields []*Field `json:"-"`
|
||||
HasDataSource bool `json:"-"`
|
||||
DataSourceMap map[string]*DataSource `json:"-"`
|
||||
}
|
||||
|
||||
type DataSource struct {
|
||||
Association int `json:"association"` // 关联关系 1 一对一 2 一对多
|
||||
Table string `json:"table"`
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (a *AutoCodeStruct) Pretreatment() {
|
||||
@@ -57,24 +66,26 @@ func (a *AutoCodeStruct) SuffixTest() {
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
FieldName string `json:"fieldName"` // Field名
|
||||
FieldDesc string `json:"fieldDesc"` // 中文名
|
||||
FieldType string `json:"fieldType"` // Field数据类型
|
||||
FieldJson string `json:"fieldJson"` // FieldJson
|
||||
DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度
|
||||
Comment string `json:"comment"` // 数据库字段描述
|
||||
ColumnName string `json:"columnName"` // 数据库字段
|
||||
FieldSearchType string `json:"fieldSearchType"` // 搜索条件
|
||||
DictType string `json:"dictType"` // 字典
|
||||
Require bool `json:"require"` // 是否必填
|
||||
ErrorText string `json:"errorText"` // 校验失败文字
|
||||
Clearable bool `json:"clearable"` // 是否可清空
|
||||
Sort bool `json:"sort"` // 是否增加排序
|
||||
PrimaryKey bool `json:"primaryKey"` // 是否主键
|
||||
FieldName string `json:"fieldName"` // Field名
|
||||
FieldDesc string `json:"fieldDesc"` // 中文名
|
||||
FieldType string `json:"fieldType"` // Field数据类型
|
||||
FieldJson string `json:"fieldJson"` // FieldJson
|
||||
DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度
|
||||
Comment string `json:"comment"` // 数据库字段描述
|
||||
ColumnName string `json:"columnName"` // 数据库字段
|
||||
FieldSearchType string `json:"fieldSearchType"` // 搜索条件
|
||||
DictType string `json:"dictType"` // 字典
|
||||
Front bool `json:"front"` // 是否前端可见
|
||||
Require bool `json:"require"` // 是否必填
|
||||
DefaultValue string `json:"defaultValue"` // 是否必填
|
||||
ErrorText string `json:"errorText"` // 校验失败文字
|
||||
Clearable bool `json:"clearable"` // 是否可清空
|
||||
Sort bool `json:"sort"` // 是否增加排序
|
||||
PrimaryKey bool `json:"primaryKey"` // 是否主键
|
||||
DataSource *DataSource `json:"dataSource"` // 数据源
|
||||
CheckDataSource bool `json:"checkDataSource"` // 是否检查数据源
|
||||
}
|
||||
|
||||
var ErrAutoMove error = errors.New("创建代码成功并移动文件成功")
|
||||
|
||||
type SysAutoCode struct {
|
||||
global.GVA_MODEL
|
||||
PackageName string `json:"packageName" gorm:"comment:包名"`
|
||||
|
||||
@@ -14,6 +14,7 @@ type SysAutoCodeHistory struct {
|
||||
Package string `json:"package"`
|
||||
BusinessDB string `json:"businessDB"`
|
||||
TableName string `json:"tableName"`
|
||||
MenuID uint `json:"menuID"`
|
||||
RequestMeta string `gorm:"type:text" json:"requestMeta,omitempty"` // 前端传入的结构化信息
|
||||
AutoCodePath string `gorm:"type:text" json:"autoCodePath,omitempty"` // 其他meta信息 path;path
|
||||
InjectionMeta string `gorm:"type:text" json:"injectionMeta,omitempty"` // 注入的内容 RouterPath@functionName@RouterString;
|
||||
|
||||
@@ -6,34 +6,34 @@ import (
|
||||
|
||||
type SysBaseMenu struct {
|
||||
global.GVA_MODEL
|
||||
MenuLevel uint `json:"-"`
|
||||
ParentId string `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
|
||||
Path string `json:"path" gorm:"comment:路由path"` // 路由path
|
||||
Name string `json:"name" gorm:"comment:路由name"` // 路由name
|
||||
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
|
||||
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
|
||||
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
|
||||
Meta `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
|
||||
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
|
||||
Children []SysBaseMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters"`
|
||||
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
|
||||
MenuLevel uint `json:"-"`
|
||||
ParentId uint `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
|
||||
Path string `json:"path" gorm:"comment:路由path"` // 路由path
|
||||
Name string `json:"name" gorm:"comment:路由name"` // 路由name
|
||||
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
|
||||
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
|
||||
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
|
||||
Meta `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
|
||||
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
|
||||
Children []SysBaseMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters"`
|
||||
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
|
||||
}
|
||||
|
||||
type Meta struct {
|
||||
ActiveName string `json:"activeName" gorm:"comment:高亮菜单"`
|
||||
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
|
||||
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
|
||||
DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
|
||||
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
|
||||
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
|
||||
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
|
||||
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
|
||||
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
|
||||
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
|
||||
}
|
||||
|
||||
type SysBaseMenuParameter struct {
|
||||
global.GVA_MODEL
|
||||
SysBaseMenuID uint
|
||||
Type string `json:"type" gorm:"comment:地址栏携带参数为params还是query"` // 地址栏携带参数为params还是query
|
||||
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
|
||||
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
|
||||
Value string `json:"value" gorm:"comment:地址栏携带参数的值"` // 地址栏携带参数的值
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
type SysDictionaryDetail struct {
|
||||
global.GVA_MODEL
|
||||
Label string `json:"label" form:"label" gorm:"column:label;comment:展示值"` // 展示值
|
||||
Value int `json:"value" form:"value" gorm:"column:value;comment:字典值"` // 字典值
|
||||
Value string `json:"value" form:"value" gorm:"column:value;comment:字典值"` // 字典值
|
||||
Extend string `json:"extend" form:"extend" gorm:"column:extend;comment:扩展值"` // 扩展值
|
||||
Status *bool `json:"status" form:"status" gorm:"column:status;comment:启用状态"` // 启用状态
|
||||
Sort int `json:"sort" form:"sort" gorm:"column:sort;comment:排序标记"` // 排序标记
|
||||
|
||||
@@ -8,8 +8,37 @@ import (
|
||||
// 导出模板 结构体 SysExportTemplate
|
||||
type SysExportTemplate struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:模板名称;"` //模板名称
|
||||
TableName string `json:"tableName" form:"tableName" gorm:"column:table_name;comment:表名称;"` //表名称
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识;"` //模板标识
|
||||
TemplateInfo string `json:"templateInfo" form:"templateInfo" gorm:"column:template_info;type:text;"` //模板信息
|
||||
DBName string `json:"dbName" form:"dbName" gorm:"column:db_name;comment:数据库名称;"` //数据库名称
|
||||
Name string `json:"name" form:"name" gorm:"column:name;comment:模板名称;"` //模板名称
|
||||
TableName string `json:"tableName" form:"tableName" gorm:"column:table_name;comment:表名称;"` //表名称
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识;"` //模板标识
|
||||
TemplateInfo string `json:"templateInfo" form:"templateInfo" gorm:"column:template_info;type:text;"` //模板信息
|
||||
Limit int `json:"limit" form:"limit" gorm:"column:limit;comment:导出限制"`
|
||||
Order string `json:"order" form:"order" gorm:"column:order;comment:排序"`
|
||||
Conditions []Condition `json:"conditions" form:"conditions" gorm:"foreignKey:TemplateID;references:TemplateID;comment:条件"`
|
||||
JoinTemplate []JoinTemplate `json:"joinTemplate" form:"joinTemplate" gorm:"foreignKey:TemplateID;references:TemplateID;comment:关联"`
|
||||
}
|
||||
|
||||
type JoinTemplate struct {
|
||||
global.GVA_MODEL
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识"`
|
||||
JOINS string `json:"joins" form:"joins" gorm:"column:joins;comment:关联"`
|
||||
Table string `json:"table" form:"table" gorm:"column:table;comment:关联表"`
|
||||
ON string `json:"on" form:"on" gorm:"column:on;comment:关联条件"`
|
||||
}
|
||||
|
||||
func (JoinTemplate) TableName() string {
|
||||
return "sys_export_template_join"
|
||||
}
|
||||
|
||||
type Condition struct {
|
||||
global.GVA_MODEL
|
||||
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识"`
|
||||
From string `json:"from" form:"from" gorm:"column:from;comment:条件取的key"`
|
||||
Column string `json:"column" form:"column" gorm:"column:column;comment:作为查询条件的字段"`
|
||||
Operator string `json:"operator" form:"operator" gorm:"column:operator;comment:操作符"`
|
||||
}
|
||||
|
||||
func (Condition) TableName() string {
|
||||
return "sys_export_template_condition"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ type SysOperationRecord struct {
|
||||
Path string `json:"path" form:"path" gorm:"column:path;comment:请求路径"` // 请求路径
|
||||
Status int `json:"status" form:"status" gorm:"column:status;comment:请求状态"` // 请求状态
|
||||
Latency time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:延迟" swaggertype:"string"` // 延迟
|
||||
Agent string `json:"agent" form:"agent" gorm:"column:agent;comment:代理"` // 代理
|
||||
Agent string `json:"agent" form:"agent" gorm:"type:text;column:agent;comment:代理"` // 代理
|
||||
ErrorMessage string `json:"error_message" form:"error_message" gorm:"column:error_message;comment:错误信息"` // 错误信息
|
||||
Body string `json:"body" form:"body" gorm:"type:text;column:body;comment:请求Body"` // 请求Body
|
||||
Resp string `json:"resp" form:"resp" gorm:"type:text;column:resp;comment:响应Body"` // 响应Body
|
||||
|
||||
@@ -14,7 +14,6 @@ type SysUser struct {
|
||||
SideMode string `json:"sideMode" gorm:"default:dark;comment:用户侧边主题"` // 用户侧边主题
|
||||
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
|
||||
BaseColor string `json:"baseColor" gorm:"default:#fff;comment:基础颜色"` // 基础颜色
|
||||
ActiveColor string `json:"activeColor" gorm:"default:#1890ff;comment:活跃颜色"` // 活跃颜色
|
||||
AuthorityId uint `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
|
||||
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
|
||||
Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"`
|
||||
|
||||
@@ -2,9 +2,9 @@ package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func RegisterApis(apis ...system.SysApi) {
|
||||
@@ -37,13 +37,13 @@ func RegisterMenus(menus ...system.SysBaseMenu) {
|
||||
fmt.Println("插件已安装或存在同名菜单")
|
||||
return
|
||||
}
|
||||
parentMenu.ParentId = "0"
|
||||
parentMenu.ParentId = 0
|
||||
err := global.GVA_DB.Create(&parentMenu).Error
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
for i := range otherMenus {
|
||||
pid := strconv.Itoa(int(parentMenu.ID))
|
||||
pid := parentMenu.ID
|
||||
otherMenus[i].ParentId = pid
|
||||
}
|
||||
err = global.GVA_DB.Create(&otherMenus).Error
|
||||
|
||||
@@ -26,7 +26,7 @@ var {{.Abbreviation}}Service = service.ServiceGroupApp.{{.PackageT}}ServiceGroup
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body {{.Package}}.{{.StructName}} true "创建{{.Description}}"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建成功"
|
||||
// @Router /{{.Abbreviation}}/create{{.StructName}} [post]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Context) {
|
||||
var {{.Abbreviation}} {{.Package}}.{{.StructName}}
|
||||
@@ -54,7 +54,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body {{.Package}}.{{.StructName}} true "删除{{.Description}}"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除成功"
|
||||
// @Router /{{.Abbreviation}}/delete{{.StructName}} [delete]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Context) {
|
||||
{{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}")
|
||||
@@ -75,7 +75,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Con
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
|
||||
// @Success 200 {object} response.Response{msg=string} "批量删除成功"
|
||||
// @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gin.Context) {
|
||||
{{.PrimaryField.FieldJson}}s := c.QueryArray("{{.PrimaryField.FieldJson}}s[]")
|
||||
@@ -97,7 +97,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gi
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body {{.Package}}.{{.StructName}} true "更新{{.Description}}"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新成功"
|
||||
// @Router /{{.Abbreviation}}/update{{.StructName}} [put]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Context) {
|
||||
var {{.Abbreviation}} {{.Package}}.{{.StructName}}
|
||||
@@ -125,7 +125,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Con
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query {{.Package}}.{{.StructName}} true "用id查询{{.Description}}"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Success 200 {object} response.Response{data=object{re{{.Abbreviation}}={{.Package}}.{{.StructName}}},msg=string} "查询成功"
|
||||
// @Router /{{.Abbreviation}}/find{{.StructName}} [get]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Find{{.StructName}}(c *gin.Context) {
|
||||
{{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}")
|
||||
@@ -144,7 +144,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Find{{.StructName}}(c *gin.Conte
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
|
||||
// @Router /{{.Abbreviation}}/get{{.StructName}}List [get]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Context) {
|
||||
var pageInfo {{.Package}}Req.{{.StructName}}Search
|
||||
@@ -165,3 +165,38 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Co
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
{{- if .HasDataSource }}
|
||||
// Get{{.StructName}}DataSource 获取{{.StructName}}的数据源
|
||||
// @Tags {{.StructName}}
|
||||
// @Summary 获取{{.StructName}}的数据源
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=object,msg=string} "查询成功"
|
||||
// @Router /{{.Abbreviation}}/get{{.StructName}}DataSource [get]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}DataSource(c *gin.Context) {
|
||||
// 此接口为获取数据源定义的数据
|
||||
if dataSource, err := {{.Abbreviation}}Service.Get{{.StructName}}DataSource(); err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询失败", c)
|
||||
} else {
|
||||
response.OkWithData(dataSource, c)
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
// Get{{.StructName}}Public 不需要鉴权的{{.Description}}接口
|
||||
// @Tags {{.StructName}}
|
||||
// @Summary 不需要鉴权的{{.Description}}接口
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表"
|
||||
// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
|
||||
// @Router /{{.Abbreviation}}/get{{.StructName}}Public [get]
|
||||
func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}Public(c *gin.Context) {
|
||||
// 此接口不需要鉴权
|
||||
// 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑
|
||||
response.OkWithDetailed(gin.H{
|
||||
"info": "不需要鉴权的{{.Description}}接口信息",
|
||||
}, "获取成功", c)
|
||||
}
|
||||
|
||||
@@ -12,21 +12,25 @@ type {{.StructName}} struct {
|
||||
{{ if .GvaModel }} global.GVA_MODEL {{ end }}
|
||||
{{- range .Fields}}
|
||||
{{- if eq .FieldType "enum" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{- else if eq .FieldType "picture" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{- else if eq .FieldType "video" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{- else if eq .FieldType "file" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"`
|
||||
{{- else if eq .FieldType "pictures" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"`
|
||||
{{- else if eq .FieldType "richtext" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{- else if eq .FieldType "json" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"object"`
|
||||
{{- else if eq .FieldType "array" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"`
|
||||
{{- else if ne .FieldType "string" }}
|
||||
{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{- else }}
|
||||
{{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}`
|
||||
{{- end }} {{ if .FieldDesc }}//{{.FieldDesc}} {{ end }} {{- end }}
|
||||
{{- if .AutoCreateResource }}
|
||||
CreatedBy uint `gorm:"column:created_by;comment:创建者"`
|
||||
|
||||
@@ -24,11 +24,15 @@ type {{.StructName}}Search struct{
|
||||
{{- else if eq .FieldType "video" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" `
|
||||
{{- else if eq .FieldType "file" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" `
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" swaggertype:"array,object"`
|
||||
{{- else if eq .FieldType "pictures" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" `
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" swaggertype:"array,object"`
|
||||
{{- else if eq .FieldType "richtext" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" `
|
||||
{{- else if eq .FieldType "json" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" swaggertype:"object"`
|
||||
{{- else if eq .FieldType "array" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" swaggertype:"array,object"`
|
||||
{{- else if ne .FieldType "string" }}
|
||||
{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" `
|
||||
{{- else }}
|
||||
|
||||
@@ -10,9 +10,11 @@ type {{.StructName}}Router struct {
|
||||
}
|
||||
|
||||
// Init{{.StructName}}Router 初始化 {{.Description}} 路由信息
|
||||
func (s *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGroup) {
|
||||
func (s *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGroup,PublicRouter *gin.RouterGroup) {
|
||||
{{.Abbreviation}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord())
|
||||
{{.Abbreviation}}RouterWithoutRecord := Router.Group("{{.Abbreviation}}")
|
||||
{{.Abbreviation}}RouterWithoutAuth := PublicRouter.Group("{{.Abbreviation}}")
|
||||
|
||||
var {{.Abbreviation}}Api = v1.ApiGroupApp.{{.PackageT}}ApiGroup.{{.StructName}}Api
|
||||
{
|
||||
{{.Abbreviation}}Router.POST("create{{.StructName}}", {{.Abbreviation}}Api.Create{{.StructName}}) // 新建{{.Description}}
|
||||
@@ -24,4 +26,10 @@ func (s *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGrou
|
||||
{{.Abbreviation}}RouterWithoutRecord.GET("find{{.StructName}}", {{.Abbreviation}}Api.Find{{.StructName}}) // 根据ID获取{{.Description}}
|
||||
{{.Abbreviation}}RouterWithoutRecord.GET("get{{.StructName}}List", {{.Abbreviation}}Api.Get{{.StructName}}List) // 获取{{.Description}}列表
|
||||
}
|
||||
{
|
||||
{{- if .HasDataSource}}
|
||||
{{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}DataSource", {{.Abbreviation}}Api.Get{{.StructName}}DataSource) // 获取{{.Description}}数据源
|
||||
{{- end}}
|
||||
{{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}Public", {{.Abbreviation}}Api.Get{{.StructName}}Public) // 获取{{.Description}}列表
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ById
|
||||
// Update{{.StructName}} 更新{{.Description}}记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Update{{.StructName}}({{.Abbreviation}} {{.Package}}.{{.StructName}}) (err error) {
|
||||
err = {{$db}}.Save(&{{.Abbreviation}}).Error
|
||||
err = {{$db}}.Model(&{{.Package}}.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} = ?",{{.Abbreviation}}.{{.PrimaryField.FieldName}}).Updates(&{{.Abbreviation}}).Error
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -137,3 +137,15 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis
|
||||
err = db.Find(&{{.Abbreviation}}s).Error
|
||||
return {{.Abbreviation}}s, total, err
|
||||
}
|
||||
|
||||
{{- if .HasDataSource }}
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}DataSource() (res map[string][]map[string]any, err error) {
|
||||
res = make(map[string][]map[string]any)
|
||||
{{range $key, $value := .DataSourceMap}}
|
||||
{{$key}} := make([]map[string]any, 0)
|
||||
{{$db}}.Table("{{$value.Table}}").Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}})
|
||||
res["{{$key}}"] = {{$key}}
|
||||
{{- end }}
|
||||
return
|
||||
}
|
||||
{{- end }}
|
||||
@@ -95,3 +95,19 @@ export const get{{.StructName}}List = (params) => {
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
{{- if .HasDataSource}}
|
||||
// @Tags {{.StructName}}
|
||||
// @Summary 获取数据源
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /{{.Abbreviation}}/find{{.StructName}}DataSource [get]
|
||||
export const get{{.StructName}}DataSource = () => {
|
||||
return service({
|
||||
url: '/{{.Abbreviation}}/get{{.StructName}}DataSource',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
{{- end}}
|
||||
|
||||
@@ -4,24 +4,29 @@
|
||||
<el-form :model="formData" ref="elFormRef" label-position="right" :rules="rule" label-width="80px">
|
||||
{{- range .Fields}}
|
||||
<el-form-item label="{{.FieldDesc}}:" prop="{{.FieldJson}}">
|
||||
{{- if .CheckDataSource}}
|
||||
<el-select {{if eq .DataSource.Association 2}} multiple {{ end }} v-model="formData.{{.FieldJson}}" placeholder="请选择{{.FieldDesc}}" style="width:100%" :clearable="{{.Clearable}}" >
|
||||
<el-option v-for="(item,key) in dataSource.{{.FieldJson}}" :key="key" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
{{- else }}
|
||||
{{- if eq .FieldType "bool" }}
|
||||
<el-switch v-model="formData.{{.FieldJson}}" active-color="#13ce66" inactive-color="#ff4949" active-text="是" inactive-text="否" clearable ></el-switch>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "string" }}
|
||||
<el-input v-model="formData.{{.FieldJson}}" :clearable="{{.Clearable}}" placeholder="请输入" />
|
||||
{{- if .DictType}}
|
||||
<el-select v-model="formData.{{ .FieldJson }}" placeholder="请选择{{.FieldDesc}}" style="width:100%" :clearable="{{.Clearable}}" >
|
||||
<el-option v-for="(item,key) in {{ .DictType }}Options" :key="key" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
{{- else }}
|
||||
<el-input v-model="formData.{{.FieldJson}}" :clearable="{{.Clearable}}" placeholder="请输入{{.FieldDesc}}" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "richtext" }}
|
||||
<RichEdit v-model="formData.{{.FieldJson}}"/>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
{{- if .DictType }}
|
||||
<el-select v-model="formData.{{ .FieldJson }}" placeholder="请选择" :clearable="{{.Clearable}}">
|
||||
<el-option v-for="(item,key) in {{ .DictType }}Options" :key="key" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
{{- else }}
|
||||
<el-input v-model.number="formData.{{ .FieldJson }}" :clearable="{{.Clearable}}" placeholder="请输入" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "time.Time" }}
|
||||
<el-date-picker v-model="formData.{{ .FieldJson }}" type="date" placeholder="选择日期" :clearable="{{.Clearable}}"></el-date-picker>
|
||||
{{- end }}
|
||||
@@ -45,6 +50,11 @@
|
||||
{{- if eq .FieldType "file" }}
|
||||
<SelectFile v-model="formData.{{ .FieldJson }}" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "json" }}
|
||||
// 此字段为json结构,可以前端自行控制展示和数据绑定模式 需绑定json的key为 formData.{{.FieldJson}} 后端会按照json的类型进行存取
|
||||
{{"{{"}} formData.{{.FieldJson}} {{"}}"}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</el-form-item>
|
||||
{{- end }}
|
||||
<el-form-item>
|
||||
@@ -58,10 +68,13 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
{{- if .HasDataSource }}
|
||||
get{{.StructName}}DataSource,
|
||||
{{- end }}
|
||||
create{{.StructName}},
|
||||
update{{.StructName}},
|
||||
find{{.StructName}}
|
||||
} from '@/api/{{.PackageName}}'
|
||||
} from '@/api/{{.Package}}/{{.PackageName}}'
|
||||
|
||||
defineOptions({
|
||||
name: '{{.StructName}}Form'
|
||||
@@ -123,6 +136,12 @@ const formData = ref({
|
||||
{{- if eq .FieldType "file" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "json" }}
|
||||
{{.FieldJson}}: {},
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "array" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
// 验证规则
|
||||
@@ -140,6 +159,17 @@ const rule = reactive({
|
||||
|
||||
const elFormRef = ref()
|
||||
|
||||
{{- if .HasDataSource }}
|
||||
const dataSource = ref([])
|
||||
const getDataSourceFunc = async()=>{
|
||||
const res = await get{{.StructName}}DataSource()
|
||||
if (res.code === 0) {
|
||||
dataSource.value = res.data
|
||||
}
|
||||
}
|
||||
getDataSourceFunc()
|
||||
{{- end }}
|
||||
|
||||
// 初始化方法
|
||||
const init = async () => {
|
||||
// 建议通过url传参获取目标数据ID 调用 find方法进行查询数据操作 从而决定本页面是create还是update 以下为id作为url参数示例
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
</el-form-item>
|
||||
{{- else}}
|
||||
<el-form-item label="{{.FieldDesc}}" prop="{{.FieldJson}}">
|
||||
|
||||
|
||||
{{- if eq .FieldType "float64" "int"}}
|
||||
{{if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}}
|
||||
<el-input v-model.number="searchInfo.start{{.FieldName}}" placeholder="最小值" />
|
||||
@@ -86,16 +84,7 @@
|
||||
<div class="gva-table-box">
|
||||
<div class="gva-btn-list">
|
||||
<el-button type="primary" icon="plus" @click="openDialog">新增</el-button>
|
||||
<el-popover v-model:visible="deleteVisible" :disabled="!multipleSelection.length" placement="top" width="160">
|
||||
<p>确定要删除吗?</p>
|
||||
<div style="text-align: right; margin-top: 8px;">
|
||||
<el-button type="primary" link @click="deleteVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onDelete">确定</el-button>
|
||||
</div>
|
||||
<template #reference>
|
||||
<el-button icon="delete" style="margin-left: 10px;" :disabled="!multipleSelection.length" @click="deleteVisible = true">删除</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
<el-button icon="delete" style="margin-left: 10px;" :disabled="!multipleSelection.length" @click="onDelete">删除</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
@@ -110,12 +99,24 @@
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
{{ if .GvaModel }}
|
||||
<el-table-column align="left" label="日期" width="180">
|
||||
<el-table-column align="left" label="日期" prop="createdAt" width="180">
|
||||
<template #default="scope">{{ "{{ formatDate(scope.row.CreatedAt) }}" }}</template>
|
||||
</el-table-column>
|
||||
{{ end }}
|
||||
{{- range .Fields}}
|
||||
{{- if .DictType}}
|
||||
{{- range .FrontFields}}
|
||||
{{- if .CheckDataSource }}
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
|
||||
<template #default="scope">
|
||||
{{if eq .DataSource.Association 2}}
|
||||
<el-tag v-for="(item,key) in filterDataSource(dataSource.{{.FieldJson}},scope.row.{{.FieldJson}})" :key="key">
|
||||
{{ "{{ item }}" }}
|
||||
</el-tag>
|
||||
{{ else }}
|
||||
<span>{{"{{"}} filterDataSource(dataSource.{{.FieldJson}},scope.row.{{.FieldJson}}) {{"}}"}}</span>
|
||||
{{ end }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if .DictType}}
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
|
||||
<template #default="scope">
|
||||
{{"{{"}} filterDict(scope.row.{{.FieldJson}},{{.DictType}}Options) {{"}}"}}
|
||||
@@ -126,17 +127,17 @@
|
||||
<template #default="scope">{{"{{"}} formatBoolean(scope.row.{{.FieldJson}}) {{"}}"}}</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "time.Time" }}
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" width="180">
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="180">
|
||||
<template #default="scope">{{"{{"}} formatDate(scope.row.{{.FieldJson}}) {{"}}"}}</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "picture" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="200">
|
||||
<template #default="scope">
|
||||
<el-image style="width: 100px; height: 100px" :src="getUrl(scope.row.{{.FieldJson}})" fit="cover"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "pictures" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="200">
|
||||
<template #default="scope">
|
||||
<div class="multiple-img-box">
|
||||
<el-image v-for="(item,index) in scope.row.{{.FieldJson}}" :key="index" style="width: 80px; height: 80px" :src="getUrl(item)" fit="cover"/>
|
||||
@@ -144,7 +145,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "video" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="200">
|
||||
<template #default="scope">
|
||||
<video
|
||||
style="width: 100px; height: 100px"
|
||||
@@ -156,29 +157,31 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "richtext" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="200">
|
||||
<template #default="scope">
|
||||
[富文本内容]
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "file" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="200">
|
||||
<template #default="scope">
|
||||
<div class="file-list">
|
||||
<el-tag v-for="file in scope.row.{{.FieldJson}}" :key="file.uid">{{"{{"}}file.name{{"}}"}}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "json" }}
|
||||
<el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="200">
|
||||
<template #default="scope">
|
||||
[JSON]
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else }}
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<el-table-column align="left" label="操作" fixed="right" min-width="240">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link class="table-button" @click="getDetails(scope.row)">
|
||||
<el-icon style="margin-right: 5px"><InfoFilled /></el-icon>
|
||||
查看详情
|
||||
</el-button>
|
||||
<el-button type="primary" link icon="edit" class="table-button" @click="update{{.StructName}}Func(scope.row)">变更</el-button>
|
||||
<el-button type="primary" link icon="delete" @click="deleteRow(scope.row)">删除</el-button>
|
||||
</template>
|
||||
@@ -196,29 +199,52 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="type==='create'?'添加':'修改'" destroy-on-close>
|
||||
<el-scrollbar height="500px">
|
||||
<el-form :model="formData" label-position="right" ref="elFormRef" :rules="rule" label-width="80px">
|
||||
{{- range .Fields}}
|
||||
<el-drawer destroy-on-close size="800" v-model="dialogFormVisible" :show-close="false" :before-close="closeDialog">
|
||||
<template #header>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-lg">{{"{{"}}type==='create'?'添加':'修改'{{"}}"}}</span>
|
||||
<div>
|
||||
<el-button type="primary" @click="enterDialog">确 定</el-button>
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form :model="formData" label-position="top" ref="elFormRef" :rules="rule" label-width="80px">
|
||||
{{- range .FrontFields}}
|
||||
<el-form-item label="{{.FieldDesc}}:" prop="{{.FieldJson}}" >
|
||||
{{- if .CheckDataSource}}
|
||||
<el-select {{if eq .DataSource.Association 2}} multiple {{ end }} v-model="formData.{{.FieldJson}}" placeholder="请选择{{.FieldDesc}}" style="width:100%" :clearable="{{.Clearable}}" >
|
||||
<el-option v-for="(item,key) in dataSource.{{.FieldJson}}" :key="key" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
{{- else }}
|
||||
{{- if eq .FieldType "bool" }}
|
||||
<el-switch v-model="formData.{{.FieldJson}}" active-color="#13ce66" inactive-color="#ff4949" active-text="是" inactive-text="否" clearable ></el-switch>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "string" }}
|
||||
<el-input v-model="formData.{{.FieldJson}}" :clearable="{{.Clearable}}" placeholder="请输入{{.FieldDesc}}" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "richtext" }}
|
||||
<RichEdit v-model="formData.{{.FieldJson}}"/>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
{{- if .DictType}}
|
||||
<el-select v-model="formData.{{ .FieldJson }}" placeholder="请选择{{.FieldDesc}}" style="width:100%" :clearable="{{.Clearable}}" >
|
||||
<el-option v-for="(item,key) in {{ .DictType }}Options" :key="key" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
{{- else }}
|
||||
<el-input v-model.number="formData.{{ .FieldJson }}" :clearable="{{.Clearable}}" placeholder="请输入{{.FieldDesc}}" />
|
||||
<el-input v-model="formData.{{.FieldJson}}" :clearable="{{.Clearable}}" placeholder="请输入{{.FieldDesc}}" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "richtext" }}
|
||||
<RichEdit v-model="formData.{{.FieldJson}}"/>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "json" }}
|
||||
// 此字段为json结构,可以前端自行控制展示和数据绑定模式 需绑定json的key为 formData.{{.FieldJson}} 后端会按照json的类型进行存取
|
||||
{{"{{"}} formData.{{.FieldJson}} {{"}}"}}
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "array" }}
|
||||
<el-tag v-for="(item,key) in formData.{{.FieldJson}}" :key="key">
|
||||
{{ "{{ item }}" }}
|
||||
</el-tag>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
<el-input v-model.number="formData.{{ .FieldJson }}" :clearable="{{.Clearable}}" placeholder="请输入{{.FieldDesc}}" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "time.Time" }}
|
||||
<el-date-picker v-model="formData.{{ .FieldJson }}" type="date" style="width:100%" placeholder="选择日期" :clearable="{{.Clearable}}" />
|
||||
{{- end }}
|
||||
@@ -251,71 +277,27 @@
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "file" }}
|
||||
<SelectFile v-model="formData.{{ .FieldJson }}" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</el-form-item>
|
||||
{{- end }}
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
<el-button type="primary" @click="enterDialog">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="detailShow" style="width: 800px" lock-scroll :before-close="closeDetailShow" title="查看详情" destroy-on-close>
|
||||
<el-scrollbar height="550px">
|
||||
<el-descriptions :column="1" border>
|
||||
{{- range .Fields}}
|
||||
<el-descriptions-item label="{{ .FieldDesc }}">
|
||||
{{- if .DictType}}
|
||||
{{"{{"}} filterDict(formData.{{.FieldJson}},{{.DictType}}Options) {{"}}"}}
|
||||
{{- else if eq .FieldType "picture" }}
|
||||
<el-image style="width: 50px; height: 50px" :preview-src-list="ReturnArrImg(formData.{{ .FieldJson }})" :src="getUrl(formData.{{ .FieldJson }})" fit="cover" />
|
||||
{{- else if eq .FieldType "video" }}
|
||||
<video
|
||||
style="width: 50px; height: 50px"
|
||||
muted
|
||||
preload="metadata"
|
||||
>
|
||||
<source :src="getUrl(formData.{{ .FieldJson }}) + '#t=1'">
|
||||
</video>
|
||||
{{- else if eq .FieldType "pictures" }}
|
||||
<el-image style="width: 50px; height: 50px; margin-right: 10px" :preview-src-list="ReturnArrImg(formData.{{ .FieldJson }})" :initial-index="index" v-for="(item,index) in formData.{{ .FieldJson }}" :key="index" :src="getUrl(item)" fit="cover" />
|
||||
{{- else if eq .FieldType "file" }}
|
||||
<div class="fileBtn" v-for="(item,index) in formData.{{ .FieldJson }}" :key="index">
|
||||
<el-button type="primary" text bg @click="onDownloadFile(item.url)">
|
||||
<el-icon style="margin-right: 5px"><Download /></el-icon>
|
||||
{{"{{"}} item.name {{"}}"}}
|
||||
</el-button>
|
||||
</div>
|
||||
{{- else if eq .FieldType "bool" }}
|
||||
{{"{{"}} formatBoolean(formData.{{.FieldJson}}) {{"}}"}}
|
||||
{{- else if eq .FieldType "time.Time" }}
|
||||
{{"{{"}} formatDate(formData.{{.FieldJson}}) {{"}}"}}
|
||||
{{- else if eq .FieldType "richtext" }}
|
||||
[富文本内容]
|
||||
{{- else}}
|
||||
{{"{{"}} formData.{{.FieldJson}} {{"}}"}}
|
||||
{{- end }}
|
||||
</el-descriptions-item>
|
||||
{{- end }}
|
||||
</el-descriptions>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
{{- if .HasDataSource }}
|
||||
get{{.StructName}}DataSource,
|
||||
{{- end }}
|
||||
create{{.StructName}},
|
||||
delete{{.StructName}},
|
||||
delete{{.StructName}}ByIds,
|
||||
update{{.StructName}},
|
||||
find{{.StructName}},
|
||||
get{{.StructName}}List
|
||||
} from '@/api/{{.PackageName}}'
|
||||
} from '@/api/{{.Package}}/{{.PackageName}}'
|
||||
|
||||
{{- if or .HasPic .HasFile}}
|
||||
import { getUrl } from '@/utils/image'
|
||||
@@ -337,7 +319,7 @@ import SelectFile from '@/components/selectFile/selectFile.vue'
|
||||
{{- end }}
|
||||
|
||||
// 全量引入格式化工具 请按需保留
|
||||
import { getDictFunc, formatDate, formatBoolean, filterDict, ReturnArrImg, onDownloadFile } from '@/utils/format'
|
||||
import { getDictFunc, formatDate, formatBoolean, filterDict ,filterDataSource, ReturnArrImg, onDownloadFile } from '@/utils/format'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ref, reactive } from 'vue'
|
||||
|
||||
@@ -350,7 +332,7 @@ defineOptions({
|
||||
const {{ $element }}Options = ref([])
|
||||
{{- end }}
|
||||
const formData = ref({
|
||||
{{- range .Fields}}
|
||||
{{- range .FrontFields}}
|
||||
{{- if eq .FieldType "bool" }}
|
||||
{{.FieldJson}}: false,
|
||||
{{- end }}
|
||||
@@ -381,13 +363,31 @@ const formData = ref({
|
||||
{{- if eq .FieldType "file" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "json" }}
|
||||
{{.FieldJson}}: {},
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "array" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
|
||||
{{- if .HasDataSource }}
|
||||
const dataSource = ref([])
|
||||
const getDataSourceFunc = async()=>{
|
||||
const res = await get{{.StructName}}DataSource()
|
||||
if (res.code === 0) {
|
||||
dataSource.value = res.data
|
||||
}
|
||||
}
|
||||
getDataSourceFunc()
|
||||
{{- end }}
|
||||
|
||||
|
||||
|
||||
// 验证规则
|
||||
const rule = reactive({
|
||||
{{- range .Fields }}
|
||||
{{- range .FrontFields }}
|
||||
{{- if eq .Require true }}
|
||||
{{.FieldJson }} : [{
|
||||
required: true,
|
||||
@@ -420,7 +420,7 @@ const searchRule = reactive({
|
||||
}
|
||||
}, trigger: 'change' }
|
||||
],
|
||||
{{- range .Fields }}
|
||||
{{- range .FrontFields }}
|
||||
{{- if .FieldSearchType}}
|
||||
{{- if eq .FieldType "time.Time" }}
|
||||
{{.FieldJson }} : [{ validator: (rule, value, callback) => {
|
||||
@@ -453,7 +453,7 @@ const searchInfo = ref({})
|
||||
// 排序
|
||||
const sortChange = ({ prop, order }) => {
|
||||
const sortMap = {
|
||||
{{- range .Fields}}
|
||||
{{- range .FrontFields}}
|
||||
{{- if and .Sort}}
|
||||
{{- if not (eq .ColumnName "")}}
|
||||
{{.FieldJson}}: '{{.ColumnName}}',
|
||||
@@ -464,7 +464,7 @@ const sortChange = ({ prop, order }) => {
|
||||
|
||||
let sort = sortMap[prop]
|
||||
if(!sort){
|
||||
sort = prop.replace(/[A-Z]/g, match => _${match.toLowerCase()})
|
||||
sort = prop.replace(/[A-Z]/g, match => `_${match.toLowerCase()}`)
|
||||
}
|
||||
|
||||
searchInfo.value.sort = sort
|
||||
@@ -485,7 +485,7 @@ const onSubmit = () => {
|
||||
if (!valid) return
|
||||
page.value = 1
|
||||
pageSize.value = 10
|
||||
{{- range .Fields}}{{- if eq .FieldType "bool" }}
|
||||
{{- range .FrontFields}}{{- if eq .FieldType "bool" }}
|
||||
if (searchInfo.value.{{.FieldJson}} === ""){
|
||||
searchInfo.value.{{.FieldJson}}=null
|
||||
}{{ end }}{{ end }}
|
||||
@@ -549,12 +549,13 @@ const deleteRow = (row) => {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 批量删除控制标记
|
||||
const deleteVisible = ref(false)
|
||||
|
||||
// 多选删除
|
||||
const onDelete = async() => {
|
||||
ElMessageBox.confirm('确定要删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
const {{.PrimaryField.FieldJson}}s = []
|
||||
if (multipleSelection.value.length === 0) {
|
||||
ElMessage({
|
||||
@@ -576,9 +577,9 @@ const onDelete = async() => {
|
||||
if (tableData.value.length === {{.PrimaryField.FieldJson}}s.length && page.value > 1) {
|
||||
page.value--
|
||||
}
|
||||
deleteVisible.value = false
|
||||
getTableData()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 行为控制标记(弹窗内部需要增还是改)
|
||||
@@ -613,53 +614,6 @@ const delete{{.StructName}}Func = async (row) => {
|
||||
// 弹窗控制标记
|
||||
const dialogFormVisible = ref(false)
|
||||
|
||||
|
||||
// 查看详情控制标记
|
||||
const detailShow = ref(false)
|
||||
|
||||
|
||||
// 打开详情弹窗
|
||||
const openDetailShow = () => {
|
||||
detailShow.value = true
|
||||
}
|
||||
|
||||
|
||||
// 打开详情
|
||||
const getDetails = async (row) => {
|
||||
// 打开弹窗
|
||||
const res = await find{{.StructName}}({ {{.PrimaryField.FieldJson}}: row.{{.PrimaryField.FieldJson}} })
|
||||
if (res.code === 0) {
|
||||
formData.value = res.data.re{{.Abbreviation}}
|
||||
openDetailShow()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 关闭详情弹窗
|
||||
const closeDetailShow = () => {
|
||||
detailShow.value = false
|
||||
formData.value = {
|
||||
{{- range .Fields}}
|
||||
{{- if eq .FieldType "bool" }}
|
||||
{{.FieldJson}}: false,
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "string" }}
|
||||
{{.FieldJson}}: '',
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
{{.FieldJson}}: {{- if .DictType }} undefined{{ else }} 0{{- end }},
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "time.Time" }}
|
||||
{{.FieldJson}}: new Date(),
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "float64" }}
|
||||
{{.FieldJson}}: 0,
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
type.value = 'create'
|
||||
@@ -670,13 +624,16 @@ const openDialog = () => {
|
||||
const closeDialog = () => {
|
||||
dialogFormVisible.value = false
|
||||
formData.value = {
|
||||
{{- range .Fields}}
|
||||
{{- range .FrontFields}}
|
||||
{{- if eq .FieldType "bool" }}
|
||||
{{.FieldJson}}: false,
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "string" }}
|
||||
{{.FieldJson}}: '',
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "richtext" }}
|
||||
{{.FieldJson}}: '',
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
{{.FieldJson}}: {{- if .DictType }} undefined{{ else }} 0{{- end }},
|
||||
{{- end }}
|
||||
@@ -686,6 +643,21 @@ const closeDialog = () => {
|
||||
{{- if eq .FieldType "float64" }}
|
||||
{{.FieldJson}}: 0,
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "picture" }}
|
||||
{{.FieldJson}}: "",
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "video" }}
|
||||
{{.FieldJson}}: "",
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "pictures" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "file" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "json" }}
|
||||
{{.FieldJson}}: {},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package {{ .Snake}}
|
||||
|
||||
import (
|
||||
{{- if .HasGlobal }}
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/global"
|
||||
{{- end }}
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/router"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type {{ .PlugName}}Plugin struct {
|
||||
}
|
||||
|
||||
func Create{{ .PlugName}}Plug({{- range .Global}} {{.Key}} {{.Type}}, {{- end }})*{{ .PlugName}}Plugin {
|
||||
{{- if .HasGlobal }}
|
||||
{{- range .Global}}
|
||||
global.GlobalConfig.{{.Key}} = {{.Key}}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
return &{{ .PlugName}}Plugin{}
|
||||
}
|
||||
|
||||
func (*{{ .PlugName}}Plugin) Register(group *gin.RouterGroup) {
|
||||
router.RouterGroupApp.Init{{ .PlugName}}Router(group)
|
||||
}
|
||||
|
||||
func (*{{ .PlugName}}Plugin) RouterPath() string {
|
||||
return "{{ .RouterGroup}}"
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package {{ .Snake}}
|
||||
|
||||
import (
|
||||
gvaGlobal "github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/plugin-tool/utils"
|
||||
{{- if .HasGlobal }}
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/global"
|
||||
{{- end }}
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/router"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type {{ .PlugName}}Plugin struct {
|
||||
}
|
||||
|
||||
func Create{{ .PlugName}}Plug({{- range .Global}} {{.Key}} {{.Type}}, {{- end }})*{{ .PlugName }}Plugin {
|
||||
{{- if .HasGlobal }}
|
||||
{{- range .Global}}
|
||||
global.GlobalConfig.{{.Key}} = {{.Key}}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
||||
gvaGlobal.GVA_DB.AutoMigrate() // 此处可以把插件依赖的数据库结构体自动创建表 需要填写对应的结构体
|
||||
|
||||
// 下方会自动注册菜单 第一个参数为菜单一级路由信息一般为定义好的组名 第二个参数为真实使用的web页面路由信息
|
||||
// 具体值请根据实际情况修改
|
||||
utils.RegisterMenus(
|
||||
system.SysBaseMenu{
|
||||
Path: "{{ .Snake }}Group",
|
||||
Name: "{{ .Snake }}Group",
|
||||
Hidden: false,
|
||||
Component: "view/routerHolder.vue",
|
||||
Sort: 1000,
|
||||
Meta: system.Meta{
|
||||
Title: "{{ .PlugName }}组",
|
||||
Icon: "school",
|
||||
},
|
||||
},
|
||||
system.SysBaseMenu{
|
||||
Path: "{{ .Snake }}",
|
||||
Name: "{{ .Snake }}",
|
||||
Hidden: false,
|
||||
Component: "plugin/{{ .Snake }}/view/index.vue",
|
||||
Sort: 0,
|
||||
Meta: system.Meta{
|
||||
Title: "{{ .PlugName }}",
|
||||
Icon: "school",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// 下方会自动注册api 以下格式为示例格式,请按照实际情况修改
|
||||
utils.RegisterApis(
|
||||
system.SysApi{
|
||||
Path: "/{{ .RouterGroup }}/routerName",
|
||||
Description: "{{ .PlugName }}接口",
|
||||
ApiGroup: "{{ .RouterGroup }}",
|
||||
Method: "POST",
|
||||
},
|
||||
)
|
||||
|
||||
return &{{ .PlugName}}Plugin{}
|
||||
}
|
||||
|
||||
func (*{{ .PlugName}}Plugin) Register(group *gin.RouterGroup) {
|
||||
router.RouterGroupApp.Init{{ .PlugName}}Router(group)
|
||||
}
|
||||
|
||||
func (*{{ .PlugName}}Plugin) RouterPath() string {
|
||||
return "{{ .RouterGroup}}"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import service from '@/utils/request'
|
||||
|
||||
// @Router /{{ .RouterGroup }}/routerName
|
||||
export const routerName = (data) => {
|
||||
return service({
|
||||
url: '/{{ .RouterGroup }}/routerName',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div class="{{ .Snake }}">
|
||||
在此处书写页面代码
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { routerName } from '@/plugin/{{ .Snake }}/api/api.js'
|
||||
|
||||
const data = ref({})
|
||||
|
||||
defineOptions({
|
||||
name: '{{ .PlugName }}'
|
||||
})
|
||||
|
||||
const useApi = async() =>{
|
||||
const res = await routerName(data.value)
|
||||
if(res.code === 0){
|
||||
console.log(res.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.{{ .Snake }} {
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -35,8 +35,8 @@ func (apiService *ApiService) CreateApi(api system.SysApi) (err error) {
|
||||
|
||||
func (apiService *ApiService) DeleteApi(api system.SysApi) (err error) {
|
||||
var entity system.SysApi
|
||||
err = global.GVA_DB.Where("id = ?", api.ID).First(&entity).Error // 根据id查询api记录
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) { // api记录不存在
|
||||
err = global.GVA_DB.First(&entity, "id = ?", api.ID).Error // 根据id查询api记录
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) { // api记录不存在
|
||||
return err
|
||||
}
|
||||
err = global.GVA_DB.Delete(&entity).Error
|
||||
@@ -82,34 +82,27 @@ func (apiService *ApiService) GetAPIInfoList(api system.SysApi, info request.Pag
|
||||
|
||||
if err != nil {
|
||||
return apiList, total, err
|
||||
} else {
|
||||
db = db.Limit(limit).Offset(offset)
|
||||
if order != "" {
|
||||
var OrderStr string
|
||||
// 设置有效排序key 防止sql注入
|
||||
// 感谢 Tom4t0 提交漏洞信息
|
||||
orderMap := make(map[string]bool, 5)
|
||||
orderMap["id"] = true
|
||||
orderMap["path"] = true
|
||||
orderMap["api_group"] = true
|
||||
orderMap["description"] = true
|
||||
orderMap["method"] = true
|
||||
if orderMap[order] {
|
||||
if desc {
|
||||
OrderStr = order + " desc"
|
||||
} else {
|
||||
OrderStr = order
|
||||
}
|
||||
} else { // didn't match any order key in `orderMap`
|
||||
err = fmt.Errorf("非法的排序字段: %v", order)
|
||||
return apiList, total, err
|
||||
}
|
||||
}
|
||||
|
||||
err = db.Order(OrderStr).Find(&apiList).Error
|
||||
} else {
|
||||
err = db.Order("api_group").Find(&apiList).Error
|
||||
db = db.Limit(limit).Offset(offset)
|
||||
OrderStr := "id desc"
|
||||
if order != "" {
|
||||
orderMap := make(map[string]bool, 5)
|
||||
orderMap["id"] = true
|
||||
orderMap["path"] = true
|
||||
orderMap["api_group"] = true
|
||||
orderMap["description"] = true
|
||||
orderMap["method"] = true
|
||||
if !orderMap[order] {
|
||||
err = fmt.Errorf("非法的排序字段: %v", order)
|
||||
return apiList, total, err
|
||||
}
|
||||
OrderStr = order
|
||||
if desc {
|
||||
OrderStr = order + " desc"
|
||||
}
|
||||
}
|
||||
err = db.Order(OrderStr).Find(&apiList).Error
|
||||
return apiList, total, err
|
||||
}
|
||||
|
||||
@@ -130,7 +123,7 @@ func (apiService *ApiService) GetAllApis() (apis []system.SysApi, err error) {
|
||||
//@return: api model.SysApi, err error
|
||||
|
||||
func (apiService *ApiService) GetApiById(id int) (api system.SysApi, err error) {
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&api).Error
|
||||
err = global.GVA_DB.First(&api, "id = ?", id).Error
|
||||
return
|
||||
}
|
||||
|
||||
@@ -142,30 +135,30 @@ func (apiService *ApiService) GetApiById(id int) (api system.SysApi, err error)
|
||||
|
||||
func (apiService *ApiService) UpdateApi(api system.SysApi) (err error) {
|
||||
var oldA system.SysApi
|
||||
err = global.GVA_DB.Where("id = ?", api.ID).First(&oldA).Error
|
||||
err = global.GVA_DB.First(&oldA, "id = ?", api.ID).Error
|
||||
if oldA.Path != api.Path || oldA.Method != api.Method {
|
||||
var duplicateApi system.SysApi
|
||||
if err := global.GVA_DB.Where("path = ? AND method = ?", api.Path, api.Method).First(&duplicateApi).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
if ferr := global.GVA_DB.First(&duplicateApi, "path = ? AND method = ?", api.Path, api.Method).Error; ferr != nil {
|
||||
if !errors.Is(ferr, gorm.ErrRecordNotFound) {
|
||||
return ferr
|
||||
}
|
||||
} else {
|
||||
if duplicateApi.ID != api.ID {
|
||||
return errors.New("存在相同api路径")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
err = CasbinServiceApp.UpdateCasbinApi(oldA.Path, api.Path, oldA.Method, api.Method)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
err = global.GVA_DB.Save(&api).Error
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
err = CasbinServiceApp.UpdateCasbinApi(oldA.Path, api.Path, oldA.Method, api.Method)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return global.GVA_DB.Save(&api).Error
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
@@ -175,17 +168,19 @@ func (apiService *ApiService) UpdateApi(api system.SysApi) (err error) {
|
||||
//@return: err error
|
||||
|
||||
func (apiService *ApiService) DeleteApisByIds(ids request.IdsReq) (err error) {
|
||||
var apis []system.SysApi
|
||||
err = global.GVA_DB.Find(&apis, "id in ?", ids.Ids).Delete(&apis).Error
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
for _, sysApi := range apis {
|
||||
CasbinServiceApp.ClearCasbin(1, sysApi.Path, sysApi.Method)
|
||||
}
|
||||
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
var apis []system.SysApi
|
||||
err = tx.Find(&apis, "id in ?", ids.Ids).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
err = tx.Delete(&[]system.SysApi{}, "id in ?", ids.Ids).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, sysApi := range apis {
|
||||
CasbinServiceApp.ClearCasbin(1, sysApi.Path, sysApi.Method)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ package system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
|
||||
"strconv"
|
||||
|
||||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
@@ -70,7 +71,7 @@ func (authorityService *AuthorityService) CopyAuthority(copyInfo response.SysAut
|
||||
}
|
||||
var baseMenu []system.SysBaseMenu
|
||||
for _, v := range menus {
|
||||
intNum, _ := strconv.Atoi(v.MenuId)
|
||||
intNum := v.MenuId
|
||||
v.SysBaseMenu.ID = uint(intNum)
|
||||
baseMenu = append(baseMenu, v.SysBaseMenu)
|
||||
}
|
||||
@@ -111,7 +112,13 @@ func (authorityService *AuthorityService) CopyAuthority(copyInfo response.SysAut
|
||||
//@return: authority system.SysAuthority, err error
|
||||
|
||||
func (authorityService *AuthorityService) UpdateAuthority(auth system.SysAuthority) (authority system.SysAuthority, err error) {
|
||||
err = global.GVA_DB.Where("authority_id = ?", auth.AuthorityId).First(&system.SysAuthority{}).Updates(&auth).Error
|
||||
var oldAuthority system.SysAuthority
|
||||
err = global.GVA_DB.Where("authority_id = ?", auth.AuthorityId).First(&oldAuthority).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Debug(err.Error())
|
||||
return system.SysAuthority{}, errors.New("查询角色数据失败")
|
||||
}
|
||||
err = global.GVA_DB.Model(&oldAuthority).Updates(&auth).Error
|
||||
return auth, err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mholt/archiver/v4"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -30,7 +30,8 @@ import (
|
||||
const (
|
||||
autoPath = "autocode_template/"
|
||||
autocodePath = "resource/autocode_template"
|
||||
plugPath = "resource/plug_template"
|
||||
plugServerPath = "resource/plug_template/server"
|
||||
plugWebPath = "resource/plug_template/web"
|
||||
packageService = "service/%s/enter.go"
|
||||
packageServiceName = "service"
|
||||
packageRouter = "router/%s/enter.go"
|
||||
@@ -133,50 +134,7 @@ var AutoCodeServiceApp = new(AutoCodeService)
|
||||
// @return: map[string]string, error
|
||||
|
||||
func (autoCodeService *AutoCodeService) PreviewTemp(autoCode system.AutoCodeStruct) (map[string]string, error) {
|
||||
makeDictTypes(&autoCode)
|
||||
for i := range autoCode.Fields {
|
||||
if autoCode.Fields[i].FieldType == "time.Time" {
|
||||
autoCode.HasTimer = true
|
||||
if autoCode.Fields[i].FieldSearchType != "" {
|
||||
autoCode.HasSearchTimer = true
|
||||
}
|
||||
}
|
||||
if autoCode.Fields[i].Sort {
|
||||
autoCode.NeedSort = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "picture" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "video" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "richtext" {
|
||||
autoCode.HasRichText = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "pictures" {
|
||||
autoCode.HasPic = true
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "file" {
|
||||
autoCode.HasFile = true
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
|
||||
if autoCode.GvaModel {
|
||||
autoCode.PrimaryField = &system.Field{
|
||||
FieldName: "ID",
|
||||
FieldType: "uint",
|
||||
FieldDesc: "ID",
|
||||
FieldJson: "ID",
|
||||
DataTypeLong: "20",
|
||||
Comment: "主键ID",
|
||||
ColumnName: "id",
|
||||
}
|
||||
}
|
||||
if !autoCode.GvaModel && autoCode.PrimaryField == nil && autoCode.Fields[i].PrimaryKey {
|
||||
autoCode.PrimaryField = autoCode.Fields[i]
|
||||
}
|
||||
}
|
||||
fmtField(&autoCode)
|
||||
dataList, _, needMkdir, err := autoCodeService.getNeedList(&autoCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -254,55 +212,13 @@ func makeDictTypes(autoCode *system.AutoCodeStruct) {
|
||||
// @param: model.AutoCodeStruct
|
||||
// @return: err error
|
||||
|
||||
func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruct, ids ...uint) (err error) {
|
||||
makeDictTypes(&autoCode)
|
||||
for i := range autoCode.Fields {
|
||||
if autoCode.Fields[i].FieldType == "time.Time" {
|
||||
autoCode.HasTimer = true
|
||||
if autoCode.Fields[i].FieldSearchType != "" {
|
||||
autoCode.HasSearchTimer = true
|
||||
}
|
||||
}
|
||||
if autoCode.Fields[i].Sort {
|
||||
autoCode.NeedSort = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "picture" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "video" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "richtext" {
|
||||
autoCode.HasRichText = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "pictures" {
|
||||
autoCode.NeedJSON = true
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "file" {
|
||||
autoCode.NeedJSON = true
|
||||
autoCode.HasFile = true
|
||||
}
|
||||
if autoCode.GvaModel {
|
||||
autoCode.PrimaryField = &system.Field{
|
||||
FieldName: "ID",
|
||||
FieldType: "uint",
|
||||
FieldDesc: "ID",
|
||||
FieldJson: "ID",
|
||||
DataTypeLong: "20",
|
||||
Comment: "主键ID",
|
||||
ColumnName: "id",
|
||||
}
|
||||
}
|
||||
if !autoCode.GvaModel && autoCode.PrimaryField == nil && autoCode.Fields[i].PrimaryKey {
|
||||
autoCode.PrimaryField = autoCode.Fields[i]
|
||||
}
|
||||
}
|
||||
func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruct, menuID uint, ids ...uint) (err error) {
|
||||
fmtField(&autoCode)
|
||||
// 增加判断: 重复创建struct
|
||||
if autoCode.AutoMoveFile && AutoCodeHistoryServiceApp.Repeat(autoCode.BusinessDB, autoCode.StructName, autoCode.Package) {
|
||||
if AutoCodeHistoryServiceApp.Repeat(autoCode.BusinessDB, autoCode.StructName, autoCode.Package) {
|
||||
return RepeatErr
|
||||
}
|
||||
dataList, fileList, needMkdir, err := autoCodeService.getNeedList(&autoCode)
|
||||
dataList, _, needMkdir, err := autoCodeService.getNeedList(&autoCode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -342,55 +258,49 @@ func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruc
|
||||
idBf.WriteString(strconv.Itoa(int(id)))
|
||||
idBf.WriteString(";")
|
||||
}
|
||||
if autoCode.AutoMoveFile { // 判断是否需要自动转移
|
||||
Init(autoCode.Package)
|
||||
for index := range dataList {
|
||||
autoCodeService.addAutoMoveFile(&dataList[index])
|
||||
Init(autoCode.Package)
|
||||
for index := range dataList {
|
||||
autoCodeService.addAutoMoveFile(&dataList[index])
|
||||
}
|
||||
// 判断目标文件是否都可以移动
|
||||
for _, value := range dataList {
|
||||
if utils.FileExist(value.autoMoveFilePath) {
|
||||
return errors.New(fmt.Sprintf("目标文件已存在:%s\n", value.autoMoveFilePath))
|
||||
}
|
||||
// 判断目标文件是否都可以移动
|
||||
for _, value := range dataList {
|
||||
if utils.FileExist(value.autoMoveFilePath) {
|
||||
return errors.New(fmt.Sprintf("目标文件已存在:%s\n", value.autoMoveFilePath))
|
||||
}
|
||||
}
|
||||
for _, value := range dataList { // 移动文件
|
||||
if err := utils.FileMove(value.autoCodePath, value.autoMoveFilePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// 在gorm.go 注入 自动迁移
|
||||
path := filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "gorm.go")
|
||||
varDB := utils.MaheHump(autoCode.BusinessDB)
|
||||
ast2.AddRegisterTablesAst(path, "RegisterTables", autoCode.Package, varDB, autoCode.BusinessDB, autoCode.StructName)
|
||||
}
|
||||
|
||||
{
|
||||
// router.go 注入 自动迁移
|
||||
path := filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "router.go")
|
||||
ast2.AddRouterCode(path, "Routers", autoCode.Package, autoCode.StructName)
|
||||
}
|
||||
// 给各个enter进行注入
|
||||
err = injectionCode(autoCode.StructName, &injectionCodeMeta)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 保存生成信息
|
||||
for _, data := range dataList {
|
||||
if len(data.autoMoveFilePath) != 0 {
|
||||
bf.WriteString(data.autoMoveFilePath)
|
||||
bf.WriteString(";")
|
||||
}
|
||||
}
|
||||
} else { // 打包
|
||||
if err = utils.ZipFiles("./ginvueadmin.zip", fileList, ".", "."); err != nil {
|
||||
}
|
||||
for _, value := range dataList { // 移动文件
|
||||
if err := utils.FileMove(value.autoCodePath, value.autoMoveFilePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if autoCode.AutoMoveFile || autoCode.AutoCreateApiToSql {
|
||||
|
||||
{
|
||||
// 在gorm.go 注入 自动迁移
|
||||
path := filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "gorm.go")
|
||||
varDB := utils.MaheHump(autoCode.BusinessDB)
|
||||
ast2.AddRegisterTablesAst(path, "RegisterTables", autoCode.Package, varDB, autoCode.BusinessDB, autoCode.StructName)
|
||||
}
|
||||
|
||||
{
|
||||
// router.go 注入 自动迁移
|
||||
path := filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "router.go")
|
||||
ast2.AddRouterCode(path, "Routers", autoCode.Package, autoCode.StructName)
|
||||
}
|
||||
// 给各个enter进行注入
|
||||
err = injectionCode(autoCode.StructName, &injectionCodeMeta)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 保存生成信息
|
||||
for _, data := range dataList {
|
||||
if len(data.autoMoveFilePath) != 0 {
|
||||
bf.WriteString(data.autoMoveFilePath)
|
||||
bf.WriteString(";")
|
||||
}
|
||||
}
|
||||
if autoCode.AutoCreateApiToSql || autoCode.AutoCreateMenuToSql {
|
||||
if autoCode.TableName != "" {
|
||||
err = AutoCodeHistoryServiceApp.CreateAutoCodeHistory(
|
||||
string(meta),
|
||||
@@ -402,6 +312,7 @@ func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruc
|
||||
idBf.String(),
|
||||
autoCode.Package,
|
||||
autoCode.BusinessDB,
|
||||
menuID,
|
||||
)
|
||||
} else {
|
||||
err = AutoCodeHistoryServiceApp.CreateAutoCodeHistory(
|
||||
@@ -414,15 +325,13 @@ func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruc
|
||||
idBf.String(),
|
||||
autoCode.Package,
|
||||
autoCode.BusinessDB,
|
||||
menuID,
|
||||
)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if autoCode.AutoMoveFile {
|
||||
return system.ErrAutoMove
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -497,13 +406,13 @@ func (autoCodeService *AutoCodeService) addAutoMoveFile(data *tplData) {
|
||||
} else if strings.Contains(fileSlice[1], "web") {
|
||||
if strings.Contains(fileSlice[n-1], "js") {
|
||||
data.autoMoveFilePath = filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WApi, base)
|
||||
global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WApi, data.autoPackage, base)
|
||||
} else if strings.Contains(fileSlice[n-2], "form") {
|
||||
data.autoMoveFilePath = filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WForm, filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), strings.TrimSuffix(base, filepath.Ext(base))+"Form.vue")
|
||||
global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WForm, data.autoPackage, filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), strings.TrimSuffix(base, filepath.Ext(base))+"Form.vue")
|
||||
} else if strings.Contains(fileSlice[n-2], "table") {
|
||||
data.autoMoveFilePath = filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WTable, filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), base)
|
||||
global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WTable, data.autoPackage, filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), base)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -570,6 +479,21 @@ func (autoCodeService *AutoCodeService) AutoCreateApi(a *system.AutoCodeStruct)
|
||||
return ids, err
|
||||
}
|
||||
|
||||
func (autoCodeService *AutoCodeService) AutoCreateMenu(a *system.AutoCodeStruct) (id uint, err error) {
|
||||
var menu system.SysBaseMenu
|
||||
err = global.GVA_DB.First(&menu, "name = ?", a.Abbreviation).Error
|
||||
if err == nil {
|
||||
return 0, errors.New("存在相同的菜单路由,请关闭自动创建菜单功能")
|
||||
}
|
||||
menu.ParentId = 0
|
||||
menu.Name = a.Abbreviation
|
||||
menu.Path = a.Abbreviation
|
||||
menu.Meta.Title = a.Description
|
||||
menu.Component = fmt.Sprintf("view/%s/%s/%s.vue", a.Package, a.PackageName, a.PackageName)
|
||||
err = global.GVA_DB.Create(&menu).Error
|
||||
return menu.ID, err
|
||||
}
|
||||
|
||||
func (autoCodeService *AutoCodeService) getNeedList(autoCode *system.AutoCodeStruct) (dataList []tplData, fileList []string, needMkdir []string, err error) {
|
||||
// 去除所有空格
|
||||
utils.TrimSpace(autoCode)
|
||||
@@ -678,6 +602,19 @@ func (autoCodeService *AutoCodeService) CreatePackageTemp(packageName string) er
|
||||
name: packageAPIName,
|
||||
temp: string(subcontract.API),
|
||||
}}
|
||||
|
||||
webTemp := []string{
|
||||
filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WApi),
|
||||
filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Web, global.GVA_CONFIG.AutoCode.WForm),
|
||||
}
|
||||
|
||||
for _, s := range webTemp {
|
||||
err := os.MkdirAll(filepath.Join(s, packageName), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for i, s := range pendingTemp {
|
||||
pendingTemp[i].path = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, filepath.Clean(fmt.Sprintf(s.path, packageName)))
|
||||
}
|
||||
@@ -720,7 +657,19 @@ func (autoCodeService *AutoCodeService) CreatePackageTemp(packageName string) er
|
||||
func (autoCodeService *AutoCodeService) CreatePlug(plug system.AutoPlugReq) error {
|
||||
// 检查列表参数是否有效
|
||||
plug.CheckList()
|
||||
tplFileList, _ := autoCodeService.GetAllTplFile(plugPath, nil)
|
||||
err := autoCodeService.createPluginServer(plug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = autoCodeService.createPluginWeb(plug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (autoCodeService *AutoCodeService) createPluginServer(plug system.AutoPlugReq) error {
|
||||
tplFileList, _ := autoCodeService.GetAllTplFile(plugServerPath, nil)
|
||||
for _, tpl := range tplFileList {
|
||||
temp, err := template.ParseFiles(tpl)
|
||||
if err != nil {
|
||||
@@ -728,11 +677,41 @@ func (autoCodeService *AutoCodeService) CreatePlug(plug system.AutoPlugReq) erro
|
||||
return err
|
||||
}
|
||||
pathArr := strings.SplitAfter(tpl, "/")
|
||||
if strings.Index(pathArr[2], "tpl") < 0 {
|
||||
dirPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+pathArr[2]))
|
||||
if strings.Index(pathArr[3], "tpl") < 0 {
|
||||
dirPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+pathArr[3]))
|
||||
os.MkdirAll(dirPath, 0755)
|
||||
}
|
||||
file := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+tpl[len(plugPath):len(tpl)-4]))
|
||||
file := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+tpl[len(plugServerPath):len(tpl)-4]))
|
||||
f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
zap.L().Error("open file", zap.String("tpl", tpl), zap.Error(err), zap.Any("plug", plug))
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = temp.Execute(f, plug)
|
||||
if err != nil {
|
||||
zap.L().Error("exec err", zap.String("tpl", tpl), zap.Error(err), zap.Any("plug", plug))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (autoCodeService *AutoCodeService) createPluginWeb(plug system.AutoPlugReq) error {
|
||||
tplFileList, _ := autoCodeService.GetAllTplFile(plugWebPath, nil)
|
||||
for _, tpl := range tplFileList {
|
||||
temp, err := template.ParseFiles(tpl)
|
||||
if err != nil {
|
||||
zap.L().Error("parse err", zap.String("tpl", tpl), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
pathArr := strings.SplitAfter(tpl, "/")
|
||||
if strings.Index(pathArr[3], "tpl") < 0 {
|
||||
dirPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Web, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+pathArr[3]))
|
||||
os.MkdirAll(dirPath, 0755)
|
||||
}
|
||||
file := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Web, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+tpl[len(plugWebPath):len(tpl)-4]))
|
||||
f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
zap.L().Error("open file", zap.String("tpl", tpl), zap.Error(err), zap.Any("plug", plug))
|
||||
@@ -787,10 +766,10 @@ func (autoCodeService *AutoCodeService) InstallPlugin(file *multipart.FileHeader
|
||||
continue
|
||||
}
|
||||
if pathArr[2]+"/"+pathArr[3] == `server/plugin` && len(serverPlugin) == 0 {
|
||||
serverPlugin = path.Join(pathArr[0], pathArr[1], pathArr[2], pathArr[3])
|
||||
serverPlugin = filepath.Join(pathArr[0], pathArr[1], pathArr[2], pathArr[3])
|
||||
}
|
||||
if pathArr[2]+"/"+pathArr[3] == `web/plugin` && len(webPlugin) == 0 {
|
||||
webPlugin = path.Join(pathArr[0], pathArr[1], pathArr[2], pathArr[3])
|
||||
webPlugin = filepath.Join(pathArr[0], pathArr[1], pathArr[2], pathArr[3])
|
||||
}
|
||||
}
|
||||
if len(serverPlugin) == 0 && len(webPlugin) == 0 {
|
||||
@@ -875,86 +854,98 @@ func (autoCodeService *AutoCodeService) PubPlug(plugName string) (zipPath string
|
||||
|
||||
fileName := plugName + ".zip"
|
||||
// 创建一个新的zip文件
|
||||
zipFile, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer zipFile.Close()
|
||||
files, err := archiver.FilesFromDisk(nil, map[string]string{
|
||||
webPath: plugName + "/web/plugin/" + plugName,
|
||||
serverPath: plugName + "/server/plugin/" + plugName,
|
||||
})
|
||||
|
||||
// 创建一个zip写入器
|
||||
zipWriter := zip.NewWriter(zipFile)
|
||||
defer zipWriter.Close()
|
||||
// create the output file we'll write to
|
||||
out, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
webHeaderName := filepath.Join(plugName, "web", "plugin", plugName)
|
||||
err = autoCodeService.doZip(zipWriter, webPath, webHeaderName)
|
||||
if err != nil {
|
||||
return
|
||||
// we can use the CompressedArchive type to gzip a tarball
|
||||
// (compression is not required; you could use Tar directly)
|
||||
format := archiver.CompressedArchive{
|
||||
Archival: archiver.Zip{},
|
||||
}
|
||||
serverHeaderName := filepath.Join(plugName, "server", "plugin", plugName)
|
||||
err = autoCodeService.doZip(zipWriter, serverPath, serverHeaderName)
|
||||
|
||||
// create the archive
|
||||
err = format.Archive(context.Background(), out, files)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fileName), nil
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
func fmtField(autoCode *system.AutoCodeStruct) {
|
||||
makeDictTypes(autoCode)
|
||||
autoCode.DataSourceMap = make(map[string]*system.DataSource)
|
||||
for i := range autoCode.Fields {
|
||||
|
||||
zipWriter zip写入器
|
||||
serverPath 存储的路径
|
||||
headerName 写有zip的路径
|
||||
|
||||
*
|
||||
*/
|
||||
func (autoCodeService *AutoCodeService) doZip(zipWriter *zip.Writer, serverPath, headerName string) (err error) {
|
||||
// 遍历serverPath目录并将所有非隐藏文件添加到zip归档中
|
||||
err = filepath.Walk(serverPath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
if autoCode.Fields[i].Front {
|
||||
autoCode.FrontFields = append(autoCode.FrontFields, autoCode.Fields[i])
|
||||
}
|
||||
|
||||
// 跳过隐藏文件和目录
|
||||
if strings.HasPrefix(info.Name(), ".") {
|
||||
return nil
|
||||
if autoCode.Fields[i].FieldType == "time.Time" {
|
||||
autoCode.HasTimer = true
|
||||
if autoCode.Fields[i].FieldSearchType != "" {
|
||||
autoCode.HasSearchTimer = true
|
||||
}
|
||||
}
|
||||
if autoCode.Fields[i].Sort {
|
||||
autoCode.NeedSort = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "picture" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "video" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "richtext" {
|
||||
autoCode.HasRichText = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "pictures" {
|
||||
autoCode.HasPic = true
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "json" {
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "array" {
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "file" {
|
||||
autoCode.HasFile = true
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
|
||||
// 创建一个新的文件头
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return err
|
||||
if autoCode.Fields[i].DataSource != nil &&
|
||||
autoCode.Fields[i].DataSource.Table != "" &&
|
||||
autoCode.Fields[i].DataSource.Label != "" &&
|
||||
autoCode.Fields[i].DataSource.Value != "" {
|
||||
autoCode.HasDataSource = true
|
||||
autoCode.DataSourceMap[autoCode.Fields[i].FieldJson] = autoCode.Fields[i].DataSource
|
||||
autoCode.Fields[i].CheckDataSource = true
|
||||
}
|
||||
|
||||
// 将文件头的名称设置为文件的相对路径
|
||||
rel, _ := filepath.Rel(serverPath, path)
|
||||
header.Name = filepath.Join(headerName, rel)
|
||||
// 目录需要拼上一个 "/" ,否则会出现一个和目录一样的文件在压缩包中
|
||||
if info.IsDir() {
|
||||
header.Name += "/"
|
||||
if autoCode.GvaModel {
|
||||
autoCode.PrimaryField = &system.Field{
|
||||
FieldName: "ID",
|
||||
FieldType: "uint",
|
||||
FieldDesc: "ID",
|
||||
FieldJson: "ID",
|
||||
DataTypeLong: "20",
|
||||
Comment: "主键ID",
|
||||
ColumnName: "id",
|
||||
}
|
||||
}
|
||||
// 将文件添加到zip归档中
|
||||
writer, err := zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
if !autoCode.GvaModel && autoCode.PrimaryField == nil && autoCode.Fields[i].PrimaryKey {
|
||||
autoCode.PrimaryField = autoCode.Fields[i]
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 打开文件并将其内容复制到zip归档中
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = io.Copy(writer, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,74 +46,74 @@ func (a *autoCodePgsql) GetTables(businessDB string, dbName string) (data []resp
|
||||
func (a *autoCodePgsql) GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error) {
|
||||
// todo 数据获取不全, 待完善sql
|
||||
sql := `
|
||||
SELECT
|
||||
psc.COLUMN_NAME AS COLUMN_NAME,
|
||||
psc.udt_name AS data_type,
|
||||
CASE
|
||||
psc.udt_name
|
||||
WHEN 'text' THEN
|
||||
concat_ws ( '', '', psc.CHARACTER_MAXIMUM_LENGTH )
|
||||
WHEN 'varchar' THEN
|
||||
concat_ws ( '', '', psc.CHARACTER_MAXIMUM_LENGTH )
|
||||
WHEN 'smallint' THEN
|
||||
concat_ws ( ',', psc.NUMERIC_PRECISION, psc.NUMERIC_SCALE )
|
||||
WHEN 'decimal' THEN
|
||||
concat_ws ( ',', psc.NUMERIC_PRECISION, psc.NUMERIC_SCALE )
|
||||
WHEN 'integer' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'int4' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'int8' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'bigint' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'timestamp' THEN
|
||||
concat_ws ( '', '', psc.datetime_precision )
|
||||
ELSE ''
|
||||
END AS data_type_long,
|
||||
(
|
||||
SELECT
|
||||
pd.description
|
||||
FROM
|
||||
pg_description pd
|
||||
WHERE
|
||||
(pd.objoid,pd.objsubid) in (
|
||||
SELECT pa.attrelid,pa.attnum
|
||||
FROM
|
||||
pg_attribute pa
|
||||
WHERE pa.attrelid = ( SELECT oid FROM pg_class pc WHERE
|
||||
pc.relname = psc.table_name
|
||||
)
|
||||
and attname = psc.column_name
|
||||
)
|
||||
) AS column_comment,
|
||||
(
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
pg_constraint
|
||||
WHERE
|
||||
contype = 'p'
|
||||
AND conrelid = (
|
||||
SELECT
|
||||
psc.COLUMN_NAME AS COLUMN_NAME,
|
||||
psc.udt_name AS data_type,
|
||||
CASE
|
||||
psc.udt_name
|
||||
WHEN 'text' THEN
|
||||
concat_ws ( '', '', psc.CHARACTER_MAXIMUM_LENGTH )
|
||||
WHEN 'varchar' THEN
|
||||
concat_ws ( '', '', psc.CHARACTER_MAXIMUM_LENGTH )
|
||||
WHEN 'smallint' THEN
|
||||
concat_ws ( ',', psc.NUMERIC_PRECISION, psc.NUMERIC_SCALE )
|
||||
WHEN 'decimal' THEN
|
||||
concat_ws ( ',', psc.NUMERIC_PRECISION, psc.NUMERIC_SCALE )
|
||||
WHEN 'integer' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'int4' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'int8' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'bigint' THEN
|
||||
concat_ws ( '', '', psc.NUMERIC_PRECISION )
|
||||
WHEN 'timestamp' THEN
|
||||
concat_ws ( '', '', psc.datetime_precision )
|
||||
ELSE ''
|
||||
END AS data_type_long,
|
||||
(
|
||||
SELECT
|
||||
oid
|
||||
pd.description
|
||||
FROM
|
||||
pg_class
|
||||
pg_description pd
|
||||
WHERE
|
||||
relname = psc.table_name
|
||||
)
|
||||
AND conkey::int[] @> ARRAY[(
|
||||
(pd.objoid,pd.objsubid) in (
|
||||
SELECT pa.attrelid,pa.attnum
|
||||
FROM
|
||||
pg_attribute pa
|
||||
WHERE pa.attrelid = ( SELECT oid FROM pg_class pc WHERE
|
||||
pc.relname = psc.table_name
|
||||
)
|
||||
and attname = psc.column_name
|
||||
)
|
||||
) AS column_comment,
|
||||
(
|
||||
SELECT
|
||||
attnum
|
||||
COUNT(*)
|
||||
FROM
|
||||
pg_attribute
|
||||
pg_constraint
|
||||
WHERE
|
||||
attrelid = conrelid
|
||||
AND attname = psc.column_name
|
||||
)]
|
||||
) > 0 AS primary_key
|
||||
contype = 'p'
|
||||
AND conrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = psc.table_name
|
||||
)
|
||||
AND conkey::int[] @> ARRAY[(
|
||||
SELECT
|
||||
attnum::integer
|
||||
FROM
|
||||
pg_attribute
|
||||
WHERE
|
||||
attrelid = conrelid
|
||||
AND attname = psc.column_name
|
||||
)]
|
||||
) > 0 AS primary_key
|
||||
FROM
|
||||
INFORMATION_SCHEMA.COLUMNS psc
|
||||
INFORMATION_SCHEMA.COLUMNS psc
|
||||
WHERE
|
||||
table_catalog = ?
|
||||
AND table_schema = 'public'
|
||||
|
||||
@@ -30,7 +30,7 @@ var AutoCodeHistoryServiceApp = new(AutoCodeHistoryService)
|
||||
// RouterPath : RouterPath@RouterString;RouterPath2@RouterString2
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
// Author [songzhibin97](https://github.com/songzhibin97)
|
||||
func (autoCodeHistoryService *AutoCodeHistoryService) CreateAutoCodeHistory(meta, structName, structCNName, autoCodePath string, injectionMeta string, tableName string, apiIds string, Package string, BusinessDB string) error {
|
||||
func (autoCodeHistoryService *AutoCodeHistoryService) CreateAutoCodeHistory(meta, structName, structCNName, autoCodePath string, injectionMeta string, tableName string, apiIds string, Package string, BusinessDB string, menuID uint) error {
|
||||
return global.GVA_DB.Create(&system.SysAutoCodeHistory{
|
||||
Package: Package,
|
||||
RequestMeta: meta,
|
||||
@@ -41,6 +41,7 @@ func (autoCodeHistoryService *AutoCodeHistoryService) CreateAutoCodeHistory(meta
|
||||
TableName: tableName,
|
||||
ApiIDs: apiIds,
|
||||
BusinessDB: BusinessDB,
|
||||
MenuID: menuID,
|
||||
}).Error
|
||||
}
|
||||
|
||||
@@ -81,9 +82,17 @@ func (autoCodeHistoryService *AutoCodeHistoryService) RollBack(info *systemReq.R
|
||||
ids.Ids = append(ids.Ids, id)
|
||||
}
|
||||
err := ApiServiceApp.DeleteApisByIds(ids)
|
||||
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("ClearTag DeleteApiByIds:", zap.Error(err))
|
||||
}
|
||||
|
||||
err = BaseMenuServiceApp.DeleteBaseMenu(int(md.MenuID))
|
||||
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("ClearTag DeleteBaseMenu:", zap.Error(err))
|
||||
}
|
||||
|
||||
// 删除表
|
||||
if info.DeleteTable {
|
||||
if err = AutoCodeServiceApp.DropTable(md.BusinessDB, md.TableName); err != nil {
|
||||
|
||||
@@ -16,29 +16,40 @@ type BaseMenuService struct{}
|
||||
//@param: id float64
|
||||
//@return: err error
|
||||
|
||||
var BaseMenuServiceApp = new(BaseMenuService)
|
||||
|
||||
func (baseMenuService *BaseMenuService) DeleteBaseMenu(id int) (err error) {
|
||||
err = global.GVA_DB.Preload("MenuBtn").Preload("Parameters").Where("parent_id = ?", id).First(&system.SysBaseMenu{}).Error
|
||||
err = global.GVA_DB.First(&system.SysBaseMenu{}, "parent_id = ?", id).Error
|
||||
if err != nil {
|
||||
var menu system.SysBaseMenu
|
||||
db := global.GVA_DB.Preload("SysAuthoritys").Where("id = ?", id).First(&menu).Delete(&menu)
|
||||
err = global.GVA_DB.Delete(&system.SysBaseMenuParameter{}, "sys_base_menu_id = ?", id).Error
|
||||
err = global.GVA_DB.Delete(&system.SysBaseMenuBtn{}, "sys_base_menu_id = ?", id).Error
|
||||
err = global.GVA_DB.Delete(&system.SysAuthorityBtn{}, "sys_menu_id = ?", id).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(menu.SysAuthoritys) > 0 {
|
||||
err = global.GVA_DB.Model(&menu).Association("SysAuthoritys").Delete(&menu.SysAuthoritys)
|
||||
} else {
|
||||
err = db.Error
|
||||
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
err = tx.Delete(&system.SysBaseMenu{}, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return errors.New("此菜单存在子菜单不可删除")
|
||||
|
||||
err = tx.Delete(&system.SysBaseMenuParameter{}, "sys_base_menu_id = ?", id).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Delete(&system.SysBaseMenuBtn{}, "sys_base_menu_id = ?", id).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.Delete(&system.SysAuthorityBtn{}, "sys_menu_id = ?", id).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Delete(&system.SysAuthorityMenu{}, "sys_base_menu_id = ?", id).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
return err
|
||||
return errors.New("此菜单存在子菜单不可删除")
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
@@ -64,7 +75,7 @@ func (baseMenuService *BaseMenuService) UpdateBaseMenu(menu system.SysBaseMenu)
|
||||
upDateMap["sort"] = menu.Sort
|
||||
|
||||
err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
db := tx.Where("id = ?", menu.ID).Find(&oldMenu)
|
||||
tx.Where("id = ?", menu.ID).Find(&oldMenu)
|
||||
if oldMenu.Name != menu.Name {
|
||||
if !errors.Is(tx.Where("id <> ? AND name = ?", menu.ID, menu.Name).First(&system.SysBaseMenu{}).Error, gorm.ErrRecordNotFound) {
|
||||
global.GVA_LOG.Debug("存在相同name修改失败")
|
||||
@@ -103,7 +114,7 @@ func (baseMenuService *BaseMenuService) UpdateBaseMenu(menu system.SysBaseMenu)
|
||||
}
|
||||
}
|
||||
|
||||
txErr = db.Updates(upDateMap).Error
|
||||
txErr = tx.Model(&oldMenu).Updates(upDateMap).Error
|
||||
if txErr != nil {
|
||||
global.GVA_LOG.Debug(txErr.Error())
|
||||
return txErr
|
||||
|
||||
@@ -63,13 +63,17 @@ func (dictionaryService *DictionaryService) UpdateSysDictionary(sysDictionary *s
|
||||
"Status": sysDictionary.Status,
|
||||
"Desc": sysDictionary.Desc,
|
||||
}
|
||||
db := global.GVA_DB.Where("id = ?", sysDictionary.ID).First(&dict)
|
||||
err = global.GVA_DB.Where("id = ?", sysDictionary.ID).First(&dict).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Debug(err.Error())
|
||||
return errors.New("查询字典数据失败")
|
||||
}
|
||||
if dict.Type != sysDictionary.Type {
|
||||
if !errors.Is(global.GVA_DB.First(&system.SysDictionary{}, "type = ?", sysDictionary.Type).Error, gorm.ErrRecordNotFound) {
|
||||
return errors.New("存在相同的type,不允许创建")
|
||||
}
|
||||
}
|
||||
err = db.Updates(sysDictionaryMap).Error
|
||||
err = global.GVA_DB.Model(&dict).Updates(sysDictionaryMap).Error
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ func (dictionaryDetailService *DictionaryDetailService) GetSysDictionaryDetailIn
|
||||
if info.Label != "" {
|
||||
db = db.Where("label LIKE ?", "%"+info.Label+"%")
|
||||
}
|
||||
if info.Value != 0 {
|
||||
if info.Value != "" {
|
||||
db = db.Where("value = ?", info.Value)
|
||||
}
|
||||
if info.Status != nil {
|
||||
@@ -101,14 +101,14 @@ func (dictionaryDetailService *DictionaryDetailService) GetDictionaryListByType(
|
||||
}
|
||||
|
||||
// 按照字典id+字典内容value获取单条字典内容
|
||||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryInfoByValue(dictionaryID uint, value uint) (detail system.SysDictionaryDetail, err error) {
|
||||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryInfoByValue(dictionaryID uint, value string) (detail system.SysDictionaryDetail, err error) {
|
||||
var sysDictionaryDetail system.SysDictionaryDetail
|
||||
err = global.GVA_DB.First(&sysDictionaryDetail, "sys_dictionary_id = ? and value = ?", dictionaryID, value).Error
|
||||
return sysDictionaryDetail, err
|
||||
}
|
||||
|
||||
// 按照字典type+字典内容value获取单条字典内容
|
||||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryInfoByTypeValue(t string, value uint) (detail system.SysDictionaryDetail, err error) {
|
||||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryInfoByTypeValue(t string, value string) (detail system.SysDictionaryDetail, err error) {
|
||||
var sysDictionaryDetails system.SysDictionaryDetail
|
||||
db := global.GVA_DB.Model(&system.SysDictionaryDetail{}).Joins("JOIN sys_dictionaries ON sys_dictionaries.id = sys_dictionary_details.sys_dictionary_id")
|
||||
err = db.First(&sysDictionaryDetails, "sys_dictionaries.type = ? and sys_dictionary_details.value = ?", t, value).Error
|
||||
|
||||
@@ -8,10 +8,14 @@ import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/utils"
|
||||
"github.com/xuri/excelize/v2"
|
||||
"gorm.io/gorm"
|
||||
"mime/multipart"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysExportTemplateService struct {
|
||||
@@ -41,14 +45,45 @@ func (sysExportTemplateService *SysExportTemplateService) DeleteSysExportTemplat
|
||||
// UpdateSysExportTemplate 更新导出模板记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func (sysExportTemplateService *SysExportTemplateService) UpdateSysExportTemplate(sysExportTemplate system.SysExportTemplate) (err error) {
|
||||
err = global.GVA_DB.Save(&sysExportTemplate).Error
|
||||
return err
|
||||
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
conditions := sysExportTemplate.Conditions
|
||||
e := tx.Delete(&[]system.Condition{}, "template_id = ?", sysExportTemplate.TemplateID).Error
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
sysExportTemplate.Conditions = nil
|
||||
|
||||
joins := sysExportTemplate.JoinTemplate
|
||||
e = tx.Delete(&[]system.JoinTemplate{}, "template_id = ?", sysExportTemplate.TemplateID).Error
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
sysExportTemplate.JoinTemplate = nil
|
||||
|
||||
e = tx.Updates(&sysExportTemplate).Error
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
if len(conditions) > 0 {
|
||||
for i := range conditions {
|
||||
conditions[i].ID = 0
|
||||
}
|
||||
e = tx.Create(&conditions).Error
|
||||
}
|
||||
if len(joins) > 0 {
|
||||
for i := range joins {
|
||||
joins[i].ID = 0
|
||||
}
|
||||
e = tx.Create(&joins).Error
|
||||
}
|
||||
return e
|
||||
})
|
||||
}
|
||||
|
||||
// GetSysExportTemplate 根据id获取导出模板记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func (sysExportTemplateService *SysExportTemplateService) GetSysExportTemplate(id uint) (sysExportTemplate system.SysExportTemplate, err error) {
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&sysExportTemplate).Error
|
||||
err = global.GVA_DB.Where("id = ?", id).Preload("JoinTemplate").Preload("Conditions").First(&sysExportTemplate).Error
|
||||
return
|
||||
}
|
||||
|
||||
@@ -88,9 +123,9 @@ func (sysExportTemplateService *SysExportTemplateService) GetSysExportTemplateIn
|
||||
|
||||
// ExportExcel 导出Excel
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID string) (file *bytes.Buffer, name string, err error) {
|
||||
func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID string, values url.Values) (file *bytes.Buffer, name string, err error) {
|
||||
var template system.SysExportTemplate
|
||||
err = global.GVA_DB.First(&template, "template_id = ?", templateID).Error
|
||||
err = global.GVA_DB.Preload("Conditions").Preload("JoinTemplate").First(&template, "template_id = ?", templateID).Error
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -107,19 +142,78 @@ func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID
|
||||
return
|
||||
}
|
||||
var templateInfoMap = make(map[string]string)
|
||||
columns, err := utils.GetJSONKeys(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
err = json.Unmarshal([]byte(template.TemplateInfo), &templateInfoMap)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
var columns []string
|
||||
var tableTitle []string
|
||||
for key := range templateInfoMap {
|
||||
columns = append(columns, key)
|
||||
for _, key := range columns {
|
||||
tableTitle = append(tableTitle, templateInfoMap[key])
|
||||
}
|
||||
selects := strings.Join(columns, ", ")
|
||||
var tableMap []map[string]interface{}
|
||||
err = global.GVA_DB.Select(selects).Table(template.TableName).Find(&tableMap).Error
|
||||
db := global.GVA_DB
|
||||
if template.DBName != "" {
|
||||
db = global.MustGetGlobalDBByDBName(template.DBName)
|
||||
}
|
||||
|
||||
if len(template.JoinTemplate) > 0 {
|
||||
for _, join := range template.JoinTemplate {
|
||||
db = db.Joins(join.JOINS + "`" + join.Table + "`" + " ON " + join.ON)
|
||||
}
|
||||
}
|
||||
|
||||
db = db.Select(selects).Table(template.TableName)
|
||||
|
||||
if len(template.Conditions) > 0 {
|
||||
for _, condition := range template.Conditions {
|
||||
sql := fmt.Sprintf("%s %s ?", condition.Column, condition.Operator)
|
||||
value := values.Get(condition.From)
|
||||
if value != "" {
|
||||
if condition.Operator == "LIKE" {
|
||||
value = "%" + value + "%"
|
||||
}
|
||||
db = db.Where(sql, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 通过参数传入limit
|
||||
limit := values.Get("limit")
|
||||
if limit != "" {
|
||||
l, e := strconv.Atoi(limit)
|
||||
if e == nil {
|
||||
db = db.Limit(l)
|
||||
}
|
||||
}
|
||||
// 模板的默认limit
|
||||
if limit == "" && template.Limit != 0 {
|
||||
db = db.Limit(template.Limit)
|
||||
}
|
||||
|
||||
// 通过参数传入offset
|
||||
offset := values.Get("offset")
|
||||
if offset != "" {
|
||||
o, e := strconv.Atoi(offset)
|
||||
if e == nil {
|
||||
db = db.Offset(o)
|
||||
}
|
||||
}
|
||||
|
||||
// 通过参数传入order
|
||||
order := values.Get("order")
|
||||
if order != "" {
|
||||
db = db.Order(order)
|
||||
}
|
||||
// 模板的默认order
|
||||
if order == "" && template.Order != "" {
|
||||
db = db.Order(template.Order)
|
||||
}
|
||||
|
||||
err = db.Debug().Find(&tableMap).Error
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -128,6 +222,12 @@ func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID
|
||||
for _, table := range tableMap {
|
||||
var row []string
|
||||
for _, column := range columns {
|
||||
if len(template.JoinTemplate) > 0 {
|
||||
columnArr := strings.Split(column, ".")
|
||||
if len(columnArr) > 1 {
|
||||
column = strings.Split(column, ".")[1]
|
||||
}
|
||||
}
|
||||
row = append(row, fmt.Sprintf("%v", table[column]))
|
||||
}
|
||||
rows = append(rows, row)
|
||||
@@ -170,14 +270,18 @@ func (sysExportTemplateService *SysExportTemplateService) ExportTemplate(templat
|
||||
return
|
||||
}
|
||||
var templateInfoMap = make(map[string]string)
|
||||
|
||||
columns, err := utils.GetJSONKeys(template.TemplateInfo)
|
||||
|
||||
err = json.Unmarshal([]byte(template.TemplateInfo), &templateInfoMap)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
var tableTitle []string
|
||||
for key := range templateInfoMap {
|
||||
for _, key := range columns {
|
||||
tableTitle = append(tableTitle, templateInfoMap[key])
|
||||
}
|
||||
|
||||
for i := range tableTitle {
|
||||
fErr := f.SetCellValue("Sheet1", fmt.Sprintf("%s%d", getColumnName(i+1), 1), tableTitle[i])
|
||||
if fErr != nil {
|
||||
@@ -228,21 +332,37 @@ func (sysExportTemplateService *SysExportTemplateService) ImportExcel(templateID
|
||||
for key, title := range templateInfoMap {
|
||||
titleKeyMap[title] = key
|
||||
}
|
||||
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
db := global.GVA_DB
|
||||
if template.DBName != "" {
|
||||
db = global.MustGetGlobalDBByDBName(template.DBName)
|
||||
}
|
||||
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
excelTitle := rows[0]
|
||||
values := rows[1:]
|
||||
items := make([]map[string]interface{}, 0, len(values))
|
||||
for _, row := range values {
|
||||
var item = make(map[string]interface{})
|
||||
for ii, value := range row {
|
||||
key := titleKeyMap[excelTitle[ii]]
|
||||
item[key] = value
|
||||
}
|
||||
cErr := tx.Table(template.TableName).Create(&item).Error
|
||||
if cErr != nil {
|
||||
return cErr
|
||||
|
||||
needCreated := tx.Migrator().HasColumn(template.TableName, "created_at")
|
||||
needUpdated := tx.Migrator().HasColumn(template.TableName, "updated_at")
|
||||
|
||||
if item["created_at"] == nil && needCreated {
|
||||
item["created_at"] = time.Now()
|
||||
}
|
||||
if item["updated_at"] == nil && needUpdated {
|
||||
item["updated_at"] = time.Now()
|
||||
}
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
return nil
|
||||
cErr := tx.Table(template.TableName).CreateInBatches(&items, 1000).Error
|
||||
return cErr
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ type InitDBService struct{}
|
||||
// InitDB 创建数据库并初始化 总入口
|
||||
func (initDBService *InitDBService) InitDB(conf request.InitDB) (err error) {
|
||||
ctx := context.TODO()
|
||||
ctx = context.WithValue(ctx, "adminPassword", conf.AdminPassword)
|
||||
if len(initializers) == 0 {
|
||||
return errors.New("无可用初始化过程,请检查初始化是否已执行完成")
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
|
||||
@@ -20,11 +19,11 @@ type MenuService struct{}
|
||||
|
||||
var MenuServiceApp = new(MenuService)
|
||||
|
||||
func (menuService *MenuService) getMenuTreeMap(authorityId uint) (treeMap map[string][]system.SysMenu, err error) {
|
||||
func (menuService *MenuService) getMenuTreeMap(authorityId uint) (treeMap map[uint][]system.SysMenu, err error) {
|
||||
var allMenus []system.SysMenu
|
||||
var baseMenu []system.SysBaseMenu
|
||||
var btns []system.SysAuthorityBtn
|
||||
treeMap = make(map[string][]system.SysMenu)
|
||||
treeMap = make(map[uint][]system.SysMenu)
|
||||
|
||||
var SysAuthorityMenus []system.SysAuthorityMenu
|
||||
err = global.GVA_DB.Where("sys_authority_authority_id = ?", authorityId).Find(&SysAuthorityMenus).Error
|
||||
@@ -47,7 +46,7 @@ func (menuService *MenuService) getMenuTreeMap(authorityId uint) (treeMap map[st
|
||||
allMenus = append(allMenus, system.SysMenu{
|
||||
SysBaseMenu: baseMenu[i],
|
||||
AuthorityId: authorityId,
|
||||
MenuId: strconv.Itoa(int(baseMenu[i].ID)),
|
||||
MenuId: baseMenu[i].ID,
|
||||
Parameters: baseMenu[i].Parameters,
|
||||
})
|
||||
}
|
||||
@@ -78,7 +77,7 @@ func (menuService *MenuService) getMenuTreeMap(authorityId uint) (treeMap map[st
|
||||
|
||||
func (menuService *MenuService) GetMenuTree(authorityId uint) (menus []system.SysMenu, err error) {
|
||||
menuTree, err := menuService.getMenuTreeMap(authorityId)
|
||||
menus = menuTree["0"]
|
||||
menus = menuTree[0]
|
||||
for i := 0; i < len(menus); i++ {
|
||||
err = menuService.getChildrenList(&menus[i], menuTree)
|
||||
}
|
||||
@@ -91,7 +90,7 @@ func (menuService *MenuService) GetMenuTree(authorityId uint) (menus []system.Sy
|
||||
//@param: menu *model.SysMenu, treeMap map[string][]model.SysMenu
|
||||
//@return: err error
|
||||
|
||||
func (menuService *MenuService) getChildrenList(menu *system.SysMenu, treeMap map[string][]system.SysMenu) (err error) {
|
||||
func (menuService *MenuService) getChildrenList(menu *system.SysMenu, treeMap map[uint][]system.SysMenu) (err error) {
|
||||
menu.Children = treeMap[menu.MenuId]
|
||||
for i := 0; i < len(menu.Children); i++ {
|
||||
err = menuService.getChildrenList(&menu.Children[i], treeMap)
|
||||
@@ -107,7 +106,7 @@ func (menuService *MenuService) getChildrenList(menu *system.SysMenu, treeMap ma
|
||||
func (menuService *MenuService) GetInfoList() (list interface{}, total int64, err error) {
|
||||
var menuList []system.SysBaseMenu
|
||||
treeMap, err := menuService.getBaseMenuTreeMap()
|
||||
menuList = treeMap["0"]
|
||||
menuList = treeMap[0]
|
||||
for i := 0; i < len(menuList); i++ {
|
||||
err = menuService.getBaseChildrenList(&menuList[i], treeMap)
|
||||
}
|
||||
@@ -120,8 +119,8 @@ func (menuService *MenuService) GetInfoList() (list interface{}, total int64, er
|
||||
//@param: menu *model.SysBaseMenu, treeMap map[string][]model.SysBaseMenu
|
||||
//@return: err error
|
||||
|
||||
func (menuService *MenuService) getBaseChildrenList(menu *system.SysBaseMenu, treeMap map[string][]system.SysBaseMenu) (err error) {
|
||||
menu.Children = treeMap[strconv.Itoa(int(menu.ID))]
|
||||
func (menuService *MenuService) getBaseChildrenList(menu *system.SysBaseMenu, treeMap map[uint][]system.SysBaseMenu) (err error) {
|
||||
menu.Children = treeMap[menu.ID]
|
||||
for i := 0; i < len(menu.Children); i++ {
|
||||
err = menuService.getBaseChildrenList(&menu.Children[i], treeMap)
|
||||
}
|
||||
@@ -146,9 +145,9 @@ func (menuService *MenuService) AddBaseMenu(menu system.SysBaseMenu) error {
|
||||
//@description: 获取路由总树map
|
||||
//@return: treeMap map[string][]system.SysBaseMenu, err error
|
||||
|
||||
func (menuService *MenuService) getBaseMenuTreeMap() (treeMap map[string][]system.SysBaseMenu, err error) {
|
||||
func (menuService *MenuService) getBaseMenuTreeMap() (treeMap map[uint][]system.SysBaseMenu, err error) {
|
||||
var allMenus []system.SysBaseMenu
|
||||
treeMap = make(map[string][]system.SysBaseMenu)
|
||||
treeMap = make(map[uint][]system.SysBaseMenu)
|
||||
err = global.GVA_DB.Order("sort").Preload("MenuBtn").Preload("Parameters").Find(&allMenus).Error
|
||||
for _, v := range allMenus {
|
||||
treeMap[v.ParentId] = append(treeMap[v.ParentId], v)
|
||||
@@ -163,7 +162,7 @@ func (menuService *MenuService) getBaseMenuTreeMap() (treeMap map[string][]syste
|
||||
|
||||
func (menuService *MenuService) GetBaseMenuTree() (menus []system.SysBaseMenu, err error) {
|
||||
treeMap, err := menuService.getBaseMenuTreeMap()
|
||||
menus = treeMap["0"]
|
||||
menus = treeMap[0]
|
||||
for i := 0; i < len(menus); i++ {
|
||||
err = menuService.getBaseChildrenList(&menus[i], treeMap)
|
||||
}
|
||||
@@ -210,7 +209,7 @@ func (menuService *MenuService) GetMenuAuthority(info *request.GetAuthorityId) (
|
||||
menus = append(menus, system.SysMenu{
|
||||
SysBaseMenu: baseMenu[i],
|
||||
AuthorityId: info.AuthorityId,
|
||||
MenuId: strconv.Itoa(int(baseMenu[i].ID)),
|
||||
MenuId: baseMenu[i].ID,
|
||||
Parameters: baseMenu[i].Parameters,
|
||||
})
|
||||
}
|
||||
@@ -218,6 +217,7 @@ func (menuService *MenuService) GetMenuAuthority(info *request.GetAuthorityId) (
|
||||
}
|
||||
|
||||
// UserAuthorityDefaultRouter 用户角色默认路由检查
|
||||
//
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (menuService *MenuService) UserAuthorityDefaultRouter(user *system.SysUser) {
|
||||
var menuIds []string
|
||||
|
||||
@@ -106,7 +106,7 @@ func (userService *UserService) SetUserAuthority(id uint, authorityId uint) (err
|
||||
if errors.Is(assignErr, gorm.ErrRecordNotFound) {
|
||||
return errors.New("该用户无此角色")
|
||||
}
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&system.SysUser{}).Update("authority_id", authorityId).Error
|
||||
err = global.GVA_DB.Model(&system.SysUser{}).Where("id = ?", id).Update("authority_id", authorityId).Error
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -118,7 +118,13 @@ func (userService *UserService) SetUserAuthority(id uint, authorityId uint) (err
|
||||
|
||||
func (userService *UserService) SetUserAuthorities(id uint, authorityIds []uint) (err error) {
|
||||
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
TxErr := tx.Delete(&[]system.SysUserAuthority{}, "sys_user_id = ?", id).Error
|
||||
var user system.SysUser
|
||||
TxErr := tx.Where("id = ?", id).First(&user).Error
|
||||
if TxErr != nil {
|
||||
global.GVA_LOG.Debug(TxErr.Error())
|
||||
return errors.New("查询用户数据失败")
|
||||
}
|
||||
TxErr = tx.Delete(&[]system.SysUserAuthority{}, "sys_user_id = ?", id).Error
|
||||
if TxErr != nil {
|
||||
return TxErr
|
||||
}
|
||||
@@ -132,7 +138,7 @@ func (userService *UserService) SetUserAuthorities(id uint, authorityIds []uint)
|
||||
if TxErr != nil {
|
||||
return TxErr
|
||||
}
|
||||
TxErr = tx.Where("id = ?", id).First(&system.SysUser{}).Update("authority_id", authorityIds[0]).Error
|
||||
TxErr = tx.Model(&user).Update("authority_id", authorityIds[0]).Error
|
||||
if TxErr != nil {
|
||||
return TxErr
|
||||
}
|
||||
|
||||
@@ -50,53 +50,53 @@ func (i *initDictDetail) InitializeData(ctx context.Context) (context.Context, e
|
||||
}
|
||||
True := true
|
||||
dicts[0].SysDictionaryDetails = []sysModel.SysDictionaryDetail{
|
||||
{Label: "男", Value: 1, Status: &True, Sort: 1},
|
||||
{Label: "女", Value: 2, Status: &True, Sort: 2},
|
||||
{Label: "男", Value: "1", Status: &True, Sort: 1},
|
||||
{Label: "女", Value: "2", Status: &True, Sort: 2},
|
||||
}
|
||||
|
||||
dicts[1].SysDictionaryDetails = []sysModel.SysDictionaryDetail{
|
||||
{Label: "smallint", Value: 1, Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "mediumint", Value: 2, Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "int", Value: 3, Status: &True, Extend: "mysql", Sort: 3},
|
||||
{Label: "bigint", Value: 4, Status: &True, Extend: "mysql", Sort: 4},
|
||||
{Label: "int2", Value: 5, Status: &True, Extend: "pgsql", Sort: 5},
|
||||
{Label: "int4", Value: 6, Status: &True, Extend: "pgsql", Sort: 6},
|
||||
{Label: "int6", Value: 7, Status: &True, Extend: "pgsql", Sort: 7},
|
||||
{Label: "int8", Value: 8, Status: &True, Extend: "pgsql", Sort: 8},
|
||||
{Label: "smallint", Value: "1", Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "mediumint", Value: "2", Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "int", Value: "3", Status: &True, Extend: "mysql", Sort: 3},
|
||||
{Label: "bigint", Value: "4", Status: &True, Extend: "mysql", Sort: 4},
|
||||
{Label: "int2", Value: "5", Status: &True, Extend: "pgsql", Sort: 5},
|
||||
{Label: "int4", Value: "6", Status: &True, Extend: "pgsql", Sort: 6},
|
||||
{Label: "int6", Value: "7", Status: &True, Extend: "pgsql", Sort: 7},
|
||||
{Label: "int8", Value: "8", Status: &True, Extend: "pgsql", Sort: 8},
|
||||
}
|
||||
|
||||
dicts[2].SysDictionaryDetails = []sysModel.SysDictionaryDetail{
|
||||
{Label: "date", Status: &True},
|
||||
{Label: "time", Value: 1, Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "year", Value: 2, Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "datetime", Value: 3, Status: &True, Extend: "mysql", Sort: 3},
|
||||
{Label: "timestamp", Value: 5, Status: &True, Extend: "mysql", Sort: 5},
|
||||
{Label: "timestamptz", Value: 6, Status: &True, Extend: "pgsql", Sort: 5},
|
||||
{Label: "time", Value: "1", Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "year", Value: "2", Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "datetime", Value: "3", Status: &True, Extend: "mysql", Sort: 3},
|
||||
{Label: "timestamp", Value: "5", Status: &True, Extend: "mysql", Sort: 5},
|
||||
{Label: "timestamptz", Value: "6", Status: &True, Extend: "pgsql", Sort: 5},
|
||||
}
|
||||
dicts[3].SysDictionaryDetails = []sysModel.SysDictionaryDetail{
|
||||
{Label: "float", Status: &True},
|
||||
{Label: "double", Value: 1, Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "decimal", Value: 2, Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "numeric", Value: 3, Status: &True, Extend: "pgsql", Sort: 3},
|
||||
{Label: "smallserial", Value: 4, Status: &True, Extend: "pgsql", Sort: 4},
|
||||
{Label: "double", Value: "1", Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "decimal", Value: "2", Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "numeric", Value: "3", Status: &True, Extend: "pgsql", Sort: 3},
|
||||
{Label: "smallserial", Value: "4", Status: &True, Extend: "pgsql", Sort: 4},
|
||||
}
|
||||
|
||||
dicts[4].SysDictionaryDetails = []sysModel.SysDictionaryDetail{
|
||||
{Label: "char", Status: &True},
|
||||
{Label: "varchar", Value: 1, Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "tinyblob", Value: 2, Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "tinytext", Value: 3, Status: &True, Extend: "mysql", Sort: 3},
|
||||
{Label: "text", Value: 4, Status: &True, Extend: "mysql", Sort: 4},
|
||||
{Label: "blob", Value: 5, Status: &True, Extend: "mysql", Sort: 5},
|
||||
{Label: "mediumblob", Value: 6, Status: &True, Extend: "mysql", Sort: 6},
|
||||
{Label: "mediumtext", Value: 7, Status: &True, Extend: "mysql", Sort: 7},
|
||||
{Label: "longblob", Value: 8, Status: &True, Extend: "mysql", Sort: 8},
|
||||
{Label: "longtext", Value: 9, Status: &True, Extend: "mysql", Sort: 9},
|
||||
{Label: "varchar", Value: "1", Status: &True, Extend: "mysql", Sort: 1},
|
||||
{Label: "tinyblob", Value: "2", Status: &True, Extend: "mysql", Sort: 2},
|
||||
{Label: "tinytext", Value: "3", Status: &True, Extend: "mysql", Sort: 3},
|
||||
{Label: "text", Value: "4", Status: &True, Extend: "mysql", Sort: 4},
|
||||
{Label: "blob", Value: "5", Status: &True, Extend: "mysql", Sort: 5},
|
||||
{Label: "mediumblob", Value: "6", Status: &True, Extend: "mysql", Sort: 6},
|
||||
{Label: "mediumtext", Value: "7", Status: &True, Extend: "mysql", Sort: 7},
|
||||
{Label: "longblob", Value: "8", Status: &True, Extend: "mysql", Sort: 8},
|
||||
{Label: "longtext", Value: "9", Status: &True, Extend: "mysql", Sort: 9},
|
||||
}
|
||||
|
||||
dicts[5].SysDictionaryDetails = []sysModel.SysDictionaryDetail{
|
||||
{Label: "tinyint", Value: 1, Extend: "mysql", Status: &True},
|
||||
{Label: "bool", Value: 2, Extend: "pgsql", Status: &True},
|
||||
{Label: "tinyint", Value: "1", Extend: "mysql", Status: &True},
|
||||
{Label: "bool", Value: "2", Extend: "pgsql", Status: &True},
|
||||
}
|
||||
for _, dict := range dicts {
|
||||
if err := db.Model(&dict).Association("SysDictionaryDetails").
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
sysModel "github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/service/system"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type initExcelTemplate struct{}
|
||||
|
||||
const initOrderExcelTemplate = initOrderDictDetail + 1
|
||||
|
||||
// auto run
|
||||
func init() {
|
||||
system.RegisterInit(initOrderExcelTemplate, &initExcelTemplate{})
|
||||
}
|
||||
|
||||
func (i initExcelTemplate) InitializerName() string {
|
||||
return "sys_export_templates"
|
||||
}
|
||||
|
||||
func (i *initExcelTemplate) MigrateTable(ctx context.Context) (context.Context, error) {
|
||||
db, ok := ctx.Value("db").(*gorm.DB)
|
||||
if !ok {
|
||||
return ctx, system.ErrMissingDBContext
|
||||
}
|
||||
return ctx, db.AutoMigrate(&sysModel.SysExportTemplate{})
|
||||
}
|
||||
|
||||
func (i *initExcelTemplate) TableCreated(ctx context.Context) bool {
|
||||
db, ok := ctx.Value("db").(*gorm.DB)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return db.Migrator().HasTable(&sysModel.SysExportTemplate{})
|
||||
}
|
||||
|
||||
func (i *initExcelTemplate) InitializeData(ctx context.Context) (context.Context, error) {
|
||||
db, ok := ctx.Value("db").(*gorm.DB)
|
||||
if !ok {
|
||||
return ctx, system.ErrMissingDBContext
|
||||
}
|
||||
|
||||
entities := []sysModel.SysExportTemplate{
|
||||
{
|
||||
Name: "api",
|
||||
TableName: "sys_apis",
|
||||
TemplateID: "api",
|
||||
TemplateInfo: `{
|
||||
"path":"路径",
|
||||
"method":"方法(大写)",
|
||||
"description":"方法介绍",
|
||||
"api_group":"方法分组"
|
||||
}`,
|
||||
},
|
||||
}
|
||||
if err := db.Create(&entities).Error; err != nil {
|
||||
return ctx, errors.Wrap(err, "sys_export_templates"+"表数据初始化失败!")
|
||||
}
|
||||
next := context.WithValue(ctx, i.InitializerName(), entities)
|
||||
return next, nil
|
||||
}
|
||||
|
||||
func (i *initExcelTemplate) DataInserted(ctx context.Context) bool {
|
||||
db, ok := ctx.Value("db").(*gorm.DB)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if errors.Is(db.First(&sysModel.SysExportTemplate{}).Error, gorm.ErrRecordNotFound) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/service/system"
|
||||
"github.com/pkg/errors"
|
||||
@@ -50,36 +51,36 @@ func (i *initMenu) InitializeData(ctx context.Context) (next context.Context, er
|
||||
return ctx, system.ErrMissingDBContext
|
||||
}
|
||||
entities := []SysBaseMenu{
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "dashboard", Name: "dashboard", Component: "view/dashboard/index.vue", Sort: 1, Meta: Meta{Title: "仪表盘", Icon: "odometer"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "about", Name: "about", Component: "view/about/index.vue", Sort: 9, Meta: Meta{Title: "关于我们", Icon: "info-filled"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "admin", Name: "superAdmin", Component: "view/superAdmin/index.vue", Sort: 3, Meta: Meta{Title: "超级管理员", Icon: "user"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "authority", Name: "authority", Component: "view/superAdmin/authority/authority.vue", Sort: 1, Meta: Meta{Title: "角色管理", Icon: "avatar"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "menu", Name: "menu", Component: "view/superAdmin/menu/menu.vue", Sort: 2, Meta: Meta{Title: "菜单管理", Icon: "tickets", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "api", Name: "api", Component: "view/superAdmin/api/api.vue", Sort: 3, Meta: Meta{Title: "api管理", Icon: "platform", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "user", Name: "user", Component: "view/superAdmin/user/user.vue", Sort: 4, Meta: Meta{Title: "用户管理", Icon: "coordinate"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "dictionary", Name: "dictionary", Component: "view/superAdmin/dictionary/sysDictionary.vue", Sort: 5, Meta: Meta{Title: "字典管理", Icon: "notebook"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "3", Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: Meta{Title: "操作历史", Icon: "pie-chart"}},
|
||||
{MenuLevel: 0, Hidden: true, ParentId: "0", Path: "person", Name: "person", Component: "view/person/person.vue", Sort: 4, Meta: Meta{Title: "个人信息", Icon: "message"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "example", Name: "example", Component: "view/example/index.vue", Sort: 7, Meta: Meta{Title: "示例文件", Icon: "management"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "11", Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: Meta{Title: "媒体库(上传下载)", Icon: "upload"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "11", Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: Meta{Title: "断点续传", Icon: "upload-filled"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "11", Path: "customer", Name: "customer", Component: "view/example/customer/customer.vue", Sort: 7, Meta: Meta{Title: "客户列表(资源示例)", Icon: "avatar"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "systemTools", Name: "systemTools", Component: "view/systemTools/index.vue", Sort: 5, Meta: Meta{Title: "系统工具", Icon: "tools"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "15", Path: "autoCode", Name: "autoCode", Component: "view/systemTools/autoCode/index.vue", Sort: 1, Meta: Meta{Title: "代码生成器", Icon: "cpu", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "15", Path: "formCreate", Name: "formCreate", Component: "view/systemTools/formCreate/index.vue", Sort: 2, Meta: Meta{Title: "表单生成器", Icon: "magic-stick", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "15", Path: "system", Name: "system", Component: "view/systemTools/system/system.vue", Sort: 3, Meta: Meta{Title: "系统配置", Icon: "operation"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "15", Path: "autoCodeAdmin", Name: "autoCodeAdmin", Component: "view/systemTools/autoCodeAdmin/index.vue", Sort: 1, Meta: Meta{Title: "自动化代码管理", Icon: "magic-stick"}},
|
||||
{MenuLevel: 0, Hidden: true, ParentId: "15", Path: "autoCodeEdit/:id", Name: "autoCodeEdit", Component: "view/systemTools/autoCode/index.vue", Sort: 0, Meta: Meta{Title: "自动化代码-${id}", Icon: "magic-stick"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "15", Path: "autoPkg", Name: "autoPkg", Component: "view/systemTools/autoPkg/autoPkg.vue", Sort: 0, Meta: Meta{Title: "自动化package", Icon: "folder"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Component: "/", Sort: 0, Meta: Meta{Title: "官方网站", Icon: "customer-gva"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "state", Name: "state", Component: "view/system/state.vue", Sort: 8, Meta: Meta{Title: "服务器状态", Icon: "cloudy"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "0", Path: "plugin", Name: "plugin", Component: "view/routerHolder.vue", Sort: 6, Meta: Meta{Title: "插件系统", Icon: "cherry"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "24", Path: "https://plugin.gin-vue-admin.com/", Name: "https://plugin.gin-vue-admin.com/", Component: "https://plugin.gin-vue-admin.com/", Sort: 0, Meta: Meta{Title: "插件市场", Icon: "shop"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "24", Path: "installPlugin", Name: "installPlugin", Component: "view/systemTools/installPlugin/index.vue", Sort: 1, Meta: Meta{Title: "插件安装", Icon: "box"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "24", Path: "autoPlug", Name: "autoPlug", Component: "view/systemTools/autoPlug/autoPlug.vue", Sort: 2, Meta: Meta{Title: "插件模板", Icon: "folder"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "24", Path: "pubPlug", Name: "pubPlug", Component: "view/systemTools/pubPlug/pubPlug.vue", Sort: 3, Meta: Meta{Title: "打包插件", Icon: "files"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "24", Path: "plugin-email", Name: "plugin-email", Component: "plugin/email/view/index.vue", Sort: 4, Meta: Meta{Title: "邮件插件", Icon: "message"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: "15", Path: "exportTemplate", Name: "exportTemplate", Component: "view/systemTools/exportTemplate/exportTemplate.vue", Sort: 10, Meta: Meta{Title: "表格模板", Icon: "reading"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "dashboard", Name: "dashboard", Component: "view/dashboard/index.vue", Sort: 1, Meta: Meta{Title: "仪表盘", Icon: "odometer"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "about", Name: "about", Component: "view/about/index.vue", Sort: 9, Meta: Meta{Title: "关于我们", Icon: "info-filled"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "admin", Name: "superAdmin", Component: "view/superAdmin/index.vue", Sort: 3, Meta: Meta{Title: "超级管理员", Icon: "user"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "authority", Name: "authority", Component: "view/superAdmin/authority/authority.vue", Sort: 1, Meta: Meta{Title: "角色管理", Icon: "avatar"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "menu", Name: "menu", Component: "view/superAdmin/menu/menu.vue", Sort: 2, Meta: Meta{Title: "菜单管理", Icon: "tickets", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "api", Name: "api", Component: "view/superAdmin/api/api.vue", Sort: 3, Meta: Meta{Title: "api管理", Icon: "platform", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "user", Name: "user", Component: "view/superAdmin/user/user.vue", Sort: 4, Meta: Meta{Title: "用户管理", Icon: "coordinate"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "dictionary", Name: "dictionary", Component: "view/superAdmin/dictionary/sysDictionary.vue", Sort: 5, Meta: Meta{Title: "字典管理", Icon: "notebook"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: Meta{Title: "操作历史", Icon: "pie-chart"}},
|
||||
{MenuLevel: 0, Hidden: true, ParentId: 0, Path: "person", Name: "person", Component: "view/person/person.vue", Sort: 4, Meta: Meta{Title: "个人信息", Icon: "message"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "example", Name: "example", Component: "view/example/index.vue", Sort: 7, Meta: Meta{Title: "示例文件", Icon: "management"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 11, Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: Meta{Title: "媒体库(上传下载)", Icon: "upload"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 11, Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: Meta{Title: "断点续传", Icon: "upload-filled"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 11, Path: "customer", Name: "customer", Component: "view/example/customer/customer.vue", Sort: 7, Meta: Meta{Title: "客户列表(资源示例)", Icon: "avatar"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "systemTools", Name: "systemTools", Component: "view/systemTools/index.vue", Sort: 5, Meta: Meta{Title: "系统工具", Icon: "tools"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "autoCode", Name: "autoCode", Component: "view/systemTools/autoCode/index.vue", Sort: 1, Meta: Meta{Title: "代码生成器", Icon: "cpu", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "formCreate", Name: "formCreate", Component: "view/systemTools/formCreate/index.vue", Sort: 2, Meta: Meta{Title: "表单生成器", Icon: "magic-stick", KeepAlive: true}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "system", Name: "system", Component: "view/systemTools/system/system.vue", Sort: 3, Meta: Meta{Title: "系统配置", Icon: "operation"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "autoCodeAdmin", Name: "autoCodeAdmin", Component: "view/systemTools/autoCodeAdmin/index.vue", Sort: 1, Meta: Meta{Title: "自动化代码管理", Icon: "magic-stick"}},
|
||||
{MenuLevel: 0, Hidden: true, ParentId: 15, Path: "autoCodeEdit/:id", Name: "autoCodeEdit", Component: "view/systemTools/autoCode/index.vue", Sort: 0, Meta: Meta{Title: "自动化代码-${id}", Icon: "magic-stick"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "autoPkg", Name: "autoPkg", Component: "view/systemTools/autoPkg/autoPkg.vue", Sort: 0, Meta: Meta{Title: "自动化package", Icon: "folder"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Component: "/", Sort: 0, Meta: Meta{Title: "官方网站", Icon: "customer-gva"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "state", Name: "state", Component: "view/system/state.vue", Sort: 8, Meta: Meta{Title: "服务器状态", Icon: "cloudy"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "plugin", Name: "plugin", Component: "view/routerHolder.vue", Sort: 6, Meta: Meta{Title: "插件系统", Icon: "cherry"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "https://plugin.gin-vue-admin.com/", Name: "https://plugin.gin-vue-admin.com/", Component: "https://plugin.gin-vue-admin.com/", Sort: 0, Meta: Meta{Title: "插件市场", Icon: "shop"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "installPlugin", Name: "installPlugin", Component: "view/systemTools/installPlugin/index.vue", Sort: 1, Meta: Meta{Title: "插件安装", Icon: "box"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "autoPlug", Name: "autoPlug", Component: "view/systemTools/autoPlug/autoPlug.vue", Sort: 2, Meta: Meta{Title: "插件模板", Icon: "folder"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "pubPlug", Name: "pubPlug", Component: "view/systemTools/pubPlug/pubPlug.vue", Sort: 3, Meta: Meta{Title: "打包插件", Icon: "files"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "plugin-email", Name: "plugin-email", Component: "plugin/email/view/index.vue", Sort: 4, Meta: Meta{Title: "邮件插件", Icon: "message"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "exportTemplate", Name: "exportTemplate", Component: "view/systemTools/exportTemplate/exportTemplate.vue", Sort: 10, Meta: Meta{Title: "表格模板", Icon: "reading"}},
|
||||
}
|
||||
if err = db.Create(&entities).Error; err != nil {
|
||||
return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+"表数据初始化失败!")
|
||||
|
||||
@@ -44,8 +44,15 @@ func (i *initUser) InitializeData(ctx context.Context) (next context.Context, er
|
||||
if !ok {
|
||||
return ctx, system.ErrMissingDBContext
|
||||
}
|
||||
password := utils.BcryptHash("6447985")
|
||||
adminPassword := utils.BcryptHash("123456")
|
||||
|
||||
ap := ctx.Value("adminPassword")
|
||||
apStr, ok := ap.(string)
|
||||
if !ok {
|
||||
apStr = "123456"
|
||||
}
|
||||
|
||||
password := utils.BcryptHash(apStr)
|
||||
adminPassword := utils.BcryptHash(apStr)
|
||||
|
||||
entities := []sysModel.SysUser{
|
||||
{
|
||||
|
||||
@@ -111,7 +111,15 @@ func RollRouterBack(pk, model string) {
|
||||
}
|
||||
|
||||
var block *ast.BlockStmt
|
||||
var routerStmt *ast.FuncDecl
|
||||
|
||||
ast.Inspect(astFile, func(node ast.Node) bool {
|
||||
if n, ok := node.(*ast.FuncDecl); ok {
|
||||
if n.Name.Name == "Routers" {
|
||||
routerStmt = n
|
||||
}
|
||||
}
|
||||
|
||||
if n, ok := node.(*ast.BlockStmt); ok {
|
||||
ast.Inspect(n, func(bNode ast.Node) bool {
|
||||
if in, ok := bNode.(*ast.Ident); ok {
|
||||
@@ -146,7 +154,15 @@ func RollRouterBack(pk, model string) {
|
||||
if len(block.List) == 1 {
|
||||
// 说明这个块就没任何意义了
|
||||
block.List = nil
|
||||
// TODO 删除空的{}
|
||||
}
|
||||
|
||||
for i, n := range routerStmt.Body.List {
|
||||
if n, ok := n.(*ast.BlockStmt); ok {
|
||||
if n.List == nil {
|
||||
routerStmt.Body.List = append(append([]ast.Stmt{}, routerStmt.Body.List[:i]...), routerStmt.Body.List[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var out []byte
|
||||
|
||||
@@ -79,6 +79,9 @@ func AddRouterCode(path, funcName, pk, model string) {
|
||||
&ast.Ident{
|
||||
Name: "PrivateGroup",
|
||||
},
|
||||
&ast.Ident{
|
||||
Name: "PublicGroup",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetJSONKeys(jsonStr string) (keys []string, err error) {
|
||||
// 使用json.Decoder,以便在解析过程中记录键的顺序
|
||||
dec := json.NewDecoder(strings.NewReader(jsonStr))
|
||||
t, err := dec.Token()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 确保数据是一个对象
|
||||
if t != json.Delim('{') {
|
||||
return nil, err
|
||||
}
|
||||
for dec.More() {
|
||||
t, err = dec.Token()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys = append(keys, t.(string))
|
||||
|
||||
// 解析值
|
||||
var value interface{}
|
||||
err = dec.Decode(&value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetJSONKeys(t *testing.T) {
|
||||
var jsonStr = `
|
||||
{
|
||||
"Name": "test",
|
||||
"TableName": "test",
|
||||
"TemplateID": "test",
|
||||
"TemplateInfo": "test",
|
||||
"Limit": 0
|
||||
}`
|
||||
keys, err := GetJSONKeys(jsonStr)
|
||||
if err != nil {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
return
|
||||
}
|
||||
if len(keys) != 5 {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
return
|
||||
}
|
||||
if keys[0] != "Name" {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
if keys[1] != "TableName" {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
if keys[2] != "TemplateID" {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
if keys[3] != "TemplateInfo" {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
if keys[4] != "Limit" {
|
||||
t.Errorf("GetJSONKeys failed" + err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(keys)
|
||||
}
|
||||
+18
-10
@@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@@ -20,7 +21,7 @@ type Server struct {
|
||||
Os Os `json:"os"`
|
||||
Cpu Cpu `json:"cpu"`
|
||||
Ram Ram `json:"ram"`
|
||||
Disk Disk `json:"disk"`
|
||||
Disk []Disk `json:"disk"`
|
||||
}
|
||||
|
||||
type Os struct {
|
||||
@@ -43,6 +44,7 @@ type Ram struct {
|
||||
}
|
||||
|
||||
type Disk struct {
|
||||
MountPoint string `json:"mountPoint"`
|
||||
UsedMB int `json:"usedMb"`
|
||||
UsedGB int `json:"usedGb"`
|
||||
TotalMB int `json:"totalMb"`
|
||||
@@ -104,15 +106,21 @@ func InitRAM() (r Ram, err error) {
|
||||
//@description: 硬盘信息
|
||||
//@return: d Disk, err error
|
||||
|
||||
func InitDisk() (d Disk, err error) {
|
||||
if u, err := disk.Usage("/"); err != nil {
|
||||
return d, err
|
||||
} else {
|
||||
d.UsedMB = int(u.Used) / MB
|
||||
d.UsedGB = int(u.Used) / GB
|
||||
d.TotalMB = int(u.Total) / MB
|
||||
d.TotalGB = int(u.Total) / GB
|
||||
d.UsedPercent = int(u.UsedPercent)
|
||||
func InitDisk() (d []Disk, err error) {
|
||||
for i := range global.GVA_CONFIG.DiskList {
|
||||
mp := global.GVA_CONFIG.DiskList[i].MountPoint
|
||||
if u, err := disk.Usage(mp); err != nil {
|
||||
return d, err
|
||||
} else {
|
||||
d = append(d, Disk{
|
||||
MountPoint: mp,
|
||||
UsedMB: int(u.Used) / MB,
|
||||
UsedGB: int(u.Used) / GB,
|
||||
TotalMB: int(u.Total) / MB,
|
||||
TotalGB: int(u.Total) / GB,
|
||||
UsedPercent: int(u.UsedPercent),
|
||||
})
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user