diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 63137d833dc4f8d06c21a6314e11adf7fba867f7..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: issues模板 -about: 请严格按照要求进行提交issues! 如果未能按照要求,我们将会close您的issues,敬请谅解! ---- - - -### 1. 您使用的是哪个版本的`Go`和系统类型/架构 ? - - - -### 2. 您使用的是哪个版本的 `Nodejs` 和 `npm` 或 `cnpm` ? - - - - - - - -### 3. 您使用的是哪个版本的 `gin-vue-admin` ? - - - - - -### 4. 可以在master版本中复现此问题吗 ? - - - -### 5. 您做了什么 ? - - - - - -### 6. 您期望看到什么 ? - - - -### 7. 您看到了什么 ? - - - -### 8. 错误堆栈或者SQL打印 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000000000000000000000000000000000000..134a4168f1484f1b7ab5b2ae51b56928d9f52485 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,60 @@ +name: 🐛 Bug report +description: Report a bug to help us improve Gin-Vue-Admin +title: "[Bug]: " +labels: [bug] +assignees: + - piexlmax + - songzhibin97 + - SliverHorn + - bypanghu +body: + - type: input + id: gva + attributes: + label: gin-vue-admin 版本 + description: 请输入您当前使用的项目版本? + placeholder: 2.4.5Beta + validations: + required: true + - type: input + id: node + attributes: + label: Node 版本 + description: 请输入您当前使用的NODE版本? + placeholder: v14.16.0 + validations: + required: true + - type: input + id: golang + attributes: + label: Golang 版本 + description: 请输入您当前使用的GOLANG版本? + placeholder: go 1.16 + validations: + required: true + - type: dropdown + id: reappearance + attributes: + label: 是否依旧存在 + description: 是否可以在master分支复现此bug? + options: + - 可以 + - 不可以 + - 未测试 + validations: + required: true + - type: textarea + id: desc + attributes: + label: bug描述 + description: 请简要描述bug以及复现过程. + placeholder: | + 1. 首先... + 2. 然后... + validations: + required: true + - type: textarea + id: advise + attributes: + label: 修改建议 + description: 您有好的建议或者修改方案可以提供给我们。 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..e3838d7523ae3929647e8c6ca52d335ac07a6c6d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Document + url: https://www.gin-vue-admin.com + about: If you have any questions about the use, you can check our official documents first diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000000000000000000000000000000000000..99a2603f6ecbf2c7f6f040f1270d016a112b764c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,22 @@ +name: 🚀 Feature request +description: Suggest an idea for Gin-Vue-Admin +title: "[Feature]: " +labels: [feature] +assignees: + - piexlmax +body: + - type: textarea + id: desc + attributes: + label: 功能描述以及必要性描述 + description: 您觉得此新功能会为框架带来什么便利. + placeholder: | + 1. 首先... + 2. 然后... + validations: + required: true + - type: textarea + id: advise + attributes: + label: 建议和方案 + description: 您有好的建议或者修改方案可以提供给我们。 diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 9d228e46e39177746b328312bfccc63e4e985b1d..b3f769938bf40abbc665421d6fb0bc022a1b9cc8 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [14.16.0] steps: - name: Check out branch uses: actions/checkout@v2 diff --git a/.github/workflows/devops.yml b/.github/workflows/devops.yml new file mode 100644 index 0000000000000000000000000000000000000000..912497e29ca3bc1500f4365c81db52471180cfd8 --- /dev/null +++ b/.github/workflows/devops.yml @@ -0,0 +1,51 @@ +name: devops +on: + push: + tags: + - v* + workflow_dispatch: +jobs: + build: + name: Build + runs-on: ubuntu-latest + strategy: + matrix: + node-version: ['16.x'] + go-version: ['1.16'] + steps: + - name: Check out branch + uses: actions/checkout@v2 + - name: Sed Config + shell: bash + run: | + git branch + ls -l + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2.1.2 + with: + node-version: ${{ matrix.node-version }} + - name: Build-Node + run: | + cd web/ && yarn install && yarn run build + - name: Use Go ${{ matrix.go-version }} + uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - name: Build-go + run: | + cd server/ && go mod tidy && go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s + - name: restart + env: + KEY: ${{ secrets.KEY }} + HOST: ${{ secrets.HOST }} + USER: ${{ secrets.USER }} + PROT: ${{ secrets.PROT }} + MKDIR: ${{ secrets.MKDIR }} + run: | + mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa + ssh-keyscan github.com >> ~/.ssh/known_hosts + scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIR}dist/ + scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIR} + ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR}resource/ && rm -rf ${MKDIR}resource/*" + scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIR}resource/ + ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR} && bash restart.sh > /dev/null 2>&1 &" diff --git a/.gitignore b/.gitignore index e7cc5a9db959cbdf44506f6e50769dae406bc708..859587ed043c6c7fba8d0cf0d0f2867b1a09ea6d 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ yarn-error.log* *.sln *.sw? -go.sum /server/log/ /server/gva /server/latest_log diff --git a/README.md b/README.md index 1a016332050f6079daf0f4e93754ba2032ab6c44..575c032f2343e005938d73b3eb43fe27457d7fb2 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@
- + - - + +
@@ -29,6 +29,8 @@ [开发教学](https://www.gin-vue-admin.com/docs/help) (贡献者: LLemonGreen And Fann) +[交流社区](https://support.qq.com/products/371961) + # 重要提示 1.本项目从起步到开发到部署均有文档和详细视频教程 @@ -37,11 +39,17 @@ 3.您完全可以通过我们的教程和文档完成一切操作,因此我们不再提供免费的技术服务,如需服务请进行[付费支持](https://www.gin-vue-admin.com/docs/payment) +4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,其余信息功能不做任何限制。如需剔除请联系微信:shouzi_1994 + + + +5.如果您需要服务器的话 2C4G8M 80GB 腾讯云 一年74 三年222 在这里购买:https://curl.qcloud.com/sArxMfaw + ## 1. 基本介绍 ### 1.1 项目介绍 -> Gin-vue-admin是一个基于 [vue](https://vuejs.org) 和 [gin](https://gin-gonic.com) 开发的全栈前后端分离的后台管理系统,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。 +> Gin-vue-admin是一个基于 [vue](https://vuejs.org) 和 [gin](https://gin-gonic.com) 开发的全栈前后端分离的开发基础平台,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。 [在线预览](http://demo.gin-vue-admin.com): http://demo.gin-vue-admin.com @@ -52,7 +60,7 @@ ### 1.2 贡献指南 Hi! 首先感谢你使用 gin-vue-admin。 -Gin-vue-admin 是一套为后台管理平台准备的一整套前后端分离架构式的开源框架,旨在快速搭建后台管理系统。 +Gin-vue-admin 是一套为快速研发准备的一整套前后端分离架构式的开源框架,旨在快速搭建中小型项目。 Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-admin 贡献代码或提供建议,请阅读以下内容。 @@ -72,20 +80,13 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm - 合并代码需要两名维护人员参与:一人进行 review 后 approve,另一人再次 review,通过后即可合并。 -### 1.3 版本列表 - -- master: 2.0, 用于生产环境 -- develop: 2.0, 用于测试环境 -- [gin-vue-admin_v2_dev](https://github.com/flipped-aurora/gin-vue-admin/tree/gin-vue-admin_v2_dev) (v2.0 [GormV1版本](https://v1.gorm.io)稳定分支) -- [gva_gormv2_dev](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_gormv2_dev) (v2.0 [GormV2版本](https://v2.gorm.io)开发分支) - ## 2. 使用说明 ``` -- node版本 > v8.6.0 -- golang版本 >= v1.14 +- node版本 > v12.18.3 +- golang版本 >= v1.16 - IDE推荐:Goland -- 初始化项目: 不同版本数据库初始化不通 参见 https://www.gin-vue-admin.com/docs/first +- 初始化项目: 不同版本数据库初始化不通 参见 https://www.gin-vue-admin.com/docs/first_master - 替换掉项目中的七牛云公钥,私钥,仓名和默认url地址,以免发生测试文件数据错乱 ``` diff --git a/deployment/server/gva-server-configmap.yaml b/deployment/server/gva-server-configmap.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fb889fb7e6dfef203ec3081c8c612970b1f44677 --- /dev/null +++ b/deployment/server/gva-server-configmap.yaml @@ -0,0 +1,148 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: config.yaml + annotations: + flipped-aurora/gin-vue-admin: backend + github: "https://github.com/flipped-aurora/gin-vue-admin.git" + app.kubernetes.io/version: 0.0.1 + labels: + app: gva-server + version: gva-vue3 +data: + config.yaml: | + # github.com/flipped-aurora/gin-vue-admin/server Global Configuration + + # jwt configuration + jwt: + signing-key: 'qmPlus' + expires-time: 604800 + buffer-time: 86400 + + # zap logger configuration + zap: + level: 'info' + format: 'console' + prefix: '[github.com/flipped-aurora/gin-vue-admin/server]' + director: 'log' + link-name: 'latest_log' + show-line: true + encode-level: 'LowercaseColorLevelEncoder' + stacktrace-key: 'stacktrace' + log-in-console: true + + # redis configuration + redis: + db: 0 + addr: '127.0.0.1:6379' + password: '' + + # email configuration + email: + to: 'xxx@qq.com' + port: 465 + from: 'xxx@163.com' + host: 'smtp.163.com' + is-ssl: true + secret: 'xxx' + nickname: 'test' + + # casbin configuration + casbin: + model-path: './resource/rbac_model.conf' + + # system configuration + system: + env: 'develop' # Change to "develop" to skip authentication for development mode + addr: 8888 + db-type: 'mysql' + oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 + use-multipoint: false + + # captcha configuration + captcha: + key-long: 6 + img-width: 240 + img-height: 80 + + # mysql connect configuration + # 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first) + mysql: + path: '' + config: '' + db-name: '' + username: '' + password: '' + max-idle-conns: 10 + max-open-conns: 100 + log-mode: false + log-zap: "" + + # local configuration + local: + path: 'uploads/file' + + # autocode configuration + autocode: + transfer-restart: true + root: "" + server: /server + server-api: /api/v1/autocode + server-initialize: /initialize + server-model: /model/autocode + server-request: /model/autocode/request/ + server-router: /router/autocode + server-service: /service/autocode + web: /web/src + web-api: /api + web-flow: /view + web-form: /view + web-table: /view + + # qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址) + qiniu: + zone: 'ZoneHuaDong' + bucket: '' + img-path: '' + use-https: false + access-key: '' + secret-key: '' + use-cdn-domains: false + + + # aliyun oss configuration + aliyun-oss: + endpoint: 'yourEndpoint' + access-key-id: 'yourAccessKeyId' + access-key-secret: 'yourAccessKeySecret' + bucket-name: 'yourBucketName' + bucket-url: 'yourBucketUrl' + base-path: 'yourBasePath' + + # tencent cos configuration + tencent-cos: + bucket: 'xxxxx-10005608' + region: 'ap-shanghai' + secret-id: 'xxxxxxxx' + secret-key: 'xxxxxxxx' + base-url: 'https://gin.vue.admin' + path-prefix: 'github.com/flipped-aurora/gin-vue-admin/server' + + # excel configuration + excel: + dir: './resource/excel/' + + + # timer task db clear table + Timer: + start: true + spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3 + detail: [ + # tableName: 需要清理的表名 + # compareField: 需要比较时间的字段 + # interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数 + # 2160h = 24 * 30 * 3 -> 三个月 + { tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" }, + { tableName: "jwt_blacklists" , compareField: "created_at", interval: "168h" } + #{ tableName: "log2" , compareField: "created_at", interval: "2160h" } + ] diff --git a/deployment/server/gva-server-deployment.yaml b/deployment/server/gva-server-deployment.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d89dcb63b93312e3b908a536503389e4702b7245 --- /dev/null +++ b/deployment/server/gva-server-deployment.yaml @@ -0,0 +1,68 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gva-server + annotations: + flipped-aurora/gin-vue-admin: backend + github: "https://github.com/flipped-aurora/gin-vue-admin.git" + app.kubernetes.io/version: 0.0.1 + labels: + app: gva-server + version: gva-vue3 +spec: + replicas: 1 + selector: + matchLabels: + app: gva-server + version: gva-vue3 + template: + metadata: + labels: + app: gva-server + version: gva-vue3 + spec: + containers: + - name: gin-vue-admin-container + image: registry.cn-hangzhou.aliyuncs.com/gin-vue-admin/server:40fc3aa6 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8888 + name: http + volumeMounts: + - mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.yaml + name: config + subPath: config.yaml + - mountPath: /etc/localtime + name: localtime + resources: + limits: + cpu: 1000m + memory: 2000Mi + requests: + cpu: 100m + memory: 200Mi +# readinessProbe: +# httpGet: +# path: /ready +# port: http +# initialDelaySeconds: 20 +# periodSeconds: 10 +# successThreshold: 1 +# failureThreshold: 3 +# livenessProbe: +# httpGet: +# path: /health +# port: http +# initialDelaySeconds: 20 +# periodSeconds: 10 +# successThreshold: 1 +# failureThreshold: 3 + #imagePullSecrets: + # - name: docker-registry + volumes: + - name: localtime + hostPath: + path: /etc/localtime + - name: config + configMap: + name: config.yaml \ No newline at end of file diff --git a/deployment/server/gva-server-service.yaml b/deployment/server/gva-server-service.yaml new file mode 100644 index 0000000000000000000000000000000000000000..17aaef2c8d5a4be741154f386389e29a7f919af9 --- /dev/null +++ b/deployment/server/gva-server-service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: gva-server + annotations: + flipped-aurora/gin-vue-admin: backend + github: "https://github.com/flipped-aurora/gin-vue-admin.git" + app.kubernetes.io/version: 0.0.1 + labels: + app: gva-server + version: gva-vue3 +spec: + selector: + app: gva-server + version: gva-vue3 + ports: + - port: 8888 + name: http + targetPort: 8888 + type: ClusterIP +# type: NodePort diff --git a/deployment/web/gva-web-configmap.yaml b/deployment/web/gva-web-configmap.yaml new file mode 100644 index 0000000000000000000000000000000000000000..189b8617e5afd117f8296e9838c7bdebea77c569 --- /dev/null +++ b/deployment/web/gva-web-configmap.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: my.conf +data: + my.conf: | + server { + listen 8080; + server_name localhost; + + #charset koi8-r; + #access_log logs/host.access.log main; + + location / { + root /usr/share/nginx/html; + add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + rewrite ^/api/(.*)$ /$1 break; #重写 + proxy_pass http://gva-server:8888; # 设置代理服务器的协议和地址 + } + + location /api/swagger/index.html { + proxy_pass http://gva-server:8888/swagger/index.html; + } + } \ No newline at end of file diff --git a/deployment/web/gva-web-deploymemt.yaml b/deployment/web/gva-web-deploymemt.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bb442477e4ec771bd446b2cd7aebcd5cc9ea4bc4 --- /dev/null +++ b/deployment/web/gva-web-deploymemt.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gva-web + annotations: + flipped-aurora/gin-vue-admin: ui + github: "https://github.com/flipped-aurora/gin-vue-admin.git" + app.kubernetes.io/version: 0.0.1 + labels: + app: gva-web + version: gva-vue3 +spec: + replicas: 1 + selector: + matchLabels: + app: gva-web + version: gva-vue3 + template: + metadata: + labels: + app: gva-web + version: gva-vue3 + spec: + containers: + - name: gin-vue-admin-nginx-container + image: registry.cn-hangzhou.aliyuncs.com/gin-vue-admin/web:40fc3aa6 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 + name: http + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + resources: + limits: + cpu: 500m + memory: 1000Mi + requests: + cpu: 100m + memory: 100Mi + volumeMounts: + - mountPath: /etc/nginx/conf.d/ + name: nginx-config + volumes: + - name: nginx-config + configMap: + name: my.conf diff --git a/deployment/web/gva-web-service.yaml b/deployment/web/gva-web-service.yaml new file mode 100644 index 0000000000000000000000000000000000000000..39bdeab39e0f99c4907be03997bb83b793b4f2c3 --- /dev/null +++ b/deployment/web/gva-web-service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: gva-web + annotations: + flipped-aurora/gin-vue-admin: ui + github: "https://github.com/flipped-aurora/gin-vue-admin.git" + app.kubernetes.io/version: 0.0.1 + labels: + app: gva-web + version: gva-vue3 +spec: + type: NodePort +# type: ClusterIP + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: gva-web + version: gva-vue3 diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 8b28c9bb244be0bf08b1980ef0cfc545746bb0ab..0000000000000000000000000000000000000000 --- a/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "gin-vue-admin", - "lockfileVersion": 2, - "requires": true, - "packages": {} -} diff --git a/package.json b/package.json deleted file mode 100644 index 0967ef424bce6791893e9a57bb952f80fd536e93..0000000000000000000000000000000000000000 --- a/package.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/server/Dockerfile b/server/Dockerfile index 3481e8eb72176ce256a3d7cab3c4d56eaeae91df..5c3b88618adc3dd66d027637c8705cddc4b192a9 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,9 +1,14 @@ -FROM golang:alpine +FROM golang:alpine as builder WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server COPY . . -RUN go generate && go env && go build -o server . +RUN go env -w GO111MODULE=on +RUN go env -w GOPROXY=https://goproxy.cn,direct +RUN go env -w CGO_ENABLED=0 +RUN go env +RUN go mod tidy +RUN go build -o server . FROM alpine:latest LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com" diff --git a/server/api/v1/autocode/autocodeExample.go b/server/api/v1/autocode/auto_code_example.go similarity index 93% rename from server/api/v1/autocode/autocodeExample.go rename to server/api/v1/autocode/auto_code_example.go index ff83240c2ef533c111dd8b27aa0f22d2c6220daf..8d34959965aa0c00b028f43b6b26b2fdb6c05adc 100644 --- a/server/api/v1/autocode/autocodeExample.go +++ b/server/api/v1/autocode/auto_code_example.go @@ -11,8 +11,7 @@ import ( "go.uber.org/zap" ) -type AutoCodeExampleApi struct { -} +type AutoCodeExampleApi struct{} var autoCodeExampleService = service.ServiceGroupApp.AutoCodeServiceGroup.AutoCodeExampleService @@ -28,7 +27,7 @@ func (autoCodeExampleApi *AutoCodeExampleApi) CreateAutoCodeExample(c *gin.Conte var autoCodeExample autocode.AutoCodeExample _ = c.ShouldBindJSON(&autoCodeExample) if err := autoCodeExampleService.CreateAutoCodeExample(autoCodeExample); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -47,7 +46,7 @@ func (autoCodeExampleApi *AutoCodeExampleApi) DeleteAutoCodeExample(c *gin.Conte var autoCodeExample autocode.AutoCodeExample _ = c.ShouldBindJSON(&autoCodeExample) if err := autoCodeExampleService.DeleteAutoCodeExample(autoCodeExample); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -66,7 +65,7 @@ func (autoCodeExampleApi *AutoCodeExampleApi) UpdateAutoCodeExample(c *gin.Conte var autoCodeExample autocode.AutoCodeExample _ = c.ShouldBindJSON(&autoCodeExample) if err := autoCodeExampleService.UpdateAutoCodeExample(&autoCodeExample); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) @@ -89,7 +88,7 @@ func (autoCodeExampleApi *AutoCodeExampleApi) FindAutoCodeExample(c *gin.Context return } if err, reAutoCodeExample := autoCodeExampleService.GetAutoCodeExample(autoCodeExample.ID); err != nil { - global.GVA_LOG.Error("查询失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败", c) } else { response.OkWithDetailed(gin.H{"reAutoCodeExample": reAutoCodeExample}, "查询成功", c) @@ -108,7 +107,7 @@ func (autoCodeExampleApi *AutoCodeExampleApi) GetAutoCodeExampleList(c *gin.Cont var pageInfo autocodeReq.AutoCodeExampleSearch _ = c.ShouldBindQuery(&pageInfo) if err, list, total := autoCodeExampleService.GetAutoCodeExampleInfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/enter.go b/server/api/v1/enter.go index 4f92934ec53b239021c5b9ced773cc0da300c593..919f6881fdd857a3c46bac46aa4e679697e7ffdc 100644 --- a/server/api/v1/enter.go +++ b/server/api/v1/enter.go @@ -7,8 +7,8 @@ import ( ) type ApiGroup struct { - ExampleApiGroup example.ApiGroup SystemApiGroup system.ApiGroup + ExampleApiGroup example.ApiGroup AutoCodeApiGroup autocode.ApiGroup } diff --git a/server/api/v1/example/enter.go b/server/api/v1/example/enter.go index 9149e02e20bdebc84f88c9496834548b095fdea4..1a3ac1173a5b72821517638ada4d5964e8612a43 100644 --- a/server/api/v1/example/enter.go +++ b/server/api/v1/example/enter.go @@ -3,11 +3,13 @@ package example import "github.com/flipped-aurora/gin-vue-admin/server/service" type ApiGroup struct { - CustomerApi ExcelApi + CustomerApi FileUploadAndDownloadApi } -var fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService -var customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService -var excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService +var ( + excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService + customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService + fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService +) diff --git a/server/api/v1/example/exa_breakpoint_continue.go b/server/api/v1/example/exa_breakpoint_continue.go index 9afbf2792b11842a228f02e77a30249f471c0c64..e10db174f95d20ad92705662a0139d632ad6465f 100644 --- a/server/api/v1/example/exa_breakpoint_continue.go +++ b/server/api/v1/example/exa_breakpoint_continue.go @@ -1,7 +1,9 @@ package example import ( + "fmt" "io/ioutil" + "mime/multipart" "strconv" "github.com/flipped-aurora/gin-vue-admin/server/global" @@ -28,38 +30,43 @@ func (u *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) { chunkTotal, _ := strconv.Atoi(c.Request.FormValue("chunkTotal")) _, FileHeader, err := c.Request.FormFile("file") if err != nil { - global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err)) + global.GVA_LOG.Error("接收文件失败!", zap.Error(err)) response.FailWithMessage("接收文件失败", c) return } f, err := FileHeader.Open() if err != nil { - global.GVA_LOG.Error("文件读取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("文件读取失败!", zap.Error(err)) response.FailWithMessage("文件读取失败", c) return } - defer f.Close() + defer func(f multipart.File) { + err := f.Close() + if err != nil { + fmt.Println(err) + } + }(f) cen, _ := ioutil.ReadAll(f) if !utils.CheckMd5(cen, chunkMd5) { - global.GVA_LOG.Error("检查md5失败!", zap.Any("err", err)) + global.GVA_LOG.Error("检查md5失败!", zap.Error(err)) response.FailWithMessage("检查md5失败", c) return } err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal) if err != nil { - global.GVA_LOG.Error("查找或创建记录失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查找或创建记录失败!", zap.Error(err)) response.FailWithMessage("查找或创建记录失败", c) return } err, pathc := utils.BreakPointContinue(cen, fileName, chunkNumber, chunkTotal, fileMd5) if err != nil { - global.GVA_LOG.Error("断点续传失败!", zap.Any("err", err)) + global.GVA_LOG.Error("断点续传失败!", zap.Error(err)) response.FailWithMessage("断点续传失败", c) return } if err = fileUploadAndDownloadService.CreateFileChunk(file.ID, pathc, chunkNumber); err != nil { - global.GVA_LOG.Error("创建文件记录失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建文件记录失败!", zap.Error(err)) response.FailWithMessage("创建文件记录失败", c) return } @@ -80,7 +87,7 @@ func (u *FileUploadAndDownloadApi) FindFile(c *gin.Context) { chunkTotal, _ := strconv.Atoi(c.Query("chunkTotal")) err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal) if err != nil { - global.GVA_LOG.Error("查找失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查找失败!", zap.Error(err)) response.FailWithMessage("查找失败", c) } else { response.OkWithDetailed(exampleRes.FileResponse{File: file}, "查找成功", c) @@ -100,7 +107,7 @@ func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Context) { fileName := c.Query("fileName") err, filePath := utils.MakeFile(fileName, fileMd5) if err != nil { - global.GVA_LOG.Error("文件创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("文件创建失败!", zap.Error(err)) response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建失败", c) } else { response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建成功", c) @@ -120,9 +127,12 @@ func (u *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) { fileName := c.Query("fileName") filePath := c.Query("filePath") err := utils.RemoveChunk(fileMd5) + if err != nil { + return + } err = fileUploadAndDownloadService.DeleteFileChunk(fileMd5, fileName, filePath) if err != nil { - global.GVA_LOG.Error("缓存切片删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("缓存切片删除失败!", zap.Error(err)) response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "缓存切片删除失败", c) } else { response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "缓存切片删除成功", c) diff --git a/server/api/v1/example/exa_customer.go b/server/api/v1/example/exa_customer.go index 3939ebfb58f76d82d62b11c40402ce67b6a3d7ab..4a3aecc266928dcf9cb8d75c34923fdec4af9657 100644 --- a/server/api/v1/example/exa_customer.go +++ b/server/api/v1/example/exa_customer.go @@ -11,8 +11,7 @@ import ( "go.uber.org/zap" ) -type CustomerApi struct { -} +type CustomerApi struct{} // @Tags ExaCustomer // @Summary 创建客户 @@ -32,7 +31,7 @@ func (e *CustomerApi) CreateExaCustomer(c *gin.Context) { customer.SysUserID = utils.GetUserID(c) customer.SysUserAuthorityID = utils.GetUserAuthorityId(c) if err := customerService.CreateExaCustomer(customer); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -55,7 +54,7 @@ func (e *CustomerApi) DeleteExaCustomer(c *gin.Context) { return } if err := customerService.DeleteExaCustomer(customer); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -82,7 +81,7 @@ func (e *CustomerApi) UpdateExaCustomer(c *gin.Context) { return } if err := customerService.UpdateExaCustomer(&customer); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) @@ -106,7 +105,7 @@ func (e *CustomerApi) GetExaCustomer(c *gin.Context) { } err, data := customerService.GetExaCustomer(customer.ID) if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(exampleRes.ExaCustomerResponse{Customer: data}, "获取成功", c) @@ -130,7 +129,7 @@ func (e *CustomerApi) GetExaCustomerList(c *gin.Context) { } err, customerList, total := customerService.GetCustomerInfoList(utils.GetUserAuthorityId(c), pageInfo) if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败"+err.Error(), c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/example/exa_excel.go b/server/api/v1/example/exa_excel.go index 12dc2b9eb6539531b8d19003d7a03e84b761be94..22a13645dddc0f0d032ef7617c2d95996ad9bf90 100644 --- a/server/api/v1/example/exa_excel.go +++ b/server/api/v1/example/exa_excel.go @@ -9,8 +9,7 @@ import ( "go.uber.org/zap" ) -type ExcelApi struct { -} +type ExcelApi struct{} // /excel/importExcel 接口,与upload接口作用类似,只是把文件存到resource/excel目录下,用于导入Excel时存放Excel文件(ExcelImport.xlsx) // /excel/loadExcel接口,用于读取resource/excel目录下的文件((ExcelImport.xlsx)并加载为[]model.SysBaseMenu类型的示例数据 @@ -31,7 +30,7 @@ func (e *ExcelApi) ExportExcel(c *gin.Context) { filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName err := excelService.ParseInfoList2Excel(excelInfo.InfoList, filePath) if err != nil { - global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err)) + global.GVA_LOG.Error("转换Excel失败!", zap.Error(err)) response.FailWithMessage("转换Excel失败", c) return } @@ -50,7 +49,7 @@ func (e *ExcelApi) ExportExcel(c *gin.Context) { func (e *ExcelApi) ImportExcel(c *gin.Context) { _, header, err := c.Request.FormFile("file") if err != nil { - global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err)) + global.GVA_LOG.Error("接收文件失败!", zap.Error(err)) response.FailWithMessage("接收文件失败", c) return } @@ -67,7 +66,7 @@ func (e *ExcelApi) ImportExcel(c *gin.Context) { func (e *ExcelApi) LoadExcel(c *gin.Context) { menus, err := excelService.ParseExcel2InfoList() if err != nil { - global.GVA_LOG.Error("加载数据失败!", zap.Any("err", err)) + global.GVA_LOG.Error("加载数据失败!", zap.Error(err)) response.FailWithMessage("加载数据失败", c) return } @@ -92,7 +91,7 @@ func (e *ExcelApi) DownloadTemplate(c *gin.Context) { filePath := global.GVA_CONFIG.Excel.Dir + fileName ok, err := utils.PathExists(filePath) if !ok || err != nil { - global.GVA_LOG.Error("文件不存在!", zap.Any("err", err)) + global.GVA_LOG.Error("文件不存在!", zap.Error(err)) response.FailWithMessage("文件不存在", c) return } diff --git a/server/api/v1/example/exa_file_upload_download.go b/server/api/v1/example/exa_file_upload_download.go index 5fdf6dc58b96f97d90c431dfe635c0f1cee853d7..6d33b4a067ad632cfcaadaf387ecdc7048b6e833 100644 --- a/server/api/v1/example/exa_file_upload_download.go +++ b/server/api/v1/example/exa_file_upload_download.go @@ -10,8 +10,7 @@ import ( "go.uber.org/zap" ) -type FileUploadAndDownloadApi struct { -} +type FileUploadAndDownloadApi struct{} // @Tags ExaFileUploadAndDownload // @Summary 上传文件示例 @@ -26,13 +25,13 @@ func (u *FileUploadAndDownloadApi) UploadFile(c *gin.Context) { noSave := c.DefaultQuery("noSave", "0") _, header, err := c.Request.FormFile("file") if err != nil { - global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err)) + global.GVA_LOG.Error("接收文件失败!", zap.Error(err)) response.FailWithMessage("接收文件失败", c) return } err, file = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径 if err != nil { - global.GVA_LOG.Error("修改数据库链接失败!", zap.Any("err", err)) + global.GVA_LOG.Error("修改数据库链接失败!", zap.Error(err)) response.FailWithMessage("修改数据库链接失败", c) return } @@ -50,7 +49,7 @@ func (u *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) { var file example.ExaFileUploadAndDownload _ = c.ShouldBindJSON(&file) if err := fileUploadAndDownloadService.DeleteFile(file); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) return } @@ -70,7 +69,7 @@ func (u *FileUploadAndDownloadApi) GetFileList(c *gin.Context) { _ = c.ShouldBindJSON(&pageInfo) err, list, total := fileUploadAndDownloadService.GetFileRecordInfoList(pageInfo) if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/system/enter.go b/server/api/v1/system/enter.go index 995522c3c0a368fcf3981425cb97b762bea994cb..edb3622277539b89a4a5ed1ce91df243b818925e 100644 --- a/server/api/v1/system/enter.go +++ b/server/api/v1/system/enter.go @@ -3,31 +3,34 @@ package system import "github.com/flipped-aurora/gin-vue-admin/server/service" type ApiGroup struct { - SystemApiApi - AuthorityApi - AutoCodeApi + DBApi + JwtApi BaseApi + SystemApi CasbinApi + AutoCodeApi + SystemApiApi + AuthorityApi DictionaryApi - DictionaryDetailApi - SystemApi - DBApi - JwtApi - OperationRecordApi AuthorityMenuApi + OperationRecordApi + AutoCodeHistoryApi + DictionaryDetailApi } -var authorityService = service.ServiceGroupApp.SystemServiceGroup.AuthorityService -var apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService -var menuService = service.ServiceGroupApp.SystemServiceGroup.MenuService -var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService -var autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService -var autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService -var dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService -var dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService -var initDBService = service.ServiceGroupApp.SystemServiceGroup.InitDBService -var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService -var baseMenuService = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService -var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService -var userService = service.ServiceGroupApp.SystemServiceGroup.UserService -var systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService +var ( + apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService + jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService + menuService = service.ServiceGroupApp.SystemServiceGroup.MenuService + userService = service.ServiceGroupApp.SystemServiceGroup.UserService + initDBService = service.ServiceGroupApp.SystemServiceGroup.InitDBService + casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService + autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService + baseMenuService = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService + authorityService = service.ServiceGroupApp.SystemServiceGroup.AuthorityService + dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService + systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService + operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService + autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService + dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService +) diff --git a/server/api/v1/system/sys_api.go b/server/api/v1/system/sys_api.go index ba7fb8a37794938ad7dcb930a527a19d105a7da7..cb1f6772a493d7078a2715e61e6f24cb80e275c9 100644 --- a/server/api/v1/system/sys_api.go +++ b/server/api/v1/system/sys_api.go @@ -13,8 +13,7 @@ import ( "go.uber.org/zap" ) -type SystemApiApi struct { -} +type SystemApiApi struct{} // @Tags SysApi // @Summary 创建基础api @@ -32,7 +31,7 @@ func (s *SystemApiApi) CreateApi(c *gin.Context) { return } if err := apiService.CreateApi(api); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -55,7 +54,7 @@ func (s *SystemApiApi) DeleteApi(c *gin.Context) { return } if err := apiService.DeleteApi(api); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -78,7 +77,7 @@ func (s *SystemApiApi) GetApiList(c *gin.Context) { return } if err, list, total := apiService.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ @@ -107,7 +106,7 @@ func (s *SystemApiApi) GetApiById(c *gin.Context) { } err, api := apiService.GetApiById(idInfo.ID) if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithData(systemRes.SysAPIResponse{Api: api}, c) @@ -130,7 +129,7 @@ func (s *SystemApiApi) UpdateApi(c *gin.Context) { return } if err := apiService.UpdateApi(api); err != nil { - global.GVA_LOG.Error("修改失败!", zap.Any("err", err)) + global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage("修改失败", c) } else { response.OkWithMessage("修改成功", c) @@ -146,7 +145,7 @@ func (s *SystemApiApi) UpdateApi(c *gin.Context) { // @Router /api/getAllApis [post] func (s *SystemApiApi) GetAllApis(c *gin.Context) { if err, apis := apiService.GetAllApis(); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(systemRes.SysAPIListResponse{Apis: apis}, "获取成功", c) @@ -165,7 +164,7 @@ func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) { var ids request.IdsReq _ = c.ShouldBindJSON(&ids) if err := apiService.DeleteApisByIds(ids); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) diff --git a/server/api/v1/system/sys_authority.go b/server/api/v1/system/sys_authority.go index 5cb6d96a44a855f535ca39a369762177313474b5..32e669eb5d19e5164864022a2b3b02b4cf0c286a 100644 --- a/server/api/v1/system/sys_authority.go +++ b/server/api/v1/system/sys_authority.go @@ -13,8 +13,7 @@ import ( "go.uber.org/zap" ) -type AuthorityApi struct { -} +type AuthorityApi struct{} // @Tags Authority // @Summary 创建角色 @@ -32,7 +31,7 @@ func (a *AuthorityApi) CreateAuthority(c *gin.Context) { return } if err, authBack := authorityService.CreateAuthority(authority); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败"+err.Error(), c) } else { _ = menuService.AddMenuAuthority(systemReq.DefaultMenu(), authority.AuthorityId) @@ -61,7 +60,7 @@ func (a *AuthorityApi) CopyAuthority(c *gin.Context) { return } if err, authBack := authorityService.CopyAuthority(copyInfo); err != nil { - global.GVA_LOG.Error("拷贝失败!", zap.Any("err", err)) + global.GVA_LOG.Error("拷贝失败!", zap.Error(err)) response.FailWithMessage("拷贝失败"+err.Error(), c) } else { response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c) @@ -84,7 +83,7 @@ func (a *AuthorityApi) DeleteAuthority(c *gin.Context) { return } if err := authorityService.DeleteAuthority(&authority); err != nil { // 删除角色之前需要判断是否有用户正在使用此角色 - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败"+err.Error(), c) } else { response.OkWithMessage("删除成功", c) @@ -107,7 +106,7 @@ func (a *AuthorityApi) UpdateAuthority(c *gin.Context) { return } if err, authority := authorityService.UpdateAuthority(auth); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败"+err.Error(), c) } else { response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authority}, "更新成功", c) @@ -130,7 +129,7 @@ func (a *AuthorityApi) GetAuthorityList(c *gin.Context) { return } if err, list, total := authorityService.GetAuthorityInfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败"+err.Error(), c) } else { response.OkWithDetailed(response.PageResult{ @@ -158,7 +157,7 @@ func (a *AuthorityApi) SetDataAuthority(c *gin.Context) { return } if err := authorityService.SetDataAuthority(auth); err != nil { - global.GVA_LOG.Error("设置失败!", zap.Any("err", err)) + global.GVA_LOG.Error("设置失败!", zap.Error(err)) response.FailWithMessage("设置失败"+err.Error(), c) } else { response.OkWithMessage("设置成功", c) diff --git a/server/api/v1/system/sys_auto_code.go b/server/api/v1/system/sys_auto_code.go index e8b7b049141fbd2da48c1a7793e2ed321e372975..7b24e9267e417aae9cf5d08fcf569c8deefce407 100644 --- a/server/api/v1/system/sys_auto_code.go +++ b/server/api/v1/system/sys_auto_code.go @@ -9,99 +9,15 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" "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/gin-gonic/gin" "go.uber.org/zap" ) -type AutoCodeApi struct { -} - -// @Tags AutoCode -// @Summary 删除回滚记录 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body systemReq.AutoHistoryByID true "删除回滚记录" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" -// @Router /autoCode/delSysHistory [post] -func (autoApi *AutoCodeApi) DelSysHistory(c *gin.Context) { - var id systemReq.AutoHistoryByID - _ = c.ShouldBindJSON(&id) - err := autoCodeHistoryService.DeletePage(id.ID) - if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) - response.FailWithMessage("获取失败", c) - } - response.OkWithMessage("删除成功", c) - -} - -// @Tags AutoCode -// @Summary 查询回滚记录 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body systemReq.SysAutoHistory true "查询回滚记录" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" -// @Router /autoCode/getSysHistory [post] -func (autoApi *AutoCodeApi) GetSysHistory(c *gin.Context) { - var search systemReq.SysAutoHistory - _ = c.ShouldBindJSON(&search) - err, list, total := autoCodeHistoryService.GetSysHistoryPage(search.PageInfo) - if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) - response.FailWithMessage("获取失败", c) - } else { - response.OkWithDetailed(response.PageResult{ - List: list, - Total: total, - Page: search.Page, - PageSize: search.PageSize, - }, "获取成功", c) - } -} - -// @Tags AutoCode -// @Summary 回滚 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body systemReq.AutoHistoryByID true "回滚自动生成代码" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"回滚成功"}" -// @Router /autoCode/rollback [post] -func (autoApi *AutoCodeApi) RollBack(c *gin.Context) { - var id systemReq.AutoHistoryByID - _ = c.ShouldBindJSON(&id) - if err := autoCodeHistoryService.RollBack(id.ID); err != nil { - response.FailWithMessage(err.Error(), c) - return - } - response.OkWithMessage("回滚成功", c) -} - -// @Tags AutoCode -// @Summary 回滚 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body systemReq.AutoHistoryByID true "获取meta信息" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" -// @Router /autoCode/getMeta [post] -func (autoApi *AutoCodeApi) GetMeta(c *gin.Context) { - var id systemReq.AutoHistoryByID - _ = c.ShouldBindJSON(&id) - if v, err := autoCodeHistoryService.GetMeta(id.ID); err != nil { - response.FailWithMessage(err.Error(), c) - return - } else { - response.OkWithDetailed(gin.H{"meta": v}, "获取成功", c) - } - -} +type AutoCodeApi struct{} +// PreviewTemp // @Tags AutoCode // @Summary 预览创建后的代码 // @Security ApiKeyAuth @@ -119,13 +35,14 @@ func (autoApi *AutoCodeApi) PreviewTemp(c *gin.Context) { } autoCode, err := autoCodeService.PreviewTemp(a) if err != nil { - global.GVA_LOG.Error("预览失败!", zap.Any("err", err)) + global.GVA_LOG.Error("预览失败!", zap.Error(err)) response.FailWithMessage("预览失败", c) } else { response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c) } } +// CreateTemp // @Tags AutoCode // @Summary 自动代码模板 // @Security ApiKeyAuth @@ -144,7 +61,7 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) { var apiIds []uint if a.AutoCreateApiToSql { if ids, err := autoCodeService.AutoCreateApi(&a); err != nil { - global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Any("err", err)) + global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err)) c.Writer.Header().Add("success", "false") c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!")) return @@ -171,40 +88,43 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) { } } +// GetDB // @Tags AutoCode -// @Summary 获取当前数据库所有表 +// @Summary 获取当前所有数据库 // @Security ApiKeyAuth // @accept application/json // @Produce application/json // @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" -// @Router /autoCode/getTables [get] -func (autoApi *AutoCodeApi) GetTables(c *gin.Context) { - dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) - err, tables := autoCodeService.GetTables(dbName) +// @Router /autoCode/getDatabase [get] +func (autoApi *AutoCodeApi) GetDB(c *gin.Context) { + dbs, err := autoCodeService.Database().GetDB() if err != nil { - global.GVA_LOG.Error("查询table失败!", zap.Any("err", err)) - response.FailWithMessage("查询table失败", c) - } else { - response.OkWithDetailed(gin.H{"tables": tables}, "获取成功", c) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败", c) } + response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c) } +// GetTables // @Tags AutoCode -// @Summary 获取当前所有数据库 +// @Summary 获取当前数据库所有表 // @Security ApiKeyAuth // @accept application/json // @Produce application/json // @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" -// @Router /autoCode/getDatabase [get] -func (autoApi *AutoCodeApi) GetDB(c *gin.Context) { - if err, dbs := autoCodeService.GetDB(); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) - response.FailWithMessage("获取失败", c) +// @Router /autoCode/getTables [get] +func (autoApi *AutoCodeApi) GetTables(c *gin.Context) { + dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) + tables, err := autoCodeService.Database().GetTables(dbName) + if err != nil { + global.GVA_LOG.Error("查询table失败!", zap.Error(err)) + response.FailWithMessage("查询table失败", c) } else { - response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c) + response.OkWithDetailed(gin.H{"tables": tables}, "获取成功", c) } } +// GetColumn // @Tags AutoCode // @Summary 获取当前表所有字段 // @Security ApiKeyAuth @@ -215,10 +135,10 @@ func (autoApi *AutoCodeApi) GetDB(c *gin.Context) { func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) { dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) tableName := c.Query("tableName") - if err, columns := autoCodeService.GetColumn(tableName, dbName); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + columns, err := autoCodeService.Database().GetColumn(tableName, dbName) + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) - } else { - response.OkWithDetailed(gin.H{"columns": columns}, "获取成功", c) } + response.OkWithDetailed(gin.H{"columns": columns}, "获取成功", c) } diff --git a/server/api/v1/system/sys_auto_code_history.go b/server/api/v1/system/sys_auto_code_history.go new file mode 100644 index 0000000000000000000000000000000000000000..7254b96b364749b7de89bb475da3706894340afb --- /dev/null +++ b/server/api/v1/system/sys_auto_code_history.go @@ -0,0 +1,98 @@ +package system + +import ( + "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/common/response" + systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +type AutoCodeHistoryApi struct{} + +// First +// @Tags AutoCode +// @Summary 获取meta信息 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.GetById true "请求参数" +// @Success 200 {object} response.Response{} "获取成功!" +// @Router /autoCode/getMeta [post] +func (a *AutoCodeHistoryApi) First(c *gin.Context) { + var info request.GetById + _ = c.ShouldBindJSON(&info) + data, err := autoCodeHistoryService.First(&info) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + response.OkWithDetailed(gin.H{"meta": data}, "获取成功", c) +} + +// Delete +// @Tags AutoCode +// @Summary 删除回滚记录 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.GetById true "请求参数" +// @Success 200 {object} response.Response{} "删除成功!" +// @Router /autoCode/delSysHistory [post] +func (a *AutoCodeHistoryApi) Delete(c *gin.Context) { + var info request.GetById + _ = c.ShouldBindJSON(&info) + err := autoCodeHistoryService.Delete(&info) + if err != nil { + global.GVA_LOG.Error("删除失败!", zap.Error(err)) + response.FailWithMessage("删除失败", c) + return + } + response.OkWithMessage("删除成功", c) +} + +// RollBack +// @Tags AutoCode +// @Summary 回滚自动生成代码 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.GetById true "请求参数" +// @Success 200 {object} response.Response{} "回滚成功!" +// @Router /autoCode/rollback [post] +func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) { + var info request.GetById + _ = c.ShouldBindJSON(&info) + if err := autoCodeHistoryService.RollBack(&info); err != nil { + response.FailWithMessage(err.Error(), c) + return + } + response.OkWithMessage("回滚成功", c) +} + +// GetList +// @Tags AutoCode +// @Summary 查询回滚记录 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body systemReq.SysAutoHistory true "请求参数" +// @Success 200 {object} response.Response{} "获取成功!" +// @Router /autoCode/getSysHistory [post] +func (a *AutoCodeHistoryApi) GetList(c *gin.Context) { + var search systemReq.SysAutoHistory + _ = c.ShouldBindJSON(&search) + list, total, err := autoCodeHistoryService.GetList(search.PageInfo) + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败", c) + return + } + response.OkWithDetailed(response.PageResult{ + List: list, + Total: total, + Page: search.Page, + PageSize: search.PageSize, + }, "获取成功", c) +} diff --git a/server/api/v1/system/sys_captcha.go b/server/api/v1/system/sys_captcha.go index f07587d560a702ffe3c9150399f344fa95ced162..763e8ee0270cc01528739791a6901bb81f61ca80 100644 --- a/server/api/v1/system/sys_captcha.go +++ b/server/api/v1/system/sys_captcha.go @@ -10,11 +10,10 @@ import ( ) // 当开启多服务器部署时,替换下面的配置,使用redis共享存储验证码 -//var store = captcha.NewDefaultRedisStore() +// var store = captcha.NewDefaultRedisStore() var store = base64Captcha.DefaultMemStore -type BaseApi struct { -} +type BaseApi struct{} // @Tags Base // @Summary 生成验证码 @@ -27,15 +26,16 @@ func (b *BaseApi) Captcha(c *gin.Context) { // 字符,公式,验证码配置 // 生成默认数字的driver 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.UseWithCtx(c)) // v8下使用redis cp := base64Captcha.NewCaptcha(driver, store) if id, b64s, err := cp.Generate(); err != nil { - global.GVA_LOG.Error("验证码获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("验证码获取失败!", zap.Error(err)) response.FailWithMessage("验证码获取失败", c) } else { response.OkWithDetailed(systemRes.SysCaptchaResponse{ - CaptchaId: id, - PicPath: b64s, + CaptchaId: id, + PicPath: b64s, + CaptchaLength: global.GVA_CONFIG.Captcha.KeyLong, }, "验证码获取成功", c) } } diff --git a/server/api/v1/system/sys_casbin.go b/server/api/v1/system/sys_casbin.go index ce2f1bcb1b92b8742c5151e854d27a5e02733aca..eef09f6410c8311bad010dcb255a1c05d07936df 100644 --- a/server/api/v1/system/sys_casbin.go +++ b/server/api/v1/system/sys_casbin.go @@ -10,8 +10,7 @@ import ( "go.uber.org/zap" ) -type CasbinApi struct { -} +type CasbinApi struct{} // @Tags Casbin // @Summary 更新角色api权限 @@ -29,7 +28,7 @@ func (cas *CasbinApi) UpdateCasbin(c *gin.Context) { return } if err := casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) diff --git a/server/api/v1/system/sys_dictionary.go b/server/api/v1/system/sys_dictionary.go index 4b7b394464c3bca9a78569108672e73477e5111a..d3c560e170503e533ab4f68c7f02a0f779cc66e0 100644 --- a/server/api/v1/system/sys_dictionary.go +++ b/server/api/v1/system/sys_dictionary.go @@ -10,8 +10,7 @@ import ( "go.uber.org/zap" ) -type DictionaryApi struct { -} +type DictionaryApi struct{} // @Tags SysDictionary // @Summary 创建SysDictionary @@ -25,7 +24,7 @@ func (s *DictionaryApi) CreateSysDictionary(c *gin.Context) { var dictionary system.SysDictionary _ = c.ShouldBindJSON(&dictionary) if err := dictionaryService.CreateSysDictionary(dictionary); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -44,7 +43,7 @@ func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) { var dictionary system.SysDictionary _ = c.ShouldBindJSON(&dictionary) if err := dictionaryService.DeleteSysDictionary(dictionary); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -63,7 +62,7 @@ func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) { var dictionary system.SysDictionary _ = c.ShouldBindJSON(&dictionary) if err := dictionaryService.UpdateSysDictionary(&dictionary); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) @@ -82,7 +81,7 @@ func (s *DictionaryApi) FindSysDictionary(c *gin.Context) { var dictionary system.SysDictionary _ = c.ShouldBindQuery(&dictionary) if err, sysDictionary := dictionaryService.GetSysDictionary(dictionary.Type, dictionary.ID); err != nil { - global.GVA_LOG.Error("查询失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败", c) } else { response.OkWithDetailed(gin.H{"resysDictionary": sysDictionary}, "查询成功", c) @@ -105,7 +104,7 @@ func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) { return } if err, list, total := dictionaryService.GetSysDictionaryInfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/system/sys_dictionary_detail.go b/server/api/v1/system/sys_dictionary_detail.go index 4984462426782201f5488bb429e7829decc37ac8..5c06246c59a5ed743b29b9b1909d301026f6013b 100644 --- a/server/api/v1/system/sys_dictionary_detail.go +++ b/server/api/v1/system/sys_dictionary_detail.go @@ -10,8 +10,7 @@ import ( "go.uber.org/zap" ) -type DictionaryDetailApi struct { -} +type DictionaryDetailApi struct{} // @Tags SysDictionaryDetail // @Summary 创建SysDictionaryDetail @@ -25,7 +24,7 @@ func (s *DictionaryDetailApi) CreateSysDictionaryDetail(c *gin.Context) { var detail system.SysDictionaryDetail _ = c.ShouldBindJSON(&detail) if err := dictionaryDetailService.CreateSysDictionaryDetail(detail); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -44,7 +43,7 @@ func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) { var detail system.SysDictionaryDetail _ = c.ShouldBindJSON(&detail) if err := dictionaryDetailService.DeleteSysDictionaryDetail(detail); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -63,7 +62,7 @@ func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) { var detail system.SysDictionaryDetail _ = c.ShouldBindJSON(&detail) if err := dictionaryDetailService.UpdateSysDictionaryDetail(&detail); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) @@ -86,7 +85,7 @@ func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) { return } if err, resysDictionaryDetail := dictionaryDetailService.GetSysDictionaryDetail(detail.ID); err != nil { - global.GVA_LOG.Error("查询失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败", c) } else { response.OkWithDetailed(gin.H{"resysDictionaryDetail": resysDictionaryDetail}, "查询成功", c) @@ -105,7 +104,7 @@ func (s *DictionaryDetailApi) GetSysDictionaryDetailList(c *gin.Context) { var pageInfo request.SysDictionaryDetailSearch _ = c.ShouldBindQuery(&pageInfo) if err, list, total := dictionaryDetailService.GetSysDictionaryDetailInfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/system/sys_initdb.go b/server/api/v1/system/sys_initdb.go index 0d062a99f75e4f9212d0ca4abaab682180eb418f..70645aa12269f6c609306e61c63bfca9d11a747c 100644 --- a/server/api/v1/system/sys_initdb.go +++ b/server/api/v1/system/sys_initdb.go @@ -9,9 +9,9 @@ import ( "github.com/gin-gonic/gin" ) -type DBApi struct { -} +type DBApi struct{} +// InitDB // @Tags InitDB // @Summary 初始化用户数据库 // @Produce application/json @@ -26,18 +26,19 @@ func (i *DBApi) InitDB(c *gin.Context) { } var dbInfo request.InitDB if err := c.ShouldBindJSON(&dbInfo); err != nil { - global.GVA_LOG.Error("参数校验不通过!", zap.Any("err", err)) + global.GVA_LOG.Error("参数校验不通过!", zap.Error(err)) response.FailWithMessage("参数校验不通过", c) return } if err := initDBService.InitDB(dbInfo); err != nil { - global.GVA_LOG.Error("自动创建数据库失败!", zap.Any("err", err)) + global.GVA_LOG.Error("自动创建数据库失败!", zap.Error(err)) response.FailWithMessage("自动创建数据库失败,请查看后台日志,检查后在进行初始化", c) return } response.OkWithData("自动创建数据库成功", c) } +// CheckDB // @Tags CheckDB // @Summary 初始化用户数据库 // @Produce application/json diff --git a/server/api/v1/system/sys_jwt_blacklist.go b/server/api/v1/system/sys_jwt_blacklist.go index a3ecb2dc7dc9a1e61dc65ee276e11d42e5a94c89..8d377f301972405322c1300fd4e9d2ee845736c1 100644 --- a/server/api/v1/system/sys_jwt_blacklist.go +++ b/server/api/v1/system/sys_jwt_blacklist.go @@ -8,8 +8,7 @@ import ( "go.uber.org/zap" ) -type JwtApi struct { -} +type JwtApi struct{} // @Tags Jwt // @Summary jwt加入黑名单 @@ -22,7 +21,7 @@ func (j *JwtApi) JsonInBlacklist(c *gin.Context) { token := c.Request.Header.Get("x-token") jwt := system.JwtBlacklist{Jwt: token} if err := jwtService.JsonInBlacklist(jwt); err != nil { - global.GVA_LOG.Error("jwt作废失败!", zap.Any("err", err)) + global.GVA_LOG.Error("jwt作废失败!", zap.Error(err)) response.FailWithMessage("jwt作废失败", c) } else { response.OkWithMessage("jwt作废成功", c) diff --git a/server/api/v1/system/sys_menu.go b/server/api/v1/system/sys_menu.go index d01393669f37b81bb949c52bcbe73acb05f9cf5b..dc125d6289bf37f69906c38e5ffb46f527bb2aa6 100644 --- a/server/api/v1/system/sys_menu.go +++ b/server/api/v1/system/sys_menu.go @@ -13,8 +13,7 @@ import ( "go.uber.org/zap" ) -type AuthorityMenuApi struct { -} +type AuthorityMenuApi struct{} // @Tags AuthorityMenu // @Summary 获取用户动态路由 @@ -25,7 +24,7 @@ type AuthorityMenuApi struct { // @Router /menu/getMenu [post] func (a *AuthorityMenuApi) GetMenu(c *gin.Context) { if err, menus := menuService.GetMenuTree(utils.GetUserAuthorityId(c)); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { if menus == nil { @@ -44,7 +43,7 @@ func (a *AuthorityMenuApi) GetMenu(c *gin.Context) { // @Router /menu/getBaseMenuTree [post] func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) { if err, menus := menuService.GetBaseMenuTree(); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(systemRes.SysBaseMenusResponse{Menus: menus}, "获取成功", c) @@ -67,7 +66,7 @@ func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) { return } if err := menuService.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil { - global.GVA_LOG.Error("添加失败!", zap.Any("err", err)) + global.GVA_LOG.Error("添加失败!", zap.Error(err)) response.FailWithMessage("添加失败", c) } else { response.OkWithMessage("添加成功", c) @@ -90,7 +89,7 @@ func (a *AuthorityMenuApi) GetMenuAuthority(c *gin.Context) { return } if err, menus := menuService.GetMenuAuthority(¶m); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取失败", c) } else { response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c) @@ -117,7 +116,7 @@ func (a *AuthorityMenuApi) AddBaseMenu(c *gin.Context) { return } if err := menuService.AddBaseMenu(menu); err != nil { - global.GVA_LOG.Error("添加失败!", zap.Any("err", err)) + global.GVA_LOG.Error("添加失败!", zap.Error(err)) response.FailWithMessage("添加失败", c) } else { @@ -141,7 +140,7 @@ func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) { return } if err := baseMenuService.DeleteBaseMenu(menu.ID); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -168,7 +167,7 @@ func (a *AuthorityMenuApi) UpdateBaseMenu(c *gin.Context) { return } if err := baseMenuService.UpdateBaseMenu(menu); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) @@ -191,7 +190,7 @@ func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) { return } if err, menu := baseMenuService.GetBaseMenuById(idInfo.ID); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c) @@ -214,7 +213,7 @@ func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) { return } if err, menuList, total := menuService.GetInfoList(); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/system/sys_operation_record.go b/server/api/v1/system/sys_operation_record.go index 8bf165a6502888f7277eb45ce627728f3ec2b306..89d574640b81569384030d3972655c782074904c 100644 --- a/server/api/v1/system/sys_operation_record.go +++ b/server/api/v1/system/sys_operation_record.go @@ -11,8 +11,7 @@ import ( "go.uber.org/zap" ) -type OperationRecordApi struct { -} +type OperationRecordApi struct{} // @Tags SysOperationRecord // @Summary 创建SysOperationRecord @@ -26,7 +25,7 @@ func (s *OperationRecordApi) CreateSysOperationRecord(c *gin.Context) { var sysOperationRecord system.SysOperationRecord _ = c.ShouldBindJSON(&sysOperationRecord) if err := operationRecordService.CreateSysOperationRecord(sysOperationRecord); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -45,7 +44,7 @@ func (s *OperationRecordApi) DeleteSysOperationRecord(c *gin.Context) { var sysOperationRecord system.SysOperationRecord _ = c.ShouldBindJSON(&sysOperationRecord) if err := operationRecordService.DeleteSysOperationRecord(sysOperationRecord); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -64,7 +63,7 @@ func (s *OperationRecordApi) DeleteSysOperationRecordByIds(c *gin.Context) { var IDS request.IdsReq _ = c.ShouldBindJSON(&IDS) if err := operationRecordService.DeleteSysOperationRecordByIds(IDS); err != nil { - global.GVA_LOG.Error("批量删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) response.FailWithMessage("批量删除失败", c) } else { response.OkWithMessage("批量删除成功", c) @@ -87,7 +86,7 @@ func (s *OperationRecordApi) FindSysOperationRecord(c *gin.Context) { return } if err, resysOperationRecord := operationRecordService.GetSysOperationRecord(sysOperationRecord.ID); err != nil { - global.GVA_LOG.Error("查询失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败", c) } else { response.OkWithDetailed(gin.H{"resysOperationRecord": resysOperationRecord}, "查询成功", c) @@ -106,7 +105,7 @@ func (s *OperationRecordApi) GetSysOperationRecordList(c *gin.Context) { var pageInfo systemReq.SysOperationRecordSearch _ = c.ShouldBindQuery(&pageInfo) if err, list, total := operationRecordService.GetSysOperationRecordInfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/api/v1/system/sys_system.go b/server/api/v1/system/sys_system.go index c344bac530f646f69ba0089b4b8e56380a44c0f0..970bc46bf6ec1d547dba34dfc030249c3d65b10c 100644 --- a/server/api/v1/system/sys_system.go +++ b/server/api/v1/system/sys_system.go @@ -11,8 +11,7 @@ import ( "go.uber.org/zap" ) -type SystemApi struct { -} +type SystemApi struct{} // @Tags System // @Summary 获取配置文件内容 @@ -22,7 +21,7 @@ type SystemApi struct { // @Router /system/getSystemConfig [post] func (s *SystemApi) GetSystemConfig(c *gin.Context) { if err, config := systemConfigService.GetSystemConfig(); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(systemRes.SysConfigResponse{Config: config}, "获取成功", c) @@ -40,7 +39,7 @@ func (s *SystemApi) SetSystemConfig(c *gin.Context) { var sys system.System _ = c.ShouldBindJSON(&sys) if err := systemConfigService.SetSystemConfig(sys); err != nil { - global.GVA_LOG.Error("设置失败!", zap.Any("err", err)) + global.GVA_LOG.Error("设置失败!", zap.Error(err)) response.FailWithMessage("设置失败", c) } else { response.OkWithData("设置成功", c) @@ -56,7 +55,7 @@ func (s *SystemApi) SetSystemConfig(c *gin.Context) { func (s *SystemApi) ReloadSystem(c *gin.Context) { err := utils.Reload() if err != nil { - global.GVA_LOG.Error("重启系统失败!", zap.Any("err", err)) + global.GVA_LOG.Error("重启系统失败!", zap.Error(err)) response.FailWithMessage("重启系统失败", c) } else { response.OkWithMessage("重启系统成功", c) @@ -71,7 +70,7 @@ func (s *SystemApi) ReloadSystem(c *gin.Context) { // @Router /system/getServerInfo [post] func (s *SystemApi) GetServerInfo(c *gin.Context) { if server, err := systemConfigService.GetServerInfo(); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(gin.H{"server": server}, "获取成功", c) diff --git a/server/api/v1/system/sys_user.go b/server/api/v1/system/sys_user.go index 8a59407afb09baf50a519be14bfdd5f37c9c4fa7..4815cd320e446e2e08125f75e51a817d8c1db890 100644 --- a/server/api/v1/system/sys_user.go +++ b/server/api/v1/system/sys_user.go @@ -2,7 +2,6 @@ package system import ( "strconv" - "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" @@ -12,7 +11,6 @@ import ( systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" "github.com/flipped-aurora/gin-vue-admin/server/utils" - "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" "go.uber.org/zap" @@ -34,7 +32,7 @@ func (b *BaseApi) Login(c *gin.Context) { if store.Verify(l.CaptchaId, l.Captcha, true) { u := &system.SysUser{Username: l.Username, Password: l.Password} if err, user := userService.Login(u); err != nil { - global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Any("err", err)) + global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Error(err)) response.FailWithMessage("用户名不存在或者密码错误", c) } else { b.tokenNext(c, *user) @@ -47,22 +45,16 @@ func (b *BaseApi) Login(c *gin.Context) { // 登录以后签发jwt func (b *BaseApi) tokenNext(c *gin.Context, user system.SysUser) { j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 - claims := systemReq.CustomClaims{ + claims := j.CreateClaims(systemReq.BaseClaims{ UUID: user.UUID, ID: user.ID, NickName: user.NickName, Username: user.Username, AuthorityId: user.AuthorityId, - BufferTime: global.GVA_CONFIG.JWT.BufferTime, // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失 - StandardClaims: jwt.StandardClaims{ - NotBefore: time.Now().Unix() - 1000, // 签名生效时间 - ExpiresAt: time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime, // 过期时间 7天 配置文件 - Issuer: "qmPlus", // 签名的发行者 - }, - } + }) token, err := j.CreateToken(claims) if err != nil { - global.GVA_LOG.Error("获取token失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取token失败!", zap.Error(err)) response.FailWithMessage("获取token失败", c) return } @@ -77,7 +69,7 @@ func (b *BaseApi) tokenNext(c *gin.Context, user system.SysUser) { if err, jwtStr := jwtService.GetRedisJWT(user.Username); err == redis.Nil { if err := jwtService.SetRedisJWT(token, user.Username); err != nil { - global.GVA_LOG.Error("设置登录状态失败!", zap.Any("err", err)) + global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err)) response.FailWithMessage("设置登录状态失败", c) return } @@ -87,7 +79,7 @@ func (b *BaseApi) tokenNext(c *gin.Context, user system.SysUser) { ExpiresAt: claims.StandardClaims.ExpiresAt * 1000, }, "登录成功", c) } else if err != nil { - global.GVA_LOG.Error("设置登录状态失败!", zap.Any("err", err)) + global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err)) response.FailWithMessage("设置登录状态失败", c) } else { var blackJWT system.JwtBlacklist @@ -130,7 +122,7 @@ func (b *BaseApi) Register(c *gin.Context) { user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities} err, userReturn := userService.Register(*user) if err != nil { - global.GVA_LOG.Error("注册失败!", zap.Any("err", err)) + global.GVA_LOG.Error("注册失败!", zap.Error(err)) response.FailWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册失败", c) } else { response.OkWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册成功", c) @@ -153,7 +145,7 @@ func (b *BaseApi) ChangePassword(c *gin.Context) { } u := &system.SysUser{Username: user.Username, Password: user.Password} if err, _ := userService.ChangePassword(u, user.NewPassword); err != nil { - global.GVA_LOG.Error("修改失败!", zap.Any("err", err)) + global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage("修改失败,原密码与当前账户不符", c) } else { response.OkWithMessage("修改成功", c) @@ -176,7 +168,7 @@ func (b *BaseApi) GetUserList(c *gin.Context) { return } if err, list, total := userService.GetUserInfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ @@ -206,14 +198,14 @@ func (b *BaseApi) SetUserAuthority(c *gin.Context) { userID := utils.GetUserID(c) uuid := utils.GetUserUuid(c) if err := userService.SetUserAuthority(userID, uuid, sua.AuthorityId); err != nil { - global.GVA_LOG.Error("修改失败!", zap.Any("err", err)) + global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage(err.Error(), c) } else { claims := utils.GetUserInfo(c) j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 claims.AuthorityId = sua.AuthorityId if token, err := j.CreateToken(*claims); err != nil { - global.GVA_LOG.Error("修改失败!", zap.Any("err", err)) + global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage(err.Error(), c) } else { c.Header("new-token", token) @@ -236,7 +228,7 @@ func (b *BaseApi) SetUserAuthorities(c *gin.Context) { var sua systemReq.SetUserAuthorities _ = c.ShouldBindJSON(&sua) if err := userService.SetUserAuthorities(sua.ID, sua.AuthorityIds); err != nil { - global.GVA_LOG.Error("修改失败!", zap.Any("err", err)) + global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage("修改失败", c) } else { response.OkWithMessage("修改成功", c) @@ -264,7 +256,7 @@ func (b *BaseApi) DeleteUser(c *gin.Context) { return } if err := userService.DeleteUser(reqId.ID); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -287,7 +279,7 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) { return } if err, ReqUser := userService.SetUserInfo(user); err != nil { - global.GVA_LOG.Error("设置失败!", zap.Any("err", err)) + global.GVA_LOG.Error("设置失败!", zap.Error(err)) response.FailWithMessage("设置失败", c) } else { response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c) @@ -304,9 +296,27 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) { func (b *BaseApi) GetUserInfo(c *gin.Context) { uuid := utils.GetUserUuid(c) if err, ReqUser := userService.GetUserInfo(uuid); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c) } } + +// @Tags SysUser +// @Summary 用户修改密码 +// @Security ApiKeyAuth +// @Produce application/json +// @Param data body system.SysUser true "ID" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}" +// @Router /user/resetPassword [post] +func (b *BaseApi) ResetPassword(c *gin.Context) { + var user system.SysUser + _ = c.ShouldBindJSON(&user) + if err := userService.ResetPassword(user.ID); err != nil { + global.GVA_LOG.Error("重置失败!", zap.Error(err)) + response.FailWithMessage("重置失败"+err.Error(), c) + } else { + response.OkWithMessage("重置成功", c) + } +} diff --git a/server/config.docker.yaml b/server/config.docker.yaml index 886c1b451b482a5a5cfc4af0e07536fd49381c70..71bd4cbc497d768bc930b9ae3cf9db19d65772dd 100644 --- a/server/config.docker.yaml +++ b/server/config.docker.yaml @@ -43,7 +43,7 @@ system: env: 'public' # Change to "develop" to skip authentication for development mode addr: 8888 db-type: 'mysql' - oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 + oss-type: 'local' # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 use-multipoint: false # captcha configuration @@ -55,6 +55,7 @@ captcha: # mysql connect configuration mysql: path: '' + port: '' config: '' db-name: '' username: '' @@ -81,7 +82,6 @@ autocode: server-service: /service web: /web/src web-api: /api - web-flow: /view web-form: /view web-table: /view @@ -95,7 +95,6 @@ qiniu: secret-key: '' use-cdn-domains: false - # aliyun oss configuration aliyun-oss: endpoint: 'yourEndpoint' @@ -113,11 +112,18 @@ tencent-cos: base-url: 'https://gin.vue.admin' path-prefix: 'github.com/flipped-aurora/gin-vue-admin/server' +# huawei obs configuration +hua-wei-obs: + path: 'you-path' + bucket: 'you-bucket' + endpoint: 'you-endpoint' + access-key: 'you-access-key' + secret-key: 'you-secret-key' + # excel configuration excel: dir: './resource/excel/' - # timer task db clear table Timer: start: true @@ -130,3 +136,19 @@ Timer: { tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" }, #{ tableName: "log2" , compareField: "created_at", interval: "2160h" } ] + +# 跨域配置 +# 需要配合 server/initialize/router.go#L32 使用 +cors: + mode: whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝 + whitelist: + - allow-origin: example1.com + allow-headers: content-type + allow-methods: GET, POST + expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type + allow-credentials: true # 布尔值 + - allow-origin: example2.com + allow-headers: content-type + allow-methods: GET, POST + expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type + allow-credentials: true # 布尔值 diff --git a/server/config.yaml b/server/config.yaml index 8130f1ed94dd06d559cf67dee058cc5eef8446f9..4ad8e3d62003874d556ff5563012e8dbd102b1a4 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -5,14 +5,13 @@ jwt: signing-key: 'qmPlus' expires-time: 604800 buffer-time: 86400 - + issuer: 'qmPlus' # zap logger configuration zap: level: 'info' format: 'console' prefix: '[github.com/flipped-aurora/gin-vue-admin/server]' director: 'log' - link-name: 'latest_log' show-line: true encode-level: 'LowercaseColorLevelEncoder' stacktrace-key: 'stacktrace' @@ -43,8 +42,12 @@ system: env: 'public' # Change to "develop" to skip authentication for development mode addr: 8888 db-type: 'mysql' - oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 + oss-type: 'local' # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 use-multipoint: false + # IP限制次数 一个小时15000次 + iplimit-count: 15000 + # IP限制一个小时 + iplimit-time: 3600 # captcha configuration captcha: @@ -56,14 +59,49 @@ captcha: # 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first) mysql: path: '' + port: '' config: '' db-name: '' username: '' password: '' max-idle-conns: 10 max-open-conns: 100 - log-mode: false - log-zap: "" + log-mode: "" + log-zap: false + +# pgsql connect configuration +# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first) +pgsql: + path: '' + port: '' + config: '' + db-name: '' + username: '' + password: '' + max-idle-conns: 10 + max-open-conns: 100 + log-mode: "" + log-zap: false + +db-list: [ + { + disabled: true, # 是否启用 + type: "", # 数据库的类型,目前支持mysql、pgsql + alias-name: "", # 数据库的名称,注意: alias-name 需要在db-list中唯一 + path: '', + port: '', + config: '', + db-name: '', + username: '', + password: '', + max-idle-conns: 10, + max-open-conns: 100, + log-mode: "", + log-zap: false, + } +] + + # local configuration local: @@ -72,6 +110,8 @@ local: # autocode configuration autocode: transfer-restart: true + # root 自动适配项目根目录 + # 请不要手动配置,他会在项目加载的时候识别出根路径 root: "" server: /server server-api: /api/v1/autocode @@ -82,7 +122,6 @@ autocode: server-service: /service/autocode web: /web/src web-api: /api - web-flow: /view web-form: /view web-table: /view @@ -96,7 +135,6 @@ qiniu: secret-key: '' use-cdn-domains: false - # aliyun oss configuration aliyun-oss: endpoint: 'yourEndpoint' @@ -115,11 +153,18 @@ tencent-cos: base-url: 'https://gin.vue.admin' path-prefix: 'github.com/flipped-aurora/gin-vue-admin/server' +# huawei obs configuration +hua-wei-obs: + path: 'you-path' + bucket: 'you-bucket' + endpoint: 'you-endpoint' + access-key: 'you-access-key' + secret-key: 'you-secret-key' + # excel configuration excel: dir: './resource/excel/' - # timer task db clear table Timer: start: true @@ -134,3 +179,18 @@ Timer: #{ tableName: "log2" , compareField: "created_at", interval: "2160h" } ] +# 跨域配置 +# 需要配合 server/initialize/router.go#L32 使用 +cors: + mode: whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝 + whitelist: + - allow-origin: example1.com + allow-headers: content-type + allow-methods: GET, POST + expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type + allow-credentials: true # 布尔值 + - allow-origin: example2.com + allow-headers: content-type + allow-methods: GET, POST + expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type + allow-credentials: true # 布尔值 diff --git a/server/config/auto_code.go b/server/config/auto_code.go index f941e398ca7d53a5c3b69345bbf20e5c859d86a5..4182625cec40c62468ba106b08f5b19d12cd6621 100644 --- a/server/config/auto_code.go +++ b/server/config/auto_code.go @@ -14,5 +14,4 @@ type Autocode struct { WApi string `mapstructure:"web-api" json:"webApi" yaml:"web-api"` WForm string `mapstructure:"web-form" json:"webForm" yaml:"web-form"` WTable string `mapstructure:"web-table" json:"webTable" yaml:"web-table"` - WFlow string `mapstructure:"web-flow" json:"webFlow" yaml:"web-flow"` } diff --git a/server/config/config.go b/server/config/config.go index 83d256f491668c4e0d08835a7e339a5864d1bd20..dae3571fd7428d54b3a30af0e380210b28630a14 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -11,12 +11,19 @@ type Server struct { // auto AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"` // gorm - Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` + Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` + Pgsql Pgsql `mapstructure:"pgsql" json:"pgsql" yaml:"pgsql"` + DBList []DB `mapstructure:"db-list" json:"db-list" yaml:"db-list"` // oss Local Local `mapstructure:"local" json:"local" yaml:"local"` Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"` AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyunOSS" yaml:"aliyun-oss"` + HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"huaWeiObs" yaml:"hua-wei-obs"` TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"` - Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` - Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"` + + Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` + Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"` + + // 跨域配置 + Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"` } diff --git a/server/config/cors.go b/server/config/cors.go new file mode 100644 index 0000000000000000000000000000000000000000..7fba9934697211949bcac3fcd06becdf12f431e5 --- /dev/null +++ b/server/config/cors.go @@ -0,0 +1,14 @@ +package config + +type CORS struct { + Mode string `mapstructure:"mode" json:"mode" yaml:"mode"` + Whitelist []CORSWhitelist `mapstructure:"whitelist" json:"whitelist" yaml:"whitelist"` +} + +type CORSWhitelist struct { + AllowOrigin string `mapstructure:"allow-origin" json:"allow-origin" yaml:"allow-origin"` + AllowMethods string `mapstructure:"allow-methods" json:"allow-methods" yaml:"allow-methods"` + AllowHeaders string `mapstructure:"allow-headers" json:"allow-headers" yaml:"allow-headers"` + ExposeHeaders string `mapstructure:"expose-headers" json:"expose-headers" yaml:"expose-headers"` + AllowCredentials bool `mapstructure:"allow-credentials" json:"allow-credentials" yaml:"allow-credentials"` +} diff --git a/server/config/db_list.go b/server/config/db_list.go new file mode 100644 index 0000000000000000000000000000000000000000..2933e8e4bd811aba4380e681349218bc53abcfd2 --- /dev/null +++ b/server/config/db_list.go @@ -0,0 +1,21 @@ +package config + +type DB struct { + Disable bool `mapstructure:"disable" json:"disable" yaml:"disable"` + Type string `mapstructure:"type" json:"type" yaml:"type"` + AliasName string `mapstructure:"alias-name" json:"alias-name" yaml:"alias-name"` + Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口 + Port string `mapstructure:"port" json:"port" yaml:"port"` //:端口 + Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 + Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名 + Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名 + Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码 + MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数 + MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数 + LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志 + LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` +} + +func (m *DB) Dsn() string { + return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config +} diff --git a/server/config/gorm.go b/server/config/gorm_mysql.go similarity index 80% rename from server/config/gorm.go rename to server/config/gorm_mysql.go index ae6c73843ceed7b8b9f16157945663c09f425c33..b596c29b963722d1a63f194a50713098dd833c05 100644 --- a/server/config/gorm.go +++ b/server/config/gorm_mysql.go @@ -1,7 +1,8 @@ package config type Mysql struct { - Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口 + Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址 + Port string `mapstructure:"port" json:"port" yaml:"port"` // 端口 Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名 Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名 @@ -13,5 +14,5 @@ type Mysql struct { } func (m *Mysql) Dsn() string { - return m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config + return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config } diff --git a/server/config/gorm_pgsql.go b/server/config/gorm_pgsql.go new file mode 100644 index 0000000000000000000000000000000000000000..554da8b47ad586d500d3c2c1e58f57ebedbfb150 --- /dev/null +++ b/server/config/gorm_pgsql.go @@ -0,0 +1,26 @@ +package config + +type Pgsql struct { + Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口 + Port string `mapstructure:"port" json:"port" yaml:"port"` //:端口 + Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 + Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名 + Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名 + Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码 + MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数 + MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数 + LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志 + LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` // 是否通过zap写入日志文件 +} + +// Dsn 基于配置文件获取 dsn +// Author [SliverHorn](https://github.com/SliverHorn) +func (p *Pgsql) Dsn() string { + return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + p.Dbname + " port=" + p.Port + " " + p.Config +} + +// LinkDsn 根据 dbname 生成 dsn +// Author [SliverHorn](https://github.com/SliverHorn) +func (p *Pgsql) LinkDsn(dbname string) string { + return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + dbname + " port=" + p.Port + " " + p.Config +} diff --git a/server/config/jwt.go b/server/config/jwt.go index 0ac7168fb9734f7b2b633834fcb2069840f5c52d..4f41985305709ffd46645fe45f8d9b1c86b7e4f7 100644 --- a/server/config/jwt.go +++ b/server/config/jwt.go @@ -4,4 +4,5 @@ type JWT struct { SigningKey string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"` // jwt签名 ExpiresTime int64 `mapstructure:"expires-time" json:"expiresTime" yaml:"expires-time"` // 过期时间 BufferTime int64 `mapstructure:"buffer-time" json:"bufferTime" yaml:"buffer-time"` // 缓冲时间 + Issuer string `mapstructure:"issuer" json:"issuer" yaml:"issuer"` // 签发者 } diff --git a/server/config/oss_aliyun.go b/server/config/oss_aliyun.go new file mode 100644 index 0000000000000000000000000000000000000000..519f89fcac038cc18ebbc2ba759b194c869d15cc --- /dev/null +++ b/server/config/oss_aliyun.go @@ -0,0 +1,10 @@ +package config + +type AliyunOSS struct { + Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"` + AccessKeyId string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"` + AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"` + BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"` + BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"` + BasePath string `mapstructure:"base-path" json:"basePath" yaml:"base-path"` +} diff --git a/server/config/oss_huawei.go b/server/config/oss_huawei.go new file mode 100644 index 0000000000000000000000000000000000000000..9462c0254a5d45c8815f8dded84ac782007b9b46 --- /dev/null +++ b/server/config/oss_huawei.go @@ -0,0 +1,9 @@ +package config + +type HuaWeiObs struct { + Path string `mapstructure:"path" json:"path" yaml:"path"` + Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` + Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"` + AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"` + SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` +} diff --git a/server/config/oss_local.go b/server/config/oss_local.go new file mode 100644 index 0000000000000000000000000000000000000000..5ff1f32414d824da87c5ab828f0360e7d6dfa384 --- /dev/null +++ b/server/config/oss_local.go @@ -0,0 +1,5 @@ +package config + +type Local struct { + Path string `mapstructure:"path" json:"path" yaml:"path"` // 本地文件路径 +} diff --git a/server/config/oss.go b/server/config/oss_qiniu.go similarity index 42% rename from server/config/oss.go rename to server/config/oss_qiniu.go index da6575869ebe44f0fdaba59ed8bdf319416898a3..af554b78529a35d1061f7be4c80bd1c33cb7b3c0 100644 --- a/server/config/oss.go +++ b/server/config/oss_qiniu.go @@ -1,9 +1,5 @@ package config -type Local struct { - Path string `mapstructure:"path" json:"path" yaml:"path"` // 本地文件路径 -} - type Qiniu struct { Zone string `mapstructure:"zone" json:"zone" yaml:"zone"` // 存储区域 Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` // 空间名称 @@ -13,20 +9,3 @@ type Qiniu struct { SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` // 秘钥SK UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"` // 上传是否使用CDN上传加速 } - -type AliyunOSS struct { - Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"` - AccessKeyId string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"` - AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"` - BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"` - BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"` - BasePath string `mapstructure:"base-path" json:"basePath" yaml:"base-path"` -} -type TencentCOS struct { - Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` - Region string `mapstructure:"region" json:"region" yaml:"region"` - SecretID string `mapstructure:"secret-id" json:"secretID" yaml:"secret-id"` - SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` - BaseURL string `mapstructure:"base-url" json:"baseURL" yaml:"base-url"` - PathPrefix string `mapstructure:"path-prefix" json:"pathPrefix" yaml:"path-prefix"` -} diff --git a/server/config/oss_tencent.go b/server/config/oss_tencent.go new file mode 100644 index 0000000000000000000000000000000000000000..0a7e190b234bbc048a52dd2e537fa8f125225bd0 --- /dev/null +++ b/server/config/oss_tencent.go @@ -0,0 +1,10 @@ +package config + +type TencentCOS struct { + Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` + Region string `mapstructure:"region" json:"region" yaml:"region"` + SecretID string `mapstructure:"secret-id" json:"secretID" yaml:"secret-id"` + SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` + BaseURL string `mapstructure:"base-url" json:"baseURL" yaml:"base-url"` + PathPrefix string `mapstructure:"path-prefix" json:"pathPrefix" yaml:"path-prefix"` +} diff --git a/server/config/system.go b/server/config/system.go index 768788ab0be222189f701d23ea498533877ad9dd..8cf92b060f8ea8d2b97949368618da2b943cc8ee 100644 --- a/server/config/system.go +++ b/server/config/system.go @@ -6,4 +6,6 @@ type System struct { DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"` // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"` // Oss类型 UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"` // 多点登录拦截 + LimitCountIP int `mapstructure:"iplimit-count" json:"iplimitCount" yaml:"iplimit-count"` + LimitTimeIP int `mapstructure:"iplimit-time" json:"iplimitTime" yaml:"iplimit-time"` } diff --git a/server/config/zap.go b/server/config/zap.go index f681ca837e8623526add541f8a142602857144ca..e5a00916c8c605977cf5cf39116106b17907e2b9 100644 --- a/server/config/zap.go +++ b/server/config/zap.go @@ -5,7 +5,6 @@ type Zap struct { Format string `mapstructure:"format" json:"format" yaml:"format"` // 输出 Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 日志前缀 Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹 - LinkName string `mapstructure:"link-name" json:"linkName" yaml:"link-name"` // 软链接名称 ShowLine bool `mapstructure:"show-line" json:"showLine" yaml:"showLine"` // 显示行 EncodeLevel string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level"` // 编码级 StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key"` // 栈名 diff --git a/server/core/server.go b/server/core/server.go index 96d0b68461f152958418b7da3a52e6ce41f89f4c..c0e1fc379008512688c8fe2c417df1ddf346a1ab 100644 --- a/server/core/server.go +++ b/server/core/server.go @@ -6,6 +6,7 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/initialize" + "github.com/flipped-aurora/gin-vue-admin/server/service/system" "go.uber.org/zap" ) @@ -18,6 +19,12 @@ func RunWindowsServer() { // 初始化redis服务 initialize.Redis() } + + // 从db加载jwt数据 + if global.GVA_DB != nil { + system.LoadAll() + } + Router := initialize.Routers() Router.Static("/form-generator", "./resource/page") @@ -31,8 +38,9 @@ func RunWindowsServer() { fmt.Printf(` 欢迎使用 github.com/flipped-aurora/gin-vue-admin/server - 当前版本:V2.4.5 alpha + 当前版本:V2.4.6 加群方式:微信号:shouzi_1994 QQ群:622360840 + GVA讨论社区:https://support.qq.com/products/371961 默认自动化文档地址:http://127.0.0.1%s/swagger/index.html 默认前端文件运行地址:http://127.0.0.1:8080 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/coffee diff --git a/server/core/server_other.go b/server/core/server_other.go index ce159fe34049af6144f1015f64553a3c156de056..b95e9011630a79497c5960c7e0b192e529efea41 100644 --- a/server/core/server_other.go +++ b/server/core/server_other.go @@ -4,15 +4,16 @@ package core import ( + "time" + "github.com/fvbock/endless" "github.com/gin-gonic/gin" - "time" ) func initServer(address string, router *gin.Engine) server { s := endless.NewServer(address, router) - s.ReadHeaderTimeout = 10 * time.Millisecond - s.WriteTimeout = 10 * time.Second + s.ReadHeaderTimeout = 20 * time.Second + s.WriteTimeout = 20 * time.Second s.MaxHeaderBytes = 1 << 20 return s } diff --git a/server/core/server_win.go b/server/core/server_win.go index 60fb26810dc21965e0990899007f6c02beabe82a..54c4c0768b925fbbfaca7de772a1f6005512790e 100644 --- a/server/core/server_win.go +++ b/server/core/server_win.go @@ -4,17 +4,18 @@ package core import ( - "github.com/gin-gonic/gin" "net/http" "time" + + "github.com/gin-gonic/gin" ) func initServer(address string, router *gin.Engine) server { return &http.Server{ Addr: address, Handler: router, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, + ReadTimeout: 20 * time.Second, + WriteTimeout: 20 * time.Second, MaxHeaderBytes: 1 << 20, } } diff --git a/server/core/viper.go b/server/core/viper.go index bbcfd364a2274a4298084455a1c02a1beee97fef..bf0a11a95ed8f2b4875fe335438b225eb78f4a73 100644 --- a/server/core/viper.go +++ b/server/core/viper.go @@ -7,8 +7,6 @@ import ( "path/filepath" "time" - "github.com/flipped-aurora/gin-vue-admin/server/service/system" - "github.com/songzhibin97/gkit/cache/local_cache" "github.com/flipped-aurora/gin-vue-admin/server/global" @@ -58,12 +56,11 @@ func Viper(path ...string) *viper.Viper { if err := v.Unmarshal(&global.GVA_CONFIG); err != nil { fmt.Println(err) } + // root 适配性 + // 根据root位置去找到对应迁移位置,保证root路径有效 global.GVA_CONFIG.AutoCode.Root, _ = filepath.Abs("..") global.BlackCache = local_cache.NewCache( - local_cache.SetDefaultExpire(time.Duration(global.GVA_CONFIG.JWT.ExpiresTime))) - // 从db加载jwt数据 - if global.GVA_DB != nil { - system.LoadAll() - } + local_cache.SetDefaultExpire(time.Second * time.Duration(global.GVA_CONFIG.JWT.ExpiresTime)), + ) return v } diff --git a/server/core/zap.go b/server/core/zap.go index a0f40fe76214fd5b0cfc0f526fb15a050bcd5911..1abec961b2c5f0f3af5d687f16ba7b5f6e684623 100644 --- a/server/core/zap.go +++ b/server/core/zap.go @@ -11,38 +11,36 @@ import ( "go.uber.org/zap/zapcore" ) -var level zapcore.Level - func Zap() (logger *zap.Logger) { if ok, _ := utils.PathExists(global.GVA_CONFIG.Zap.Director); !ok { // 判断是否有Director文件夹 fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director) _ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm) } + // 调试级别 + debugPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { + return lev == zap.DebugLevel + }) + // 日志级别 + infoPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { + return lev == zap.InfoLevel + }) + // 警告级别 + warnPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { + return lev == zap.WarnLevel + }) + // 错误级别 + errorPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { + return lev >= zap.ErrorLevel + }) - switch global.GVA_CONFIG.Zap.Level { // 初始化配置文件的Level - case "debug": - level = zap.DebugLevel - case "info": - level = zap.InfoLevel - case "warn": - level = zap.WarnLevel - case "error": - level = zap.ErrorLevel - case "dpanic": - level = zap.DPanicLevel - case "panic": - level = zap.PanicLevel - case "fatal": - level = zap.FatalLevel - default: - level = zap.InfoLevel + cores := [...]zapcore.Core{ + getEncoderCore(fmt.Sprintf("./%s/server_debug.log", global.GVA_CONFIG.Zap.Director), debugPriority), + getEncoderCore(fmt.Sprintf("./%s/server_info.log", global.GVA_CONFIG.Zap.Director), infoPriority), + getEncoderCore(fmt.Sprintf("./%s/server_warn.log", global.GVA_CONFIG.Zap.Director), warnPriority), + getEncoderCore(fmt.Sprintf("./%s/server_error.log", global.GVA_CONFIG.Zap.Director), errorPriority), } + logger = zap.New(zapcore.NewTee(cores[:]...), zap.AddCaller()) - if level == zap.DebugLevel || level == zap.ErrorLevel { - logger = zap.New(getEncoderCore(), zap.AddStacktrace(level)) - } else { - logger = zap.New(getEncoderCore()) - } if global.GVA_CONFIG.Zap.ShowLine { logger = logger.WithOptions(zap.AddCaller()) } @@ -88,12 +86,8 @@ func getEncoder() zapcore.Encoder { } // getEncoderCore 获取Encoder的zapcore.Core -func getEncoderCore() (core zapcore.Core) { - writer, err := utils.GetWriteSyncer() // 使用file-rotatelogs进行日志分割 - if err != nil { - fmt.Printf("Get Write Syncer Failed err:%v", err.Error()) - return - } +func getEncoderCore(fileName string, level zapcore.LevelEnabler) (core zapcore.Core) { + writer := utils.GetWriteSyncer(fileName) // 使用file-rotatelogs进行日志分割 return zapcore.NewCore(getEncoder(), writer, level) } diff --git a/server/docs/docs.go b/server/docs/docs.go index a0abd33267e6e17bcc381f2c7e1c9703fa3c325e..62955b57413652781b4692dc20b302a6c7a41406 100644 --- a/server/docs/docs.go +++ b/server/docs/docs.go @@ -3576,9 +3576,6 @@ var doc = `{ "webApi": { "type": "string" }, - "webFlow": { - "type": "string" - }, "webForm": { "type": "string" }, diff --git a/server/docs/swagger.json b/server/docs/swagger.json index 60db1a597cb50d84bb941e9a63bd973733b26808..4a5f9741916266f13c1067d9aaa2318e95b20dcd 100644 --- a/server/docs/swagger.json +++ b/server/docs/swagger.json @@ -3560,9 +3560,6 @@ "webApi": { "type": "string" }, - "webFlow": { - "type": "string" - }, "webForm": { "type": "string" }, diff --git a/server/docs/swagger.yaml b/server/docs/swagger.yaml index fae34820f16e030f1c4c44788607d58f630d8570..39944813cae300fe3143bf6fa2162c3ace39195c 100644 --- a/server/docs/swagger.yaml +++ b/server/docs/swagger.yaml @@ -54,8 +54,6 @@ definitions: type: string webApi: type: string - webFlow: - type: string webForm: type: string webTable: diff --git a/server/global/global.go b/server/global/global.go index 9093c505d9ac8c8eac72cb5cb5d2eb9aac363e9b..f00695be8e8da91e7158c64161895078e3f39d10 100644 --- a/server/global/global.go +++ b/server/global/global.go @@ -1,6 +1,8 @@ package global import ( + "sync" + "github.com/flipped-aurora/gin-vue-admin/server/utils/timer" "github.com/songzhibin97/gkit/cache/local_cache" @@ -17,13 +19,33 @@ import ( var ( GVA_DB *gorm.DB + GVA_DBList map[string]*gorm.DB GVA_REDIS *redis.Client GVA_CONFIG config.Server GVA_VP *viper.Viper - //GVA_LOG *oplogging.Logger + // GVA_LOG *oplogging.Logger GVA_LOG *zap.Logger GVA_Timer timer.Timer = timer.NewTimerTask() GVA_Concurrency_Control = &singleflight.Group{} BlackCache local_cache.Cache + lock sync.RWMutex ) + +// GetGlobalDBByDBName 通过名称获取db list中的db +func GetGlobalDBByDBName(dbname string) *gorm.DB { + lock.RLock() + defer lock.RUnlock() + return GVA_DBList[dbname] +} + +// MustGetGlobalDBByDBName 通过名称获取db 如果不存在则panic +func MustGetGlobalDBByDBName(dbname string) *gorm.DB { + lock.RLock() + defer lock.RUnlock() + db, ok := GVA_DBList[dbname] + if !ok || db == nil { + panic("db no init") + } + return db +} diff --git a/server/global/model.go b/server/global/model.go index 2e2bb706be7c27bd73ce2da1648d389da23ff7cb..2a497bd1e1e25794c2455cc0a2c6832335b8f946 100644 --- a/server/global/model.go +++ b/server/global/model.go @@ -1,8 +1,9 @@ package global import ( - "gorm.io/gorm" "time" + + "gorm.io/gorm" ) type GVA_MODEL struct { diff --git a/server/go.mod b/server/go.mod index 58369fe16fbe9fea19cd5419d3442771d403b51d..02feb48366282c742aecd34de8a3da5cbe13111a 100644 --- a/server/go.mod +++ b/server/go.mod @@ -16,23 +16,29 @@ require ( github.com/go-redis/redis/v8 v8.11.0 github.com/go-sql-driver/mysql v1.5.0 github.com/gookit/color v1.3.1 + github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 - github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible github.com/mojocn/base64Captcha v1.3.1 + github.com/natefinch/lumberjack v2.0.0+incompatible + github.com/pkg/errors v0.9.1 github.com/qiniu/api.v7/v7 v7.4.1 github.com/robfig/cron/v3 v3.0.1 github.com/satori/go.uuid v1.2.0 - github.com/shirou/gopsutil v3.21.1+incompatible + github.com/shirou/gopsutil v3.21.9+incompatible github.com/songzhibin97/gkit v1.1.1 github.com/spf13/viper v1.7.0 + github.com/stretchr/testify v1.7.0 github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/swag v1.7.0 github.com/tencentyun/cos-go-sdk-v5 v0.7.19 + github.com/tklauser/go-sysconf v0.3.9 // indirect github.com/unrolled/secure v1.0.7 github.com/xuri/excelize/v2 v2.4.1 go.uber.org/zap v1.16.0 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gorm.io/driver/mysql v1.0.1 - gorm.io/gorm v1.20.7 + gorm.io/driver/postgres v0.2.6 + gorm.io/gorm v1.20.11 nhooyr.io/websocket v1.8.6 ) diff --git a/server/go.sum b/server/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..00f68f1f69022ab44c738944ca9b8ebbc011cac8 --- /dev/null +++ b/server/go.sum @@ -0,0 +1,787 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4= +github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= +github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/casbin/casbin/v2 v2.2.2/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8= +github.com/casbin/casbin/v2 v2.11.0 h1:6M/sWT9gh2pUcL541be/rllWEVxcEV6wdg1t7MN6fHQ= +github.com/casbin/casbin/v2 v2.11.0/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8= +github.com/casbin/gorm-adapter/v3 v3.0.2 h1:4F2VFElwPyFzvHfgwizD2JQxk2OFLwvRFZct1np0yBg= +github.com/casbin/gorm-adapter/v3 v3.0.2/go.mod h1:mQI09sqvXfy5p6kZB5HBzZrgKWwxaJ4xMWpd5OGfHRY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY= +github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= +github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/emicklei/proto v1.9.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/flipped-aurora/gin-vue-admin/server v0.0.0-20210823151324-f5410430faf0/go.mod h1:ksHCxOjTTQDk1Y1MrptfG6e9+s3rDJzQXkIZBHl8sws= +github.com/flipped-aurora/gva-plugins v0.0.0-20210828060501-fc8b729b9a4a h1:GEU1KU8lvWWwvHNTXaoVxonsp8t120oFQnlpAtGqKpM= +github.com/flipped-aurora/gva-plugins v0.0.0-20210828060501-fc8b729b9a4a/go.mod h1:/DpDUj/vphN4x3UaTDhTvT6aZaCasfKOGbMgPabwGv0= +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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc= +github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= +github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= +github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +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.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA= +github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ= +github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o= +github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-redis/redis/v8 v8.11.0 h1:O1Td0mQ8UFChQ3N9zFQqo6kTU2cJ+/it88gDB+zg0wo= +github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/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 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gookit/color v1.3.1 h1:PPD/C7sf8u2L8XQPdPgsWRoAiLQGZEZOzU3cf5IYYUk= +github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible h1:3kDd8PIWAdU+qGs/+0QUgsMI2ZSiJPt45Xn0su+x/Q0= +github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.6.1 h1:lwofaXKPbIx6qEaK8mNm7uZuOwxHw+PnAFGDsDFpkRI= +github.com/jackc/pgconn v1.6.1/go.mod h1:g8mKMqmSUO6AzAvha7vy07g1rbGOlc7iF0nU0ei83hc= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +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/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.2 h1:q1Hsy66zh4vuNsajBUF2PNqfAMMfxU5mk594lPE9vjY= +github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 h1:Q3tB+ExeflWUW7AFcAhXqk40s9mnNYLk1nOkKNZ5GnU= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.4.0 h1:pHQfb4jh9iKqHyxPthq1fr+0HwSNIl3btYPbw2m2lbM= +github.com/jackc/pgtype v1.4.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.7.1 h1:aqUSOcStk6fik+lSE+tqfFhvt/EwT8q/oMtJbP9CjXI= +github.com/jackc/pgx/v4 v4.7.1/go.mod h1:nu42q3aPjuC1M0Nak4bnoprKlXPINqopEKqbq5AZSC4= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 h1:pS0A6cr4aHYZnYwC7Uw+rwgb39+nzkm2QhwZ+S6Gn5I= +github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +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/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= +github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= +github.com/lestrrat-go/strftime v1.0.3/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= +github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +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.1 h1:2Wbkt8Oc8qjmNJ5GyOfSo4tgVQPsbKMftqASnq8GlT0= +github.com/mojocn/base64Captcha v1.3.1/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY= +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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= +github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= +github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= +github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +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= +github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= +github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +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/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.21.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.21.9+incompatible h1:LTLpUnfX81MkHeCtSrwNKZwuW5Id6kCa7/P43NdcNn4= +github.com/shirou/gopsutil v3.21.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/songzhibin97/gkit v1.1.1 h1:RmnCBLA7+OY40VEa2Uf2nGfbIMs4/5QT6tXDEHsMXiQ= +github.com/songzhibin97/gkit v1.1.1/go.mod h1:V4E7H6DQuxX17xpLOqyH1j51GQctKBIIV3i2r5xkE5s= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= +github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= +github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= +github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= +github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E= +github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= +github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= +github.com/tencentyun/cos-go-sdk-v5 v0.7.19 h1:janAfTO4MglOrUFuKGTQJBuMc66+F7TgtEIt1wPsJ+k= +github.com/tencentyun/cos-go-sdk-v5 v0.7.19/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA= +github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= +github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= +github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= +github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= +github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= +github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= +github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= +github.com/unrolled/secure v1.0.7 h1:BcQHp3iKZyZCKj5gRqwQG+5urnGBF00wGgoPPwtheVQ= +github.com/unrolled/secure v1.0.7/go.mod h1:uGc1OcRF8gCVBA+ANksKmvM85Hka6SZtQIbrKc3sHS4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o= +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.4.1 h1:veeeFLAJwsNEBPBlDepzPIYS1eLyBVcXNZUW79exZ1E= +github.com/xuri/excelize/v2 v2.4.1/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= +go.opentelemetry.io/otel/sdk v1.0.0-RC2/go.mod h1:fgwHyiDn4e5k40TD9VX243rOxXR+jzsWBZYA2P5jpEw= +go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +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= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +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.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +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= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +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= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71 h1:ikCpsnYR+Ew0vu99XlDp55lGgDJdIMx3f4a18jfse/s= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +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-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ= +gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v0.3.0/go.mod h1:A7H1JD9dKdcjeUTpTuWKEC+E1a74qzW7/zaXqKaTbfM= +gorm.io/driver/mysql v1.0.1 h1:omJoilUzyrAp0xNoio88lGJCroGdIOen9hq2A/+3ifw= +gorm.io/driver/mysql v1.0.1/go.mod h1:KtqSthtg55lFp3S5kUXqlGaelnWpKitn4k1xZTnoiPw= +gorm.io/driver/postgres v0.2.6 h1:hoE6SzA5wKOo6AYxz2V7ooxnzD6S6ToLAHHDDawt+b0= +gorm.io/driver/postgres v0.2.6/go.mod h1:AsPyuhKFOplSmQwOPsycVKbe0dRxF8v18KZ7p9i8dIs= +gorm.io/driver/sqlserver v0.2.4 h1:AGofGL/TfzTZotzIHlaLISfxEKJpzj0ATbtXJW+ga1A= +gorm.io/driver/sqlserver v0.2.4/go.mod h1:TcPfkdce5b8qlCMgyUeUdm7HQa1ZzWUuxzI+odcueLA= +gorm.io/gorm v0.2.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v0.2.23/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.9.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.20.11 h1:jYHQ0LLUViV85V8dM1TP9VBBkfzKTnuTXDjYObkI6yc= +gorm.io/gorm v1.20.11/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/server/initialize/db_list.go b/server/initialize/db_list.go new file mode 100644 index 0000000000000000000000000000000000000000..d976b12c9e9af283d8b61e00afbee776440fc2ed --- /dev/null +++ b/server/initialize/db_list.go @@ -0,0 +1,31 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + "gorm.io/gorm" +) + +const sys = "system" + +func DBList() { + dbMap := make(map[string]*gorm.DB) + for _, info := range global.GVA_CONFIG.DBList { + if info.Disable { + continue + } + switch info.Type { + case "mysql": + dbMap[info.Dbname] = GormMysqlByConfig(info) + case "pgsql": + dbMap[info.Dbname] = GormPgSqlByConfig(info) + default: + continue + } + } + // 做特殊判断,是否有迁移 + // 适配低版本迁移多数据库版本 + if sysDB, ok := dbMap[sys]; ok { + global.GVA_DB = sysDB + } + global.GVA_DBList = dbMap +} diff --git a/server/initialize/gorm.go b/server/initialize/gorm.go index fbbab797fd4f8702e8d47cb68aa019c067acd680..3657832dd94d981f94eeb71216aac9ecd3f8b15b 100644 --- a/server/initialize/gorm.go +++ b/server/initialize/gorm.go @@ -4,115 +4,57 @@ import ( "os" "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/initialize/internal" "github.com/flipped-aurora/gin-vue-admin/server/model/autocode" "github.com/flipped-aurora/gin-vue-admin/server/model/example" "github.com/flipped-aurora/gin-vue-admin/server/model/system" "go.uber.org/zap" - "gorm.io/driver/mysql" "gorm.io/gorm" - "gorm.io/gorm/logger" ) -//@author: SliverHorn -//@function: Gorm -//@description: 初始化数据库并产生数据库全局变量 -//@return: *gorm.DB - +// Gorm 初始化数据库并产生数据库全局变量 +// Author SliverHorn func Gorm() *gorm.DB { switch global.GVA_CONFIG.System.DbType { case "mysql": return GormMysql() + case "pgsql": + return GormPgSql() default: return GormMysql() } } -// MysqlTables -//@author: SliverHorn -//@function: MysqlTables -//@description: 注册数据库表专用 -//@param: db *gorm.DB - -func MysqlTables(db *gorm.DB) { +// RegisterTables 注册数据库表专用 +// Author SliverHorn +func RegisterTables(db *gorm.DB) { err := db.AutoMigrate( - system.SysUser{}, - system.SysAuthority{}, + // 系统模块表 system.SysApi{}, + system.SysUser{}, system.SysBaseMenu{}, - system.SysBaseMenuParameter{}, system.JwtBlacklist{}, + system.SysAuthority{}, system.SysDictionary{}, + system.SysOperationRecord{}, + system.SysAutoCodeHistory{}, system.SysDictionaryDetail{}, - example.ExaFileUploadAndDownload{}, + system.SysBaseMenuParameter{}, + + // 示例模块表 example.ExaFile{}, - example.ExaFileChunk{}, example.ExaCustomer{}, - system.SysOperationRecord{}, - system.SysAutoCodeHistory{}, + example.ExaFileChunk{}, + example.ExaFileUploadAndDownload{}, + + // 自动化模块表 // Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT. autocode.AutoCodeExample{}, // Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT. ) if err != nil { - global.GVA_LOG.Error("register table failed", zap.Any("err", err)) + global.GVA_LOG.Error("register table failed", zap.Error(err)) os.Exit(0) } global.GVA_LOG.Info("register table success") } - -//@author: SliverHorn -//@function: GormMysql -//@description: 初始化Mysql数据库 -//@return: *gorm.DB - -func GormMysql() *gorm.DB { - m := global.GVA_CONFIG.Mysql - if m.Dbname == "" { - return nil - } - dsn := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config - mysqlConfig := mysql.Config{ - DSN: dsn, // DSN data source name - DefaultStringSize: 191, // string 类型字段的默认长度 - DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持 - DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引 - DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列 - SkipInitializeWithVersion: false, // 根据版本自动配置 - } - if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig()); err != nil { - //global.GVA_LOG.Error("MySQL启动异常", zap.Any("err", err)) - //os.Exit(0) - //return nil - return nil - } else { - sqlDB, _ := db.DB() - sqlDB.SetMaxIdleConns(m.MaxIdleConns) - sqlDB.SetMaxOpenConns(m.MaxOpenConns) - return db - } -} - -//@author: SliverHorn -//@function: gormConfig -//@description: 根据配置决定是否开启日志 -//@param: mod bool -//@return: *gorm.Config - -func gormConfig() *gorm.Config { - config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true} - switch global.GVA_CONFIG.Mysql.LogMode { - case "silent", "Silent": - config.Logger = internal.Default.LogMode(logger.Silent) - case "error", "Error": - config.Logger = internal.Default.LogMode(logger.Error) - case "warn", "Warn": - config.Logger = internal.Default.LogMode(logger.Warn) - case "info", "Info": - config.Logger = internal.Default.LogMode(logger.Info) - default: - config.Logger = internal.Default.LogMode(logger.Info) - } - return config -} diff --git a/server/initialize/gorm_mysql.go b/server/initialize/gorm_mysql.go new file mode 100644 index 0000000000000000000000000000000000000000..4c8b6e6f7afdc5a0f6e4a8f28ad56f12562ccac2 --- /dev/null +++ b/server/initialize/gorm_mysql.go @@ -0,0 +1,52 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/config" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/initialize/internal" + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +// GormMysql 初始化Mysql数据库 +// Author [piexlmax](https://github.com/piexlmax) +// Author [SliverHorn](https://github.com/SliverHorn) +func GormMysql() *gorm.DB { + m := global.GVA_CONFIG.Mysql + if m.Dbname == "" { + return nil + } + mysqlConfig := mysql.Config{ + DSN: m.Dsn(), // DSN data source name + DefaultStringSize: 191, // string 类型字段的默认长度 + SkipInitializeWithVersion: false, // 根据版本自动配置 + } + if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil { + return nil + } else { + sqlDB, _ := db.DB() + sqlDB.SetMaxIdleConns(m.MaxIdleConns) + sqlDB.SetMaxOpenConns(m.MaxOpenConns) + return db + } +} + +// GormMysqlByConfig 初始化Mysql数据库用过传入配置 +func GormMysqlByConfig(m config.DB) *gorm.DB { + if m.Dbname == "" { + return nil + } + mysqlConfig := mysql.Config{ + DSN: m.Dsn(), // DSN data source name + DefaultStringSize: 191, // string 类型字段的默认长度 + SkipInitializeWithVersion: false, // 根据版本自动配置 + } + if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil { + panic(err) + } else { + sqlDB, _ := db.DB() + sqlDB.SetMaxIdleConns(m.MaxIdleConns) + sqlDB.SetMaxOpenConns(m.MaxOpenConns) + return db + } +} diff --git a/server/initialize/gorm_pgsql.go b/server/initialize/gorm_pgsql.go new file mode 100644 index 0000000000000000000000000000000000000000..e474b981870e1c9685be94333229532eb73705af --- /dev/null +++ b/server/initialize/gorm_pgsql.go @@ -0,0 +1,50 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/config" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/initialize/internal" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +// GormPgSql 初始化 Postgresql 数据库 +// Author [piexlmax](https://github.com/piexlmax) +// Author [SliverHorn](https://github.com/SliverHorn) +func GormPgSql() *gorm.DB { + p := global.GVA_CONFIG.Pgsql + if p.Dbname == "" { + return nil + } + pgsqlConfig := postgres.Config{ + DSN: p.Dsn(), // DSN data source name + PreferSimpleProtocol: false, + } + if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil { + return nil + } else { + sqlDB, _ := db.DB() + sqlDB.SetMaxIdleConns(p.MaxIdleConns) + sqlDB.SetMaxOpenConns(p.MaxOpenConns) + return db + } +} + +// GormPgSqlByConfig 初始化 Postgresql 数据库 通过参数 +func GormPgSqlByConfig(p config.DB) *gorm.DB { + if p.Dbname == "" { + return nil + } + pgsqlConfig := postgres.Config{ + DSN: p.Dsn(), // DSN data source name + PreferSimpleProtocol: false, + } + if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil { + panic(err) + } else { + sqlDB, _ := db.DB() + sqlDB.SetMaxIdleConns(p.MaxIdleConns) + sqlDB.SetMaxOpenConns(p.MaxOpenConns) + return db + } +} diff --git a/server/initialize/internal/gorm.go b/server/initialize/internal/gorm.go new file mode 100644 index 0000000000000000000000000000000000000000..ebfdfda9f3975c8919b0dd6b34bd9522ff30a76f --- /dev/null +++ b/server/initialize/internal/gorm.go @@ -0,0 +1,39 @@ +package internal + +import ( + "log" + "os" + "time" + + "github.com/flipped-aurora/gin-vue-admin/server/global" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +var Gorm = new(_gorm) + +type _gorm struct{} + +// Config gorm 自定义配置 +// Author [SliverHorn](https://github.com/SliverHorn) +func (g *_gorm) Config() *gorm.Config { + config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true} + _default := logger.New(NewWriter(log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{ + SlowThreshold: 200 * time.Millisecond, + LogLevel: logger.Warn, + Colorful: true, + }) + switch global.GVA_CONFIG.Mysql.LogMode { + 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 +} diff --git a/server/initialize/internal/logger.go b/server/initialize/internal/logger.go index 25b7b8ca24a4b41a1463dd1ba9c31ba956f556ab..f8d2f34ef1bb108ea4788660ed3710c30f64976d 100644 --- a/server/initialize/internal/logger.go +++ b/server/initialize/internal/logger.go @@ -1,153 +1,35 @@ package internal import ( - "context" "fmt" - "io/ioutil" - "log" - "os" - "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "gorm.io/gorm/logger" - "gorm.io/gorm/utils" ) -type config struct { - SlowThreshold time.Duration - Colorful bool - LogLevel logger.LogLevel -} - -var ( - Discard = New(log.New(ioutil.Discard, "", log.LstdFlags), config{}) - Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), config{ - SlowThreshold: 200 * time.Millisecond, - LogLevel: logger.Warn, - Colorful: true, - }) - Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()} -) - -func New(writer logger.Writer, config config) logger.Interface { - var ( - infoStr = "%s\n[info] " - warnStr = "%s\n[warn] " - errStr = "%s\n[error] " - traceStr = "%s\n[%.3fms] [rows:%v] %s\n" - traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s\n" - traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s\n" - ) - - if config.Colorful { - infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset - warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset - errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset - traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s\n" - traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s\n" + logger.Reset - traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s\n" - } - - return &_logger{ - Writer: writer, - config: config, - infoStr: infoStr, - warnStr: warnStr, - errStr: errStr, - traceStr: traceStr, - traceWarnStr: traceWarnStr, - traceErrStr: traceErrStr, - } -} - -type _logger struct { - config +type writer struct { logger.Writer - infoStr, warnStr, errStr string - traceStr, traceErrStr, traceWarnStr string } -// LogMode log mode -func (c *_logger) LogMode(level logger.LogLevel) logger.Interface { - newLogger := *c - newLogger.LogLevel = level - return &newLogger +// NewWriter writer 构造函数 +// Author [SliverHorn](https://github.com/SliverHorn) +func NewWriter(w logger.Writer) *writer { + return &writer{Writer: w} } -// Info print info -func (c *_logger) Info(ctx context.Context, message string, data ...interface{}) { - if c.LogLevel >= logger.Info { - c.Printf(c.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) +// 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 } -} - -// Warn print warn messages -func (c *_logger) Warn(ctx context.Context, message string, data ...interface{}) { - if c.LogLevel >= logger.Warn { - c.Printf(c.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) - } -} - -// Error print error messages -func (c *_logger) Error(ctx context.Context, message string, data ...interface{}) { - if c.LogLevel >= logger.Error { - c.Printf(c.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) - } -} - -// Trace print sql message -func (c *_logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { - if c.LogLevel > 0 { - elapsed := time.Since(begin) - switch { - case err != nil && c.LogLevel >= logger.Error: - sql, rows := fc() - if rows == -1 { - c.Printf(c.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) - } else { - c.Printf(c.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) - } - case elapsed > c.SlowThreshold && c.SlowThreshold != 0 && c.LogLevel >= logger.Warn: - sql, rows := fc() - slowLog := fmt.Sprintf("SLOW SQL >= %v", c.SlowThreshold) - if rows == -1 { - c.Printf(c.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) - } else { - c.Printf(c.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) - } - case c.LogLevel >= logger.Info: - sql, rows := fc() - if rows == -1 { - c.Printf(c.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) - } else { - c.Printf(c.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) - } - } - } -} - -func (c *_logger) Printf(message string, data ...interface{}) { - if global.GVA_CONFIG.Mysql.LogZap { - global.GVA_LOG.Info(fmt.Sprintf(message, data...)) + if logZap { + global.GVA_LOG.Info(fmt.Sprintf(message+"\n", data...)) } else { - c.Writer.Printf(message, data...) + w.Writer.Printf(message, data...) } } - -type traceRecorder struct { - logger.Interface - BeginAt time.Time - SQL string - RowsAffected int64 - Err error -} - -func (t traceRecorder) New() *traceRecorder { - return &traceRecorder{Interface: t.Interface, BeginAt: time.Now()} -} - -func (t *traceRecorder) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { - t.BeginAt = begin - t.SQL, t.RowsAffected = fc() - t.Err = err -} diff --git a/server/initialize/plugin.go b/server/initialize/plugin.go index 69b8a1af1f805931a37f8b7b8ea908e994a0ddbc..2181acb3259dfb6650b8aab48af80d83760b434c 100644 --- a/server/initialize/plugin.go +++ b/server/initialize/plugin.go @@ -31,5 +31,4 @@ func InstallPlugin(PublicGroup *gin.RouterGroup, PrivateGroup *gin.RouterGroup) global.GVA_CONFIG.Email.Port, global.GVA_CONFIG.Email.IsSSL, )) - } diff --git a/server/initialize/redis.go b/server/initialize/redis.go index afc2868ee7836f90c6737fa7a350950c796dd744..f52829b37744d538992dc9ff82c31fddb6c49289 100644 --- a/server/initialize/redis.go +++ b/server/initialize/redis.go @@ -18,7 +18,7 @@ func Redis() { }) pong, err := client.Ping(context.Background()).Result() if err != nil { - global.GVA_LOG.Error("redis connect ping failed, err:", zap.Any("err", err)) + global.GVA_LOG.Error("redis connect ping failed, err:", zap.Error(err)) } else { global.GVA_LOG.Info("redis connect ping response:", zap.String("pong", pong)) global.GVA_REDIS = client diff --git a/server/initialize/router.go b/server/initialize/router.go index 000f33a29076e3687d81fe205c0f5309927fae5f..853cbb0c12c35ed7623b36a7bb9dd3e012ceb664 100644 --- a/server/initialize/router.go +++ b/server/initialize/router.go @@ -15,32 +15,39 @@ import ( // 初始化总路由 func Routers() *gin.Engine { - var Router = gin.Default() + Router := gin.Default() // 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的 // VUE_APP_BASE_API = / // VUE_APP_BASE_PATH = http://localhost // 然后执行打包命令 npm run build。在打开下面4行注释 - //Router.LoadHTMLGlob("./dist/*.html") // npm打包成dist的路径 - //Router.Static("/favicon.ico", "./dist/favicon.ico") - //Router.Static("/static", "./dist/static") // dist里面的静态资源 - //Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面 + // Router.LoadHTMLGlob("./dist/*.html") // npm打包成dist的路径 + // Router.Static("/favicon.ico", "./dist/favicon.ico") + // Router.Static("/static", "./dist/assets") // dist里面的静态资源 + // Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面 Router.StaticFS(global.GVA_CONFIG.Local.Path, http.Dir(global.GVA_CONFIG.Local.Path)) // 为用户头像和文件提供静态地址 // Router.Use(middleware.LoadTls()) // 打开就能玩https了 global.GVA_LOG.Info("use middleware logger") - // 跨域 - //Router.Use(middleware.Cors()) // 如需跨域可以打开 + // 跨域,如需跨域可以打开下面的注释 + // Router.Use(middleware.Cors()) // 直接放行全部跨域请求 + //Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求 global.GVA_LOG.Info("use middleware cors") Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) global.GVA_LOG.Info("register swagger handler") // 方便统一添加路由组前缀 多服务器上线使用 - //获取路由组实例 + // 获取路由组实例 systemRouter := router.RouterGroupApp.System exampleRouter := router.RouterGroupApp.Example autocodeRouter := router.RouterGroupApp.Autocode PublicGroup := Router.Group("") + { + // 健康监测 + PublicGroup.GET("/health", func(c *gin.Context) { + c.JSON(200, "ok") + }) + } { systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权 systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关 @@ -48,20 +55,22 @@ func Routers() *gin.Engine { PrivateGroup := Router.Group("") PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) { - systemRouter.InitApiRouter(PrivateGroup) // 注册功能api路由 - systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由 - systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由 - systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由 - systemRouter.InitSystemRouter(PrivateGroup) // system相关路由 - systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由 - systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码 - systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由 - systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理 - systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 - systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 - exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 + systemRouter.InitApiRouter(PrivateGroup) // 注册功能api路由 + systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由 + systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由 + systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由 + systemRouter.InitSystemRouter(PrivateGroup) // system相关路由 + systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由 + systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码 + systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由 + systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理 + systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史 + systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 + systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 + exampleRouter.InitExcelRouter(PrivateGroup) // 表格导入导出 exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由 + exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 // Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT. autocodeRouter.InitSysAutoCodeExampleRouter(PrivateGroup) diff --git a/server/main.go b/server/main.go index c82e084bfbd7afcf0420ab6e5d05cd72f29a0c84..cdcab9ed3cd54d2823286418f50b60e6db351985 100644 --- a/server/main.go +++ b/server/main.go @@ -23,8 +23,9 @@ func main() { global.GVA_LOG = core.Zap() // 初始化zap日志库 global.GVA_DB = initialize.Gorm() // gorm连接数据库 initialize.Timer() + initialize.DBList() if global.GVA_DB != nil { - initialize.MysqlTables(global.GVA_DB) // 初始化表 + initialize.RegisterTables(global.GVA_DB) // 初始化表 // 程序结束前关闭数据库链接 db, _ := global.GVA_DB.DB() defer db.Close() diff --git a/server/middleware/casbin_rbac.go b/server/middleware/casbin_rbac.go index 05bba88c815f93248dc1ce60801a06e3cca8ca41..ea9c9824f0a408f16f09840f487078895a86dd1c 100644 --- a/server/middleware/casbin_rbac.go +++ b/server/middleware/casbin_rbac.go @@ -3,8 +3,8 @@ package middleware import ( "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" - "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" "github.com/flipped-aurora/gin-vue-admin/server/service" + "github.com/flipped-aurora/gin-vue-admin/server/utils" "github.com/gin-gonic/gin" ) @@ -13,10 +13,9 @@ var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService // 拦截器 func CasbinHandler() gin.HandlerFunc { return func(c *gin.Context) { - claims, _ := c.Get("claims") - waitUse := claims.(*request.CustomClaims) - // 获取请求的URI - obj := c.Request.URL.RequestURI() + waitUse, _ := utils.GetClaims(c) + // 获取请求的PATH + obj := c.Request.URL.Path // 获取请求方法 act := c.Request.Method // 获取用户的角色 diff --git a/server/middleware/cors.go b/server/middleware/cors.go index 68f6651f75e233f9d811645c4372d2b08d15825f..99664b7ee4bc9a879e83d72472be51e05fef8d03 100644 --- a/server/middleware/cors.go +++ b/server/middleware/cors.go @@ -1,11 +1,13 @@ package middleware import ( + "github.com/flipped-aurora/gin-vue-admin/server/config" + "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/gin-gonic/gin" "net/http" ) -// 处理跨域请求,支持options访问 +// Cors 直接放行所有跨域请求并放行所有 OPTIONS 方法 func Cors() gin.HandlerFunc { return func(c *gin.Context) { method := c.Request.Method @@ -24,3 +26,48 @@ func Cors() gin.HandlerFunc { c.Next() } } + +// CorsByRules 按照配置处理跨域请求 +func CorsByRules() gin.HandlerFunc { + // 放行全部 + if global.GVA_CONFIG.Cors.Mode == "allow-all" { + return Cors() + } + return func(c *gin.Context) { + whitelist := checkCors(c.GetHeader("origin")) + + // 通过检查, 添加请求头 + if whitelist != nil { + c.Header("Access-Control-Allow-Origin", whitelist.AllowOrigin) + c.Header("Access-Control-Allow-Headers", whitelist.AllowHeaders) + c.Header("Access-Control-Allow-Methods", whitelist.AllowMethods) + c.Header("Access-Control-Expose-Headers", whitelist.ExposeHeaders) + if whitelist.AllowCredentials { + c.Header("Access-Control-Allow-Credentials", "true") + } + } + + // 严格白名单模式且未通过检查,直接拒绝处理请求 + if whitelist == nil && global.GVA_CONFIG.Cors.Mode == "strict-whitelist" && !(c.Request.Method == "GET" && c.Request.URL.Path == "/health") { + c.AbortWithStatus(http.StatusForbidden) + } else { + // 非严格白名单模式,无论是否通过检查均放行所有 OPTIONS 方法 + if c.Request.Method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + } + } + + // 处理请求 + c.Next() + } +} + +func checkCors(currentOrigin string) *config.CORSWhitelist { + for _, whitelist := range global.GVA_CONFIG.Cors.Whitelist { + // 遍历配置中的跨域头,寻找匹配项 + if currentOrigin == whitelist.AllowOrigin { + return &whitelist + } + } + return nil +} diff --git a/server/middleware/email.go b/server/middleware/email.go index 9ba328b9170da6b3c108ef72d3f126c404bddea8..5879c99393233278a6d0661c67967d8caac5d549 100644 --- a/server/middleware/email.go +++ b/server/middleware/email.go @@ -1,14 +1,15 @@ package middleware import ( - "github.com/flipped-aurora/gin-vue-admin/server/plugin/email/utils" "io/ioutil" "strconv" "time" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/email/utils" + utils2 "github.com/flipped-aurora/gin-vue-admin/server/utils" + "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/model/system/request" "github.com/flipped-aurora/gin-vue-admin/server/service" "github.com/gin-gonic/gin" "go.uber.org/zap" @@ -19,9 +20,9 @@ var userService = service.ServiceGroupApp.SystemServiceGroup.UserService func ErrorToEmail() gin.HandlerFunc { return func(c *gin.Context) { var username string - if claims, ok := c.Get("claims"); ok { - waitUse := claims.(*request.CustomClaims) - username = waitUse.Username + claims, _ := utils2.GetClaims(c) + if claims.Username != "" { + username = claims.Username } else { id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id")) err, user := userService.FindUserById(id) @@ -42,14 +43,14 @@ func ErrorToEmail() gin.HandlerFunc { c.Next() - latency := time.Now().Sub(now) + latency := time.Since(now) status := c.Writer.Status() record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String() str := "接收到的请求为" + record.Body + "\n" + "请求方式为" + record.Method + "\n" + "报错信息如下" + record.ErrorMessage + "\n" + "耗时" + latency.String() + "\n" if status != 200 { subject := username + "" + record.Ip + "调用了" + record.Path + "报错了" if err := utils.ErrorToEmail(subject, str); err != nil { - global.GVA_LOG.Error("ErrorToEmail Failed, err:", zap.Any("err", err)) + global.GVA_LOG.Error("ErrorToEmail Failed, err:", zap.Error(err)) } } } diff --git a/server/middleware/jwt.go b/server/middleware/jwt.go index 576a3da4be0a640f73b6748df21d006c6f2842fc..46eba16678141488df688638710a09aa67a3f656 100644 --- a/server/middleware/jwt.go +++ b/server/middleware/jwt.go @@ -1,10 +1,11 @@ package middleware import ( - "github.com/flipped-aurora/gin-vue-admin/server/utils" "strconv" "time" + "github.com/flipped-aurora/gin-vue-admin/server/utils" + "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" "github.com/flipped-aurora/gin-vue-admin/server/model/system" @@ -58,7 +59,7 @@ func JWTAuth() gin.HandlerFunc { if global.GVA_CONFIG.System.UseMultipoint { err, RedisJwtToken := jwtService.GetRedisJWT(newClaims.Username) if err != nil { - global.GVA_LOG.Error("get redis jwt failed", zap.Any("err", err)) + global.GVA_LOG.Error("get redis jwt failed", zap.Error(err)) } else { // 当之前的取成功时才进行拉黑操作 _ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken}) } diff --git a/server/middleware/limit_ip.go b/server/middleware/limit_ip.go new file mode 100644 index 0000000000000000000000000000000000000000..315010b2238f3d1f6a90f227db407822a06e0883 --- /dev/null +++ b/server/middleware/limit_ip.go @@ -0,0 +1,92 @@ +package middleware + +import ( + "context" + "errors" + "net/http" + "time" + + "go.uber.org/zap" + + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" + "github.com/gin-gonic/gin" +) + +type LimitConfig struct { + // GenerationKey 根据业务生成key 下面CheckOrMark查询生成 + GenerationKey func(c *gin.Context) string + // 检查函数,用户可修改具体逻辑,更加灵活 + CheckOrMark func(key string, expire int, limit int) error + // Expire key 过期时间 + Expire int + // Limit 周期时间 + Limit int +} + +func (l LimitConfig) LimitWithTime() gin.HandlerFunc { + return func(c *gin.Context) { + if err := l.CheckOrMark(l.GenerationKey(c), l.Expire, l.Limit); err != nil { + c.JSON(http.StatusOK, gin.H{"code": response.ERROR, "msg": err}) + c.Abort() + return + } else { + c.Next() + } + } +} + +// DefaultGenerationKey 默认生成key +func DefaultGenerationKey(c *gin.Context) string { + return "GVA_Limit" + c.ClientIP() +} + +func DefaultCheckOrMark(key string, expire int, limit int) (err error) { + // 判断是否开启redis + if global.GVA_REDIS == nil { + return err + } + if err = SetLimitWithTime(key, limit, time.Duration(expire)*time.Second); err != nil { + global.GVA_LOG.Error("limit", zap.Error(err)) + } + return err +} + +func DefaultLimit() gin.HandlerFunc { + return LimitConfig{ + GenerationKey: DefaultGenerationKey, + CheckOrMark: DefaultCheckOrMark, + Expire: global.GVA_CONFIG.System.LimitTimeIP, + Limit: global.GVA_CONFIG.System.LimitCountIP, + }.LimitWithTime() +} + +// SetLimitWithTime 设置访问次数 +func SetLimitWithTime(key string, limit int, expiration time.Duration) error { + count, err := global.GVA_REDIS.Exists(context.Background(), key).Result() + if err != nil { + return err + } + if count == 0 { + pipe := global.GVA_REDIS.TxPipeline() + pipe.Incr(context.Background(), key) + pipe.Expire(context.Background(), key, expiration) + _, err = pipe.Exec(context.Background()) + return err + } else { + // 次数 + if times, err := global.GVA_REDIS.Get(context.Background(), key).Int(); err != nil { + return err + } else { + if times >= limit { + if t, err := global.GVA_REDIS.PTTL(context.Background(), key).Result(); err != nil { + return errors.New("请求太过频繁,请稍后再试") + } else { + return errors.New("请求太过频繁, 请 " + t.String() + " 秒后尝试") + } + } else { + return global.GVA_REDIS.Incr(context.Background(), key).Err() + } + } + } +} diff --git a/server/middleware/loadtls.go b/server/middleware/loadtls.go index 69efe95e9f4b9a2f1b7f395f976cef19af117c76..a17cf653bb2d3407b7b24ca08c8098db829b200d 100644 --- a/server/middleware/loadtls.go +++ b/server/middleware/loadtls.go @@ -2,6 +2,7 @@ package middleware import ( "fmt" + "github.com/gin-gonic/gin" "github.com/unrolled/secure" ) diff --git a/server/middleware/logger.go b/server/middleware/logger.go new file mode 100644 index 0000000000000000000000000000000000000000..5bfda9a543de0defe422c3e353357baef01d61ca --- /dev/null +++ b/server/middleware/logger.go @@ -0,0 +1,87 @@ +package middleware + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "strings" + "time" + + "github.com/gin-gonic/gin" +) + +// LogLayout 日志layout +type LogLayout struct { + Time time.Time + Metadata map[string]interface{} // 存储自定义原数据 + Path string // 访问路径 + Query string // 携带query + Body string // 携带body数据 + IP string // ip地址 + UserAgent string // 代理 + Error string // 错误 + Cost time.Duration // 花费时间 + Source string // 来源 +} + +type Logger struct { + // Filter 用户自定义过滤 + Filter func(c *gin.Context) bool + // FilterKeyword 关键字过滤(key) + FilterKeyword func(layout *LogLayout) bool + // AuthProcess 鉴权处理 + AuthProcess func(c *gin.Context, layout *LogLayout) + // 日志处理 + Print func(LogLayout) + // Source 服务唯一标识 + Source string +} + +func (l Logger) SetLoggerMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + start := time.Now() + path := c.Request.URL.Path + query := c.Request.URL.RawQuery + var body []byte + if l.Filter != nil && !l.Filter(c) { + body, _ = c.GetRawData() + // 将原body塞回去 + c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) + } + c.Next() + cost := time.Since(start) + layout := LogLayout{ + Time: time.Now(), + Path: path, + Query: query, + IP: c.ClientIP(), + UserAgent: c.Request.UserAgent(), + Error: strings.TrimRight(c.Errors.ByType(gin.ErrorTypePrivate).String(), "\n"), + Cost: cost, + Source: l.Source, + } + if l.Filter != nil && !l.Filter(c) { + layout.Body = string(body) + } + // 处理鉴权需要的信息 + l.AuthProcess(c, &layout) + if l.FilterKeyword != nil { + // 自行判断key/value 脱敏等 + l.FilterKeyword(&layout) + } + // 自行处理日志 + l.Print(layout) + } +} + +func DefaultLogger() gin.HandlerFunc { + return Logger{ + Print: func(layout LogLayout) { + // 标准输出,k8s做收集 + v, _ := json.Marshal(layout) + fmt.Println(string(v)) + }, + Source: "GVA", + }.SetLoggerMiddleware() +} diff --git a/server/middleware/operation.go b/server/middleware/operation.go index d6efd0881c553d7e7e836d9437c12ae2b0123e01..ea207de822351cb46b6e75f2beb6858bd6444a3d 100644 --- a/server/middleware/operation.go +++ b/server/middleware/operation.go @@ -7,9 +7,10 @@ import ( "strconv" "time" + "github.com/flipped-aurora/gin-vue-admin/server/utils" + "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/model/system/request" "github.com/flipped-aurora/gin-vue-admin/server/service" "github.com/gin-gonic/gin" "go.uber.org/zap" @@ -25,14 +26,14 @@ func OperationRecord() gin.HandlerFunc { var err error body, err = ioutil.ReadAll(c.Request.Body) if err != nil { - global.GVA_LOG.Error("read body from request error:", zap.Any("err", err)) + global.GVA_LOG.Error("read body from request error:", zap.Error(err)) } else { c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) } } - if claims, ok := c.Get("claims"); ok { - waitUse := claims.(*request.CustomClaims) - userId = int(waitUse.ID) + claims, _ := utils.GetClaims(c) + if claims.ID != 0 { + userId = int(claims.ID) } else { id, err := strconv.Atoi(c.Request.Header.Get("x-user-id")) if err != nil { @@ -62,14 +63,14 @@ func OperationRecord() gin.HandlerFunc { c.Next() - latency := time.Now().Sub(now) + latency := time.Since(now) record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String() record.Status = c.Writer.Status() record.Latency = latency record.Resp = writer.body.String() if err := operationRecordService.CreateSysOperationRecord(record); err != nil { - global.GVA_LOG.Error("create operation record error:", zap.Any("err", err)) + global.GVA_LOG.Error("create operation record error:", zap.Error(err)) } } } diff --git a/server/model/common/request/common.go b/server/model/common/request/common.go index 129c6d7ebceca940aeee73b76de00c9a65147b9c..db8bba45681e77ba90bd754f304649575f1f816d 100644 --- a/server/model/common/request/common.go +++ b/server/model/common/request/common.go @@ -1,21 +1,25 @@ package request -// Paging common input parameter structure +// PageInfo Paging common input parameter structure type PageInfo struct { Page int `json:"page" form:"page"` // 页码 PageSize int `json:"pageSize" form:"pageSize"` // 每页大小 } -// Find by id structure +// GetById Find by id structure type GetById struct { ID float64 `json:"id" form:"id"` // 主键ID } +func (r *GetById) Uint() uint { + return uint(r.ID) +} + type IdsReq struct { Ids []int `json:"ids" form:"ids"` } -// Get role by id structure +// GetAuthorityId Get role by id structure type GetAuthorityId struct { AuthorityId string `json:"authorityId" form:"authorityId"` // 角色ID } diff --git a/server/model/common/response/response.go b/server/model/common/response/response.go index 81c71d7f85a85598d784477fe534dc471646a20d..f6eaab20b7c296ea2e489d5cbd8b3ffd460787c7 100644 --- a/server/model/common/response/response.go +++ b/server/model/common/response/response.go @@ -1,8 +1,9 @@ package response import ( - "github.com/gin-gonic/gin" "net/http" + + "github.com/gin-gonic/gin" ) type Response struct { diff --git a/server/model/system/request/jwt.go b/server/model/system/request/jwt.go index 7aa164294b06591265269b9cc0dbd9f95edd095f..bb673f663a410de78021026f07d1f5d871342b03 100644 --- a/server/model/system/request/jwt.go +++ b/server/model/system/request/jwt.go @@ -7,11 +7,15 @@ import ( // Custom claims structure type CustomClaims struct { + BaseClaims + BufferTime int64 + jwt.StandardClaims +} + +type BaseClaims struct { UUID uuid.UUID ID uint Username string NickName string AuthorityId string - BufferTime int64 - jwt.StandardClaims } diff --git a/server/model/system/request/sys_auto_history.go b/server/model/system/request/sys_auto_history.go new file mode 100644 index 0000000000000000000000000000000000000000..3ab8aea3692870afafbe333d665b223cd6663b38 --- /dev/null +++ b/server/model/system/request/sys_auto_history.go @@ -0,0 +1,7 @@ +package request + +import "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + +type SysAutoHistory struct { + request.PageInfo +} diff --git a/server/model/system/request/sys_init.go b/server/model/system/request/sys_init.go index 3f994cf3f163e904537feccf47e172b5b4c590f6..6eeaae97688a2c8c80181b7fa2eb8e7d7a56ce9d 100644 --- a/server/model/system/request/sys_init.go +++ b/server/model/system/request/sys_init.go @@ -1,9 +1,66 @@ package request +import ( + "fmt" + + "github.com/flipped-aurora/gin-vue-admin/server/config" +) + type InitDB struct { + DBType string `json:"dbType"` // 数据库类型 Host string `json:"host"` // 服务器地址 Port string `json:"port"` // 数据库连接端口 UserName string `json:"userName" binding:"required"` // 数据库用户名 Password string `json:"password"` // 数据库密码 DBName string `json:"dbName" binding:"required"` // 数据库名 } + +// MysqlEmptyDsn msyql 空数据库 建库链接 +// Author SliverHorn +func (i *InitDB) MysqlEmptyDsn() string { + if i.Host == "" { + i.Host = "127.0.0.1" + } + if i.Port == "" { + i.Port = "3306" + } + return fmt.Sprintf("%s:%s@tcp(%s:%s)/", i.UserName, i.Password, i.Host, i.Port) +} + +// PgsqlEmptyDsn pgsql 空数据库 建库链接 +// Author SliverHorn +func (i *InitDB) PgsqlEmptyDsn() string { + if i.Host == "" { + i.Host = "127.0.0.1" + } + if i.Port == "" { + i.Port = "3306" + } + return "host=" + i.Host + " user=" + i.UserName + " password=" + i.Password + " port=" + i.Port + " " + "sslmode=disable TimeZone=Asia/Shanghai" +} + +// ToMysqlConfig 转换 config.Mysql +// Author [SliverHorn](https://github.com/SliverHorn) +func (i *InitDB) ToMysqlConfig() config.Mysql { + return config.Mysql{ + Path: i.Host, + Port: i.Port, + Dbname: i.DBName, + Username: i.UserName, + Password: i.Password, + Config: "charset=utf8mb4&parseTime=True&loc=Local", + } +} + +// ToPgsqlConfig 转换 config.Pgsql +// Author [SliverHorn](https://github.com/SliverHorn) +func (i *InitDB) ToPgsqlConfig() config.Pgsql { + return config.Pgsql{ + Path: i.Host, + Port: i.Port, + Dbname: i.DBName, + Username: i.UserName, + Password: i.Password, + Config: "sslmode=disable TimeZone=Asia/Shanghai", + } +} diff --git a/server/model/system/request/sys_user.go b/server/model/system/request/sys_user.go index 84ab1ef47cec8b6429aea173961d0e646cfbb4e3..c03807e166036af93749c56069d494d76d05e1de 100644 --- a/server/model/system/request/sys_user.go +++ b/server/model/system/request/sys_user.go @@ -5,7 +5,7 @@ type Register struct { Username string `json:"userName"` Password string `json:"passWord"` NickName string `json:"nickName" gorm:"default:'QMPlusUser'"` - HeaderImg string `json:"headerImg" gorm:"default:'http://www.henrongyi.top/avatar/lufu.jpg'"` + HeaderImg string `json:"headerImg" gorm:"default:'https://qmplusimg.henrongyi.top/gva_header.jpg'"` AuthorityId string `json:"authorityId" gorm:"default:888"` AuthorityIds []string `json:"authorityIds"` } diff --git a/server/model/system/request/sys_autocode.go b/server/model/system/response/sys_auto_code.go similarity index 53% rename from server/model/system/request/sys_autocode.go rename to server/model/system/response/sys_auto_code.go index 7216d91f102bb3dfbb9ca371dd4a3c3cac19412e..1e44005342bb8edad5bd307513f4458f39ab5df8 100644 --- a/server/model/system/request/sys_autocode.go +++ b/server/model/system/response/sys_auto_code.go @@ -1,26 +1,16 @@ -package request +package response -import "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" - -type SysAutoHistory struct { - request.PageInfo -} - -type AutoHistoryByID struct { - ID uint `json:"id"` -} - -type DBReq struct { +type Db struct { Database string `json:"database" gorm:"column:database"` } -type TableReq struct { - TableName string `json:"tableName"` +type Table struct { + TableName string `json:"tableName" gorm:"column:table_name"` } -type ColumnReq struct { - ColumnName string `json:"columnName" gorm:"column:column_name"` +type Column struct { DataType string `json:"dataType" gorm:"column:data_type"` + ColumnName string `json:"columnName" gorm:"column:column_name"` DataTypeLong string `json:"dataTypeLong" gorm:"column:data_type_long"` ColumnComment string `json:"columnComment" gorm:"column:column_comment"` } diff --git a/server/model/system/response/sys_auto_code_history.go b/server/model/system/response/sys_auto_code_history.go new file mode 100644 index 0000000000000000000000000000000000000000..a503a84dbdc88caf707e6e7805e7f808fad300eb --- /dev/null +++ b/server/model/system/response/sys_auto_code_history.go @@ -0,0 +1,13 @@ +package response + +import "time" + +type AutoCodeHistory struct { + ID uint `json:"ID" gorm:"column:id"` + CreatedAt time.Time `json:"CreatedAt" gorm:"column:created_at"` + UpdatedAt time.Time `json:"UpdatedAt" gorm:"column:updated_at"` + TableName string `json:"tableName" gorm:"column:table_name"` + StructName string `json:"structName" gorm:"column:struct_name"` + StructCNName string `json:"structCNName" gorm:"column:struct_cn_name"` + Flag int `json:"flag" gorm:"column:flag"` +} diff --git a/server/model/system/response/sys_captcha.go b/server/model/system/response/sys_captcha.go index 9e78035ac13dbd27d2018f350697d78cda1c254d..4d482f9cd1ce4725cb0e16f417c6d1dbca490689 100644 --- a/server/model/system/response/sys_captcha.go +++ b/server/model/system/response/sys_captcha.go @@ -1,6 +1,7 @@ package response type SysCaptchaResponse struct { - CaptchaId string `json:"captchaId"` - PicPath string `json:"picPath"` + CaptchaId string `json:"captchaId"` + PicPath string `json:"picPath"` + CaptchaLength int `json:"captchaLength""` } diff --git a/server/model/system/sys_auto_code.go b/server/model/system/sys_auto_code.go index 7047b81072d70f2388bb69403d1d8f9e3aa9dd1e..349bec61e7bcf542de86872504257c12984d7c54 100644 --- a/server/model/system/sys_auto_code.go +++ b/server/model/system/sys_auto_code.go @@ -2,7 +2,7 @@ package system import "errors" -// 初始版本自动化代码工具 +// AutoCodeStruct 初始版本自动化代码工具 type AutoCodeStruct struct { StructName string `json:"structName"` // Struct名称 TableName string `json:"tableName"` // 表名 @@ -13,6 +13,7 @@ type AutoCodeStruct struct { AutoCreateApiToSql bool `json:"autoCreateApiToSql"` // 是否自动创建api AutoMoveFile bool `json:"autoMoveFile"` // 是否自动移动文件 Fields []*Field `json:"fields"` + DictTypes []string `json:"-"` } type Field struct { @@ -20,7 +21,6 @@ type Field struct { FieldDesc string `json:"fieldDesc"` // 中文名 FieldType string `json:"fieldType"` // Field数据类型 FieldJson string `json:"fieldJson"` // FieldJson - DataType string `json:"dataType"` // 数据库字段类型 DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度 Comment string `json:"comment"` // 数据库字段描述 ColumnName string `json:"columnName"` // 数据库字段 diff --git a/server/model/system/sys_autocode_history.go b/server/model/system/sys_autocode_history.go index 2250cb304d1d6cdee6a74106ddfd77d3c07efe78..f052746d0598608626e3b7388c41e300e3a982b0 100644 --- a/server/model/system/sys_autocode_history.go +++ b/server/model/system/sys_autocode_history.go @@ -1,9 +1,14 @@ package system -import "github.com/flipped-aurora/gin-vue-admin/server/global" +import ( + "strconv" + "strings" -// 自动迁移代码记录,用于回滚,重放使用 + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" +) +// SysAutoCodeHistory 自动迁移代码记录,用于回滚,重放使用 type SysAutoCodeHistory struct { global.GVA_MODEL TableName string `json:"tableName"` @@ -14,5 +19,20 @@ type SysAutoCodeHistory struct { StructCNName string `json:"structCNName"` ApiIDs string `json:"apiIDs,omitempty"` // api表注册内容 Flag int `json:"flag"` // 表示对应状态 0 代表创建, 1 代表回滚 ... +} +// ToRequestIds ApiIDs 转换 request.IdsReq +// Author [SliverHorn](https://github.com/SliverHorn) +func (m *SysAutoCodeHistory) ToRequestIds() request.IdsReq { + if m.ApiIDs == "" { + return request.IdsReq{} + } + slice := strings.Split(m.ApiIDs, ";") + ids := make([]int, 0, len(slice)) + length := len(slice) + for i := 0; i < length; i++ { + id, _ := strconv.ParseInt(slice[i], 10, 32) + ids = append(ids, int(id)) + } + return request.IdsReq{Ids: ids} } diff --git a/server/model/system/sys_initdb.go b/server/model/system/sys_initdb.go index ae05a7481f88dbfb43477f53f880491449142825..07ea0d3d17fd3be57cec73ce76f27696e8b678a5 100644 --- a/server/model/system/sys_initdb.go +++ b/server/model/system/sys_initdb.go @@ -1,5 +1,79 @@ package system +import "github.com/gookit/color" + type InitDBFunc interface { Init() (err error) } + +const ( + Mysql = "mysql" + Pgsql = "pgsql" + InitSuccess = "\n[%v] --> 初始数据成功!\n" + AuthorityMenu = "\n[%v] --> %v 视图已存在!\n" + InitDataExist = "\n[%v] --> %v 表的初始数据已存在!\n" + InitDataFailed = "\n[%v] --> %v 表初始数据失败! \nerr: %+v\n" + InitDataSuccess = "\n[%v] --> %v 表初始数据成功!\n" +) + +type InitData interface { + TableName() string + Initialize() error + CheckDataExist() bool +} + +// MysqlDataInitialize Mysql 初始化接口使用封装 +// Author [SliverHorn](https://github.com/SliverHorn) +func MysqlDataInitialize(inits ...InitData) error { + var entity SysMenu + for i := 0; i < len(inits); i++ { + if inits[i].TableName() == entity.TableName() { + if k := inits[i].CheckDataExist(); k { + color.Info.Printf(AuthorityMenu, Mysql, inits[i].TableName()) + continue + } + } else { + if inits[i].CheckDataExist() { + color.Info.Printf(InitDataExist, Mysql, inits[i].TableName()) + continue + } + } + + if err := inits[i].Initialize(); err != nil { + color.Info.Printf(InitDataFailed, Mysql, err) + return err + } else { + color.Info.Printf(InitDataSuccess, Mysql, inits[i].TableName()) + } + } + color.Info.Printf(InitSuccess, Mysql) + return nil +} + +// PgsqlDataInitialize Pgsql 初始化接口使用封装 +// Author [SliverHorn](https://github.com/SliverHorn) +func PgsqlDataInitialize(inits ...InitData) error { + var entity SysMenu + for i := 0; i < len(inits); i++ { + if inits[i].TableName() == entity.TableName() { + if k := inits[i].CheckDataExist(); k { + color.Info.Printf(AuthorityMenu, Pgsql, inits[i].TableName()) + continue + } + } else { + if inits[i].CheckDataExist() { + color.Info.Printf(InitDataExist, Pgsql, inits[i].TableName()) + continue + } + } + + if err := inits[i].Initialize(); err != nil { + color.Info.Printf(InitDataFailed, Pgsql, err) + continue + } else { + color.Info.Printf(InitDataSuccess, Pgsql, inits[i].TableName()) + } + } + color.Info.Printf(InitSuccess, Pgsql) + return nil +} diff --git a/server/model/system/sys_operation_record.go b/server/model/system/sys_operation_record.go index 43bf7569a9b03cf46fca7132601e8a1eb24bf3cb..bd316bb4e8f4f9be215846933753f2353c96d29e 100644 --- a/server/model/system/sys_operation_record.go +++ b/server/model/system/sys_operation_record.go @@ -17,8 +17,8 @@ type SysOperationRecord struct { Latency time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:延迟" swaggertype:"string"` // 延迟 Agent string `json:"agent" form:"agent" gorm:"column:agent;comment:代理"` // 代理 ErrorMessage string `json:"error_message" form:"error_message" gorm:"column:error_message;comment:错误信息"` // 错误信息 - Body string `json:"body" form:"body" gorm:"type:longtext;column:body;comment:请求Body"` // 请求Body - Resp string `json:"resp" form:"resp" gorm:"type:longtext;column:resp;comment:响应Body"` // 响应Body + 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 UserID int `json:"user_id" form:"user_id" gorm:"column:user_id;comment:用户id"` // 用户id User SysUser `json:"user"` } diff --git a/server/model/system/sys_user.go b/server/model/system/sys_user.go index 9b10b55951903b8b41b8201a39e71ef2eb701525..40678cd42c37c12f00ccc8867199c455c91da1af 100644 --- a/server/model/system/sys_user.go +++ b/server/model/system/sys_user.go @@ -7,15 +7,15 @@ import ( type SysUser struct { global.GVA_MODEL - UUID uuid.UUID `json:"uuid" gorm:"comment:用户UUID"` // 用户UUID - Username string `json:"userName" gorm:"comment:用户登录名"` // 用户登录名 - Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码 - NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称 - HeaderImg string `json:"headerImg" gorm:"default:http://qmplusimg.henrongyi.top/head.png;comment:用户头像"` // 用户头像 + UUID uuid.UUID `json:"uuid" gorm:"comment:用户UUID"` // 用户UUID + Username string `json:"userName" gorm:"comment:用户登录名"` // 用户登录名 + Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码 + NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称 + 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 string `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"` - AuthorityId string `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID - SideMode string `json:"sideMode" gorm:"default:dark;comment:用户角色ID"` // 用户侧边主题 - ActiveColor string `json:"activeColor" gorm:"default:#1890ff;comment:用户角色ID"` // 活跃颜色 - BaseColor string `json:"baseColor" gorm:"default:#fff;comment:用户角色ID"` // 基础颜色 Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"` } diff --git a/server/plugin/email/api/sys_email.go b/server/plugin/email/api/sys_email.go index 03e13afa84beb4beb7869acdd4bed7f1e6ed1fce..09605ab9c3080348e83632afb76f51a90d23933f 100644 --- a/server/plugin/email/api/sys_email.go +++ b/server/plugin/email/api/sys_email.go @@ -9,8 +9,7 @@ import ( "go.uber.org/zap" ) -type EmailApi struct { -} +type EmailApi struct{} // @Tags System // @Summary 发送测试邮件 @@ -20,7 +19,7 @@ type EmailApi struct { // @Router /email/emailTest [post] func (s *EmailApi) EmailTest(c *gin.Context) { if err := service.ServiceGroupApp.EmailTest(); err != nil { - global.GVA_LOG.Error("发送失败!", zap.Any("err", err)) + global.GVA_LOG.Error("发送失败!", zap.Error(err)) response.FailWithMessage("发送失败", c) } else { response.OkWithData("发送成功", c) @@ -38,7 +37,7 @@ func (s *EmailApi) SendEmail(c *gin.Context) { var email email_response.Email _ = c.ShouldBindJSON(&email) if err := service.ServiceGroupApp.SendEmail(email.To, email.Subject, email.Body); err != nil { - global.GVA_LOG.Error("发送失败!", zap.Any("err", err)) + global.GVA_LOG.Error("发送失败!", zap.Error(err)) response.FailWithMessage("发送失败", c) } else { response.OkWithData("发送成功", c) diff --git a/server/plugin/email/main.go b/server/plugin/email/main.go index e044797a1899d67802697b8c995e02cf43249404..cfc8c46b1cb61c084383210a90f287df3652bafc 100644 --- a/server/plugin/email/main.go +++ b/server/plugin/email/main.go @@ -6,8 +6,7 @@ import ( "github.com/gin-gonic/gin" ) -type emailPlugin struct { -} +type emailPlugin struct{} func CreateEmailPlug(To, From, Host, Secret, Nickname string, Port int, IsSSL bool) *emailPlugin { global.GlobalConfig.To = To diff --git a/server/plugin/email/router/sys_email.go b/server/plugin/email/router/sys_email.go index 518bb0bbb18767237063789403f9a9e15ba24c9f..1f9f07f0e17e747f12a5924a690d28603c944461 100644 --- a/server/plugin/email/router/sys_email.go +++ b/server/plugin/email/router/sys_email.go @@ -6,13 +6,12 @@ import ( "github.com/gin-gonic/gin" ) -type EmailRouter struct { -} +type EmailRouter struct{} func (s *EmailRouter) InitEmailRouter(Router *gin.RouterGroup) { emailRouter := Router.Use(middleware.OperationRecord()) - var EmailApi = api.ApiGroupApp.EmailApi.EmailTest - var SendEmail = api.ApiGroupApp.EmailApi.SendEmail + EmailApi := api.ApiGroupApp.EmailApi.EmailTest + SendEmail := api.ApiGroupApp.EmailApi.SendEmail { emailRouter.POST("emailTest", EmailApi) // 发送测试邮件 emailRouter.POST("sendEmail", SendEmail) // 发送邮件 diff --git a/server/plugin/email/service/sys_email.go b/server/plugin/email/service/sys_email.go index 6659fc6f1eecf21011b1e5f077dcc48cee689328..57042769cd86dbdd09a7e2f22b26d92f3e722252 100644 --- a/server/plugin/email/service/sys_email.go +++ b/server/plugin/email/service/sys_email.go @@ -4,8 +4,7 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/plugin/email/utils" ) -type EmailService struct { -} +type EmailService struct{} //@author: [maplepie](https://github.com/maplepie) //@function: EmailTest diff --git a/server/plugin/example_plugin/main.go b/server/plugin/example_plugin/main.go index 1fa6831f44e4fedf63b37fb91a4ad54a00b325c0..79518e48586eec9262335d332afcd6d2e91952be 100644 --- a/server/plugin/example_plugin/main.go +++ b/server/plugin/example_plugin/main.go @@ -6,8 +6,7 @@ import ( var ExamplePlugin = new(pluginExample) -type pluginExample struct { -} +type pluginExample struct{} func (*pluginExample) Register(group *gin.RouterGroup) { //如需细分权限 可以在此处use中间件 gva项目包名已改为github模式 diff --git a/server/plugin/ws/utils/utils.go b/server/plugin/ws/utils/utils.go deleted file mode 100644 index 85f91fe04e2e2f8bdb9410a3fa0cf6367db5a6d4..0000000000000000000000000000000000000000 --- a/server/plugin/ws/utils/utils.go +++ /dev/null @@ -1,52 +0,0 @@ -package utils - -import ( - "github.com/flipped-aurora/gin-vue-admin/server/global" - systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" - "github.com/gin-gonic/gin" - uuid "github.com/satori/go.uuid" -) - -// 从Gin的Context中获取从jwt解析出来的用户ID -func GetUserID(c *gin.Context) uint { - if claims, exists := c.Get("claims"); !exists { - global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户ID失败, 请检查路由是否使用jwt中间件!") - return 0 - } else { - waitUse := claims.(*systemReq.CustomClaims) - return waitUse.ID - } -} - -// 从Gin的Context中获取从jwt解析出来的用户UUID -func GetUserUuid(c *gin.Context) uuid.UUID { - if claims, exists := c.Get("claims"); !exists { - global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!") - return uuid.UUID{} - } else { - waitUse := claims.(*systemReq.CustomClaims) - return waitUse.UUID - } -} - -// 从Gin的Context中获取从jwt解析出来的用户角色id -func GetUserAuthorityId(c *gin.Context) string { - if claims, exists := c.Get("claims"); !exists { - global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!") - return "" - } else { - waitUse := claims.(*systemReq.CustomClaims) - return waitUse.AuthorityId - } -} - -// 从Gin的Context中获取从jwt解析出来的用户角色id -func GetUserInfo(c *gin.Context) *systemReq.CustomClaims { - if claims, exists := c.Get("claims"); !exists { - global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!") - return nil - } else { - waitUse := claims.(*systemReq.CustomClaims) - return waitUse - } -} diff --git a/server/plugin/ws/ws.go b/server/plugin/ws/ws.go index be63a2ff08949b666019fb249f1d844eeb3e50a0..bd6926e0c9311a13fa187f781b9347222c8255cb 100644 --- a/server/plugin/ws/ws.go +++ b/server/plugin/ws/ws.go @@ -58,7 +58,6 @@ func (w *wsPlugin) Register(g *gin.RouterGroup) { InsecureSkipVerify: true, })) g.POST("/sendMsg", w.adminCase.SendMsg("gva_ws")) - } func (w *wsPlugin) RouterPath() string { @@ -78,6 +77,8 @@ func GenerateWs(logger *zap.Logger, manageBuf int64, checkMap map[string]biz.Che for key, handler := range registeredMsgHandler { admin.RegisteredMsgHandler(key, handler) } - return &wsPlugin{logger: logger, manageBuf: manageBuf, - registeredMsgHandler: registeredMsgHandler, checkMap: checkMap, admin: admin, adminCase: biz.NewAdmin(admin)} + return &wsPlugin{ + logger: logger, manageBuf: manageBuf, + registeredMsgHandler: registeredMsgHandler, checkMap: checkMap, admin: admin, adminCase: biz.NewAdmin(admin), + } } diff --git a/server/resource/rbac_model.conf b/server/resource/rbac_model.conf index 04ebedff9d76a740b074783ce6bbb59357a4867b..b5918d45e964c5c4f5ff2bd5be3c9ae8fc8fc3c7 100644 --- a/server/resource/rbac_model.conf +++ b/server/resource/rbac_model.conf @@ -11,4 +11,4 @@ g = _, _ e = some(where (p.eft == allow)) [matchers] -m = r.sub == p.sub && ParamsMatch(r.obj,p.obj) && r.act == p.act +m = r.sub == p.sub && keyMatch2(r.obj,p.obj) && r.act == p.act diff --git a/server/resource/template/server/api.go.tpl b/server/resource/template/server/api.go.tpl index 42dcad6f77e041990a17477d1d334388d0b27b3e..2fb0689cc0b1cbc5d941aacde4a51f8c40720e3a 100644 --- a/server/resource/template/server/api.go.tpl +++ b/server/resource/template/server/api.go.tpl @@ -30,7 +30,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con var {{.Abbreviation}} autocode.{{.StructName}} _ = c.ShouldBindJSON(&{{.Abbreviation}}) if err := {{.Abbreviation}}Service.Create{{.StructName}}({{.Abbreviation}}); err != nil { - global.GVA_LOG.Error("创建失败!", zap.Any("err", err)) + global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败", c) } else { response.OkWithMessage("创建成功", c) @@ -50,7 +50,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Con var {{.Abbreviation}} autocode.{{.StructName}} _ = c.ShouldBindJSON(&{{.Abbreviation}}) if err := {{.Abbreviation}}Service.Delete{{.StructName}}({{.Abbreviation}}); err != nil { - global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) } else { response.OkWithMessage("删除成功", c) @@ -70,7 +70,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gi var IDS request.IdsReq _ = c.ShouldBindJSON(&IDS) if err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds(IDS); err != nil { - global.GVA_LOG.Error("批量删除失败!", zap.Any("err", err)) + global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) response.FailWithMessage("批量删除失败", c) } else { response.OkWithMessage("批量删除成功", c) @@ -90,7 +90,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Con var {{.Abbreviation}} autocode.{{.StructName}} _ = c.ShouldBindJSON(&{{.Abbreviation}}) if err := {{.Abbreviation}}Service.Update{{.StructName}}({{.Abbreviation}}); err != nil { - global.GVA_LOG.Error("更新失败!", zap.Any("err", err)) + global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) } else { response.OkWithMessage("更新成功", c) @@ -110,7 +110,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Find{{.StructName}}(c *gin.Conte var {{.Abbreviation}} autocode.{{.StructName}} _ = c.ShouldBindQuery(&{{.Abbreviation}}) if err, re{{.Abbreviation}} := {{.Abbreviation}}Service.Get{{.StructName}}({{.Abbreviation}}.ID); err != nil { - global.GVA_LOG.Error("查询失败!", zap.Any("err", err)) + global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败", c) } else { response.OkWithData(gin.H{"re{{.Abbreviation}}": re{{.Abbreviation}}}, c) @@ -130,7 +130,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Co var pageInfo autocodeReq.{{.StructName}}Search _ = c.ShouldBindQuery(&pageInfo) if err, list, total := {{.Abbreviation}}Service.Get{{.StructName}}InfoList(pageInfo); err != nil { - global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) + global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { response.OkWithDetailed(response.PageResult{ diff --git a/server/resource/template/server/model.go.tpl b/server/resource/template/server/model.go.tpl index fbad1e01bdec36167db76481d885756018d0af4a..e585cc2068bf14d4ffd4b5798453ea0bfa104f72 100644 --- a/server/resource/template/server/model.go.tpl +++ b/server/resource/template/server/model.go.tpl @@ -10,9 +10,9 @@ import ( type {{.StructName}} struct { global.GVA_MODEL {{- range .Fields}} {{- if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}}{{- if .DataType -}};type:{{.DataType}}{{- end }}"` + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}"` {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}}{{- if .DataType -}};type:{{.DataType}}{{- if eq .FieldType "string" -}}{{- if .DataTypeLong -}}({{.DataTypeLong}}){{- end -}}{{- end -}};{{- if ne .FieldType "string" -}}{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}{{- end -}}{{- end -}}"` + {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}"` {{- end }} {{- end }} } diff --git a/server/resource/template/server/router.go.tpl b/server/resource/template/server/router.go.tpl index a4db665aecd63b23d93ca27a7670d3538378a7f8..85f0f2bce9a1aae99198a7c832011edfc0b38460 100644 --- a/server/resource/template/server/router.go.tpl +++ b/server/resource/template/server/router.go.tpl @@ -12,13 +12,16 @@ type {{.StructName}}Router struct { // Init{{.StructName}}Router 初始化 {{.StructName}} 路由信息 func (s *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGroup) { {{.Abbreviation}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord()) + {{.Abbreviation}}RouterWithoutRecord := Router.Group("{{.Abbreviation}}") var {{.Abbreviation}}Api = v1.ApiGroupApp.AutoCodeApiGroup.{{.StructName}}Api { {{.Abbreviation}}Router.POST("create{{.StructName}}", {{.Abbreviation}}Api.Create{{.StructName}}) // 新建{{.StructName}} {{.Abbreviation}}Router.DELETE("delete{{.StructName}}", {{.Abbreviation}}Api.Delete{{.StructName}}) // 删除{{.StructName}} {{.Abbreviation}}Router.DELETE("delete{{.StructName}}ByIds", {{.Abbreviation}}Api.Delete{{.StructName}}ByIds) // 批量删除{{.StructName}} {{.Abbreviation}}Router.PUT("update{{.StructName}}", {{.Abbreviation}}Api.Update{{.StructName}}) // 更新{{.StructName}} - {{.Abbreviation}}Router.GET("find{{.StructName}}", {{.Abbreviation}}Api.Find{{.StructName}}) // 根据ID获取{{.StructName}} - {{.Abbreviation}}Router.GET("get{{.StructName}}List", {{.Abbreviation}}Api.Get{{.StructName}}List) // 获取{{.StructName}}列表 + } + { + {{.Abbreviation}}RouterWithoutRecord.GET("find{{.StructName}}", {{.Abbreviation}}Api.Find{{.StructName}}) // 根据ID获取{{.StructName}} + {{.Abbreviation}}RouterWithoutRecord.GET("get{{.StructName}}List", {{.Abbreviation}}Api.Get{{.StructName}}List) // 获取{{.StructName}}列表 } } diff --git a/server/resource/template/server/service.go.tpl b/server/resource/template/server/service.go.tpl index 8a40fc44ff0e5ae323528dae53a29d6a079dba40..f944e6e8855de1e66e709cdf23c501ecc7d1ef5e 100644 --- a/server/resource/template/server/service.go.tpl +++ b/server/resource/template/server/service.go.tpl @@ -58,28 +58,31 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis {{- if .FieldSearchType}} {{- if eq .FieldType "string" }} if info.{{.FieldName}} != "" { - db = db.Where("`{{.ColumnName}}` {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- else if eq .FieldType "bool" }} if info.{{.FieldName}} != nil { - db = db.Where("`{{.ColumnName}}` {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- else if eq .FieldType "int" }} if info.{{.FieldName}} != nil { - db = db.Where("`{{.ColumnName}}` {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- else if eq .FieldType "float64" }} if info.{{.FieldName}} != nil { - db = db.Where("`{{.ColumnName}}` {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- else if eq .FieldType "time.Time" }} if info.{{.FieldName}} != nil { - db = db.Where("`{{.ColumnName}}` {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- end }} {{- end }} {{- end }} err = db.Count(&total).Error + if err!=nil { + return + } err = db.Limit(limit).Offset(offset).Find(&{{.Abbreviation}}s).Error return err, {{.Abbreviation}}s, total } diff --git a/server/resource/template/web/form.vue.tpl b/server/resource/template/web/form.vue.tpl index cd19c74fe01da17a2b02735e39b519efbb057c01..17e31158236703057a9622d4b7085dc7d7e27302 100644 --- a/server/resource/template/web/form.vue.tpl +++ b/server/resource/template/web/form.vue.tpl @@ -1,36 +1,38 @@ @@ -47,10 +49,8 @@ export default { data() { return { type: '', - {{- range .Fields}} - {{- if .DictType }} - {{ .DictType }}Options: [], - {{- end }} + {{- range $index, $element := .DictTypes}} + {{ $element }}Options: [], {{- end }} formData: { {{- range .Fields}} @@ -61,7 +61,7 @@ export default { {{.FieldJson}}: '', {{- end }} {{- if eq .FieldType "int" }} - {{.FieldJson}}: 0, + {{.FieldJson}}: {{- if .DictType }} undefined{{ else }} 0{{- end }}, {{- end }} {{- if eq .FieldType "time.Time" }} {{.FieldJson}}: new Date(), @@ -84,10 +84,8 @@ export default { } else { this.type = 'create' } - {{- range .Fields }} - {{- if .DictType }} - await this.getDict('{{.DictType}}') - {{- end }} + {{- range $index, $element := .DictTypes }} + await this.getDict('{{$element}}') {{- end }} }, methods: { diff --git a/server/resource/template/web/table.vue.tpl b/server/resource/template/web/table.vue.tpl index 6fd337c034354b8108fb1adbd00043e9787fed82..9cf641d1ad1caef6ac2fd80c066db3f371e054f0 100644 --- a/server/resource/template/web/table.vue.tpl +++ b/server/resource/template/web/table.vue.tpl @@ -1,6 +1,6 @@ @@ -34,13 +53,18 @@ diff --git a/web/src/view/routerHolder.vue b/web/src/view/routerHolder.vue index c8cd19456a1a7ca8ca35275e859160c8f027cc0f..53d157c93334cbd024a248ffee8396966c0ad0d2 100644 --- a/web/src/view/routerHolder.vue +++ b/web/src/view/routerHolder.vue @@ -1,18 +1,13 @@ + diff --git a/web/src/view/superAdmin/api/api.vue b/web/src/view/superAdmin/api/api.vue index 0e8ffe041473d4a68b5567d39a675f7b34014de7..4bb6b685c95a73c29a91e5cdd57fca5dd487738d 100644 --- a/web/src/view/superAdmin/api/api.vue +++ b/web/src/view/superAdmin/api/api.vue @@ -1,14 +1,14 @@