diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 65812ade7d..b6f64ed930 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.8.0] + node-version: [18.16.0] steps: - name: Check out branch uses: actions/checkout@v2 @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: [1.21] + go-version: [1.22] steps: - name: Set up Go ${{ matrix.go-version }} uses: actions/setup-go@v1 @@ -83,8 +83,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.8.0] - go-version: [1.21] + node-version: [18.16.0] + go-version: [1.22] steps: - name: Check out branch uses: actions/checkout@v2 @@ -194,8 +194,8 @@ jobs: name: devops-prod strategy: matrix: - node-version: ['16.x'] - go-version: ['1.21'] + node-version: ['18.x'] + go-version: ['1.22'] steps: - uses: actions/checkout@v2 - name: tag major and minor versions diff --git a/.gitignore b/.gitignore index 4bac657be5..5f7b8d3809 100644 --- a/.gitignore +++ b/.gitignore @@ -22,10 +22,13 @@ yarn-error.log* *.sln *.sw? +rm_file/ /server/log/ /server/gva +/server/server /server/latest_log /server/__debug_bin* +server/uploads/ *.iml web/.pnpm-debug.log diff --git a/Makefile b/Makefile index e1d4f760d9..4b193fc6d6 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,9 @@ SHELL = /bin/bash #SCRIPT_DIR = $(shell pwd)/etc/script #请选择golang版本 -BUILD_IMAGE_SERVER = golang:1.18 +BUILD_IMAGE_SERVER = golang:1.22 #请选择node版本 -BUILD_IMAGE_WEB = node:16 +BUILD_IMAGE_WEB = node:20 #项目名称 PROJECT_NAME = github.com/flipped-aurora/gin-vue-admin/server #配置文件目录 diff --git a/README-en.md b/README-en.md index 2a7f82efb5..1f2a59ca14 100644 --- a/README-en.md +++ b/README-en.md @@ -1,6 +1,6 @@
- +
@@ -16,10 +16,6 @@ English | [简体中文](./README.md) [github](https://github.com/flipped-aurora/gin-vue-admin): https://github.com/flipped-aurora/gin-vue-admin -[Vue3 version branch address](https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop): https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop - -[Approval flow branch](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow): https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow - # Project Guidelines [Online Documentation](https://www.gin-vue-admin.com/) : https://www.gin-vue-admin.com/ diff --git a/README.md b/README.md index 66fefe31e3..d98c3b98ee 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +
@@ -12,15 +12,6 @@ [English](./README-en.md) | 简体中文 -## 不同版本 - -我们会对以下四个版本持续维护,请选择适合自己的版本使用。最新技术栈为组合式api版本,已支持多语言(I18N) - -[组合式API版(主)](https://github.com/flipped-aurora/gin-vue-admin) | -[组合式API多语言(i18n)版](https://github.com/flipped-aurora/gin-vue-admin/tree/i18n-dev-new) | -[声明式API版](https://github.com/flipped-aurora/gin-vue-admin/tree/v2.4.x) | -[声明式API多语言(i18n)版](https://github.com/flipped-aurora/gin-vue-admin/tree/i18n-dev) - # 项目文档 [在线文档](https://www.gin-vue-admin.com) : https://www.gin-vue-admin.com @@ -42,9 +33,11 @@ 3.您完全可以通过我们的教程和文档完成一切操作,因此我们不再提供免费的技术服务,如需服务请进行[付费支持](https://www.gin-vue-admin.com/coffee/payment.html) -4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,其余信息功能不做任何限制。如需剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html) +4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,以及日志和代码中所包含的版权声明信息。所需保留信息均为文案性质,不会影响任何业务内容,如决定商用且必须剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html) + + - + ## 1. 基本介绍 @@ -83,7 +76,7 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm ``` - node版本 > v16.8.3 -- golang版本 >= v1.16 +- golang版本 >= v1.22 - IDE推荐:Goland ``` @@ -101,11 +94,9 @@ cd server # 使用 go mod 并安装go依赖包 go generate -# 编译 -go build -o server main.go (windows编译命令为go build -o server.exe main.go ) +# 运行 +go run . -# 运行二进制 -./server (windows运行命令为 server.exe) ``` ### 2.2 web项目 diff --git a/deploy/docker-compose/docker-compose-dev.yaml b/deploy/docker-compose/docker-compose-dev.yaml index 8bdb3347ef..fd0a3b6614 100644 --- a/deploy/docker-compose/docker-compose-dev.yaml +++ b/deploy/docker-compose/docker-compose-dev.yaml @@ -15,7 +15,7 @@ volumes: services: web: - image: node:16 + image: node:20 container_name: gva-web hostname: gva-web #可以通过容器名访问 restart: always @@ -25,7 +25,7 @@ services: - server working_dir: /web # 如果docker 设置了workdir 则此处不需要设置 #若网络不太好,请自行换源,如下 - #command: bash -c "yarn config set registry https://registry.npm.taobao.org --global && yarn install && yarn serve" + #command: bash -c "yarn config set registry https://registry.npmmirror.com --global && yarn install && yarn serve" command: bash -c "yarn install && yarn serve" volumes: - ../../web:/web @@ -34,7 +34,7 @@ services: ipv4_address: 177.7.0.11 server: - image: golang:1.18 + image: golang:1.22 container_name: gva-server hostname: gva-server restart: always diff --git a/server/Dockerfile b/server/Dockerfile index 545f708338..69cb44dc69 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -13,6 +13,10 @@ RUN go env -w GO111MODULE=on \ FROM alpine:latest LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com" +# 设置时区 +ENV TZ=Asia/Shanghai +RUN apk update && apk add --no-cache tzdata openntpd \ + && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server @@ -20,5 +24,8 @@ COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/server ./ COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/resource ./resource/ COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.docker.yaml ./ +# 挂载目录:如果使用了sqlite数据库,容器命令示例:docker run -d -v /宿主机路径/gva.db:/go/src/github.com/flipped-aurora/gin-vue-admin/server/gva.db -p 8888:8888 --name gva-server-v1 gva-server:1.0 +# VOLUME ["/go/src/github.com/flipped-aurora/gin-vue-admin/server"] + EXPOSE 8888 ENTRYPOINT ./server -c config.docker.yaml diff --git a/server/api/v1/enter.go b/server/api/v1/enter.go index 54adbe7968..5c1dff4434 100644 --- a/server/api/v1/enter.go +++ b/server/api/v1/enter.go @@ -5,9 +5,9 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/api/v1/system" ) +var ApiGroupApp = new(ApiGroup) + type ApiGroup struct { SystemApiGroup system.ApiGroup ExampleApiGroup example.ApiGroup } - -var ApiGroupApp = new(ApiGroup) diff --git a/server/api/v1/example/exa_breakpoint_continue.go b/server/api/v1/example/exa_breakpoint_continue.go index 5ceba06b02..8f39cb160e 100644 --- a/server/api/v1/example/exa_breakpoint_continue.go +++ b/server/api/v1/example/exa_breakpoint_continue.go @@ -84,7 +84,7 @@ func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) { // @Produce application/json // @Param file formData file true "Find the file, 查找文件" // @Success 200 {object} response.Response{data=exampleRes.FileResponse,msg=string} "查找文件,返回包括文件详情" -// @Router /fileUploadAndDownload/findFile [post] +// @Router /fileUploadAndDownload/findFile [get] func (b *FileUploadAndDownloadApi) FindFile(c *gin.Context) { fileMd5 := c.Query("fileMd5") fileName := c.Query("fileName") diff --git a/server/api/v1/example/exa_file_upload_download.go b/server/api/v1/example/exa_file_upload_download.go index 18d1251240..6905936d7e 100644 --- a/server/api/v1/example/exa_file_upload_download.go +++ b/server/api/v1/example/exa_file_upload_download.go @@ -32,8 +32,8 @@ func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) { } file, err = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径 if err != nil { - global.GVA_LOG.Error("修改数据库链接失败!", zap.Error(err)) - response.FailWithMessage("修改数据库链接失败", c) + global.GVA_LOG.Error("上传文件失败!", zap.Error(err)) + response.FailWithMessage("上传文件失败", c) return } response.OkWithDetailed(exampleRes.ExaFileResponse{File: file}, "上传成功", c) @@ -108,3 +108,26 @@ func (b *FileUploadAndDownloadApi) GetFileList(c *gin.Context) { PageSize: pageInfo.PageSize, }, "获取成功", c) } + +// ImportURL +// @Tags ExaFileUploadAndDownload +// @Summary 导入URL +// @Security ApiKeyAuth +// @Produce application/json +// @Param data body example.ExaFileUploadAndDownload true "对象" +// @Success 200 {object} response.Response{msg=string} "导入URL" +// @Router /fileUploadAndDownload/importURL [post] +func (b *FileUploadAndDownloadApi) ImportURL(c *gin.Context) { + var file []example.ExaFileUploadAndDownload + err := c.ShouldBindJSON(&file) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + if err := fileUploadAndDownloadService.ImportURL(&file); err != nil { + global.GVA_LOG.Error("导入URL失败!", zap.Error(err)) + response.FailWithMessage("导入URL失败", c) + return + } + response.OkWithMessage("导入URL成功", c) +} diff --git a/server/api/v1/system/sys_auto_code_history.go b/server/api/v1/system/auto_code_history.go similarity index 77% rename from server/api/v1/system/sys_auto_code_history.go rename to server/api/v1/system/auto_code_history.go index 4ad6b5e470..065ddd86cf 100644 --- a/server/api/v1/system/sys_auto_code_history.go +++ b/server/api/v1/system/auto_code_history.go @@ -2,9 +2,9 @@ package system import ( "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + common "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" + request "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" "github.com/gin-gonic/gin" "go.uber.org/zap" ) @@ -21,13 +21,13 @@ type AutoCodeHistoryApi struct{} // @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取meta信息" // @Router /autoCode/getMeta [post] func (a *AutoCodeHistoryApi) First(c *gin.Context) { - var info request.GetById + var info common.GetById err := c.ShouldBindJSON(&info) if err != nil { response.FailWithMessage(err.Error(), c) return } - data, err := autoCodeHistoryService.First(&info) + data, err := autoCodeHistoryService.First(c.Request.Context(), info) if err != nil { response.FailWithMessage(err.Error(), c) return @@ -45,13 +45,13 @@ func (a *AutoCodeHistoryApi) First(c *gin.Context) { // @Success 200 {object} response.Response{msg=string} "删除回滚记录" // @Router /autoCode/delSysHistory [post] func (a *AutoCodeHistoryApi) Delete(c *gin.Context) { - var info request.GetById + var info common.GetById err := c.ShouldBindJSON(&info) if err != nil { response.FailWithMessage(err.Error(), c) return } - err = autoCodeHistoryService.Delete(&info) + err = autoCodeHistoryService.Delete(c.Request.Context(), info) if err != nil { global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败", c) @@ -66,17 +66,17 @@ func (a *AutoCodeHistoryApi) Delete(c *gin.Context) { // @Security ApiKeyAuth // @accept application/json // @Produce application/json -// @Param data body systemReq.RollBack true "请求参数" +// @Param data body request.SysAutoHistoryRollBack true "请求参数" // @Success 200 {object} response.Response{msg=string} "回滚自动生成代码" // @Router /autoCode/rollback [post] func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) { - var info systemReq.RollBack + var info request.SysAutoHistoryRollBack err := c.ShouldBindJSON(&info) if err != nil { response.FailWithMessage(err.Error(), c) return } - err = autoCodeHistoryService.RollBack(&info) + err = autoCodeHistoryService.RollBack(c.Request.Context(), info) if err != nil { response.FailWithMessage(err.Error(), c) return @@ -90,17 +90,17 @@ func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) { // @Security ApiKeyAuth // @accept application/json // @Produce application/json -// @Param data body systemReq.SysAutoHistory true "请求参数" +// @Param data body common.PageInfo true "请求参数" // @Success 200 {object} response.Response{data=response.PageResult,msg=string} "查询回滚记录,返回包括列表,总数,页码,每页数量" // @Router /autoCode/getSysHistory [post] func (a *AutoCodeHistoryApi) GetList(c *gin.Context) { - var search systemReq.SysAutoHistory - err := c.ShouldBindJSON(&search) + var info common.PageInfo + err := c.ShouldBindJSON(&info) if err != nil { response.FailWithMessage(err.Error(), c) return } - list, total, err := autoCodeHistoryService.GetList(search.PageInfo) + list, total, err := autoCodeHistoryService.GetList(c.Request.Context(), info) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) @@ -109,7 +109,7 @@ func (a *AutoCodeHistoryApi) GetList(c *gin.Context) { response.OkWithDetailed(response.PageResult{ List: list, Total: total, - Page: search.Page, - PageSize: search.PageSize, + Page: info.Page, + PageSize: info.PageSize, }, "获取成功", c) } diff --git a/server/api/v1/system/auto_code_package.go b/server/api/v1/system/auto_code_package.go new file mode 100644 index 0000000000..655f29ab23 --- /dev/null +++ b/server/api/v1/system/auto_code_package.go @@ -0,0 +1,100 @@ +package system + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + "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/utils" + "github.com/gin-gonic/gin" + "go.uber.org/zap" + "strings" +) + +type AutoCodePackageApi struct{} + +// Create +// @Tags AutoCodePackage +// @Summary 创建package +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.SysAutoCodePackageCreate true "创建package" +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功" +// @Router /autoCode/createPackage [post] +func (a *AutoCodePackageApi) Create(c *gin.Context) { + var info request.SysAutoCodePackageCreate + _ = c.ShouldBindJSON(&info) + if err := utils.Verify(info, utils.AutoPackageVerify); err != nil { + response.FailWithMessage(err.Error(), c) + return + } + if strings.Contains(info.PackageName, "\\") || strings.Contains(info.PackageName, "/") || strings.Contains(info.PackageName, "..") { + response.FailWithMessage("包名不合法", c) + return + } // PackageName可能导致路径穿越的问题 / 和 \ 都要防止 + err := autoCodePackageService.Create(c.Request.Context(), &info) + if err != nil { + global.GVA_LOG.Error("创建失败!", zap.Error(err)) + response.FailWithMessage("创建失败", c) + return + } + response.OkWithMessage("创建成功", c) +} + +// Delete +// @Tags AutoCode +// @Summary 删除package +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body common.GetById true "创建package" +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "删除package成功" +// @Router /autoCode/delPackage [post] +func (a *AutoCodePackageApi) Delete(c *gin.Context) { + var info common.GetById + _ = c.ShouldBindJSON(&info) + err := autoCodePackageService.Delete(c.Request.Context(), info) + if err != nil { + global.GVA_LOG.Error("删除失败!", zap.Error(err)) + response.FailWithMessage("删除失败", c) + return + } + response.OkWithMessage("删除成功", c) +} + +// All +// @Tags AutoCodePackage +// @Summary 获取package +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功" +// @Router /autoCode/getPackage [post] +func (a *AutoCodePackageApi) All(c *gin.Context) { + data, err := autoCodePackageService.All(c.Request.Context()) + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败", c) + return + } + response.OkWithDetailed(gin.H{"pkgs": data}, "获取成功", c) +} + +// Templates +// @Tags AutoCodePackage +// @Summary 获取package +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功" +// @Router /autoCode/getTemplates [get] +func (a *AutoCodePackageApi) Templates(c *gin.Context) { + data, err := autoCodePackageService.Templates(c.Request.Context()) + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败", c) + return + } + response.OkWithDetailed(data, "获取成功", c) +} diff --git a/server/api/v1/system/auto_code_plugin.go b/server/api/v1/system/auto_code_plugin.go new file mode 100644 index 0000000000..30029feb2c --- /dev/null +++ b/server/api/v1/system/auto_code_plugin.go @@ -0,0 +1,119 @@ +package system + +import ( + "fmt" + "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/gin-gonic/gin" + "go.uber.org/zap" +) + +type AutoCodePluginApi struct{} + +// Install +// @Tags AutoCodePlugin +// @Summary 安装插件 +// @Security ApiKeyAuth +// @accept multipart/form-data +// @Produce application/json +// @Param plug formData file true "this is a test file" +// @Success 200 {object} response.Response{data=[]interface{},msg=string} "安装插件成功" +// @Router /autoCode/installPlugin [post] +func (a *AutoCodePluginApi) Install(c *gin.Context) { + header, err := c.FormFile("plug") + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + web, server, err := autoCodePluginService.Install(header) + webStr := "web插件安装成功" + serverStr := "server插件安装成功" + if web == -1 { + webStr = "web端插件未成功安装,请按照文档自行解压安装,如果为纯后端插件请忽略此条提示" + } + if server == -1 { + serverStr = "server端插件未成功安装,请按照文档自行解压安装,如果为纯前端插件请忽略此条提示" + } + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + response.OkWithData([]interface{}{ + gin.H{ + "code": web, + "msg": webStr, + }, + gin.H{ + "code": server, + "msg": serverStr, + }}, c) +} + +// Packaged +// @Tags AutoCodePlugin +// @Summary 打包插件 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param plugName query string true "插件名称" +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功" +// @Router /autoCode/pubPlug [post] +func (a *AutoCodePluginApi) Packaged(c *gin.Context) { + plugName := c.Query("plugName") + zipPath, err := autoCodePluginService.PubPlug(plugName) + if err != nil { + global.GVA_LOG.Error("打包失败!", zap.Error(err)) + response.FailWithMessage("打包失败"+err.Error(), c) + return + } + response.OkWithMessage(fmt.Sprintf("打包成功,文件路径为:%s", zipPath), c) +} + +// Packaged +// @Tags AutoCodePlugin +// @Summary 打包插件 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功" +// @Router /autoCode/initMenu [post] +func (a *AutoCodePluginApi) InitMenu(c *gin.Context) { + var menuInfo request.InitMenu + err := c.ShouldBindJSON(&menuInfo) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = autoCodePluginService.InitMenu(menuInfo) + if err != nil { + global.GVA_LOG.Error("创建初始化Menu失败!", zap.Error(err)) + response.FailWithMessage("创建初始化Menu失败"+err.Error(), c) + return + } + response.OkWithMessage("文件变更成功", c) +} + +// Packaged +// @Tags AutoCodePlugin +// @Summary 打包插件 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功" +// @Router /autoCode/initAPI [post] +func (a *AutoCodePluginApi) InitAPI(c *gin.Context) { + var apiInfo request.InitApi + err := c.ShouldBindJSON(&apiInfo) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = autoCodePluginService.InitAPI(apiInfo) + if err != nil { + global.GVA_LOG.Error("创建初始化API失败!", zap.Error(err)) + response.FailWithMessage("创建初始化API失败"+err.Error(), c) + return + } + response.OkWithMessage("文件变更成功", c) +} diff --git a/server/api/v1/system/auto_code_template.go b/server/api/v1/system/auto_code_template.go new file mode 100644 index 0000000000..18a5b9b5e7 --- /dev/null +++ b/server/api/v1/system/auto_code_template.go @@ -0,0 +1,108 @@ +package system + +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/utils" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +type AutoCodeTemplateApi struct{} + +// Preview +// @Tags AutoCodeTemplate +// @Summary 预览创建后的代码 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.AutoCode true "预览创建代码" +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "预览创建后的代码" +// @Router /autoCode/preview [post] +func (a *AutoCodeTemplateApi) Preview(c *gin.Context) { + var info request.AutoCode + err := c.ShouldBindJSON(&info) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = utils.Verify(info, utils.AutoCodeVerify) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = info.Pretreatment() + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + info.PackageT = utils.FirstUpper(info.Package) + autoCode, err := autoCodeTemplateService.Preview(c.Request.Context(), info) + if err != nil { + global.GVA_LOG.Error("预览失败!", zap.Error(err)) + response.FailWithMessage("预览失败", c) + } else { + response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c) + } +} + +// Create +// @Tags AutoCodeTemplate +// @Summary 自动代码模板 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.AutoCode true "创建自动代码" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Router /autoCode/createTemp [post] +func (a *AutoCodeTemplateApi) Create(c *gin.Context) { + var info request.AutoCode + err := c.ShouldBindJSON(&info) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = utils.Verify(info, utils.AutoCodeVerify) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = info.Pretreatment() + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = autoCodeTemplateService.Create(c.Request.Context(), info) + if err != nil { + global.GVA_LOG.Error("创建失败!", zap.Error(err)) + response.FailWithMessage(err.Error(), c) + } else { + response.OkWithMessage("创建成功", c) + } +} + +// Create +// @Tags AddFunc +// @Summary 增加方法 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.AutoCode true "增加方法" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Router /autoCode/addFunc [post] +func (a *AutoCodeTemplateApi) AddFunc(c *gin.Context) { + var info request.AutoFunc + err := c.ShouldBindJSON(&info) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = autoCodeTemplateService.AddFunc(info) + if err != nil { + global.GVA_LOG.Error("注入失败!", zap.Error(err)) + response.FailWithMessage("注入失败", c) + } else { + response.OkWithMessage("注入成功", c) + } +} diff --git a/server/api/v1/system/enter.go b/server/api/v1/system/enter.go index 1fdfc1ebc0..e496703d51 100644 --- a/server/api/v1/system/enter.go +++ b/server/api/v1/system/enter.go @@ -14,10 +14,13 @@ type ApiGroup struct { DictionaryApi AuthorityMenuApi OperationRecordApi - AutoCodeHistoryApi DictionaryDetailApi AuthorityBtnApi SysExportTemplateApi + AutoCodePluginApi + AutoCodePackageApi + AutoCodeHistoryApi + AutoCodeTemplateApi } var ( @@ -27,13 +30,16 @@ var ( 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 + authorityBtnService = service.ServiceGroupApp.SystemServiceGroup.AuthorityBtnService systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService - autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService - authorityBtnService = service.ServiceGroupApp.SystemServiceGroup.AuthorityBtnService + autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService + autoCodePluginService = service.ServiceGroupApp.SystemServiceGroup.AutoCodePlugin + autoCodePackageService = service.ServiceGroupApp.SystemServiceGroup.AutoCodePackage + autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistory + autoCodeTemplateService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeTemplate ) diff --git a/server/api/v1/system/sys_api.go b/server/api/v1/system/sys_api.go index 1a61d3b029..7c34f2cdb7 100644 --- a/server/api/v1/system/sys_api.go +++ b/server/api/v1/system/sys_api.go @@ -45,6 +45,97 @@ func (s *SystemApiApi) CreateApi(c *gin.Context) { response.OkWithMessage("创建成功", c) } +// SyncApi +// @Tags SysApi +// @Summary 同步API +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "同步API" +// @Router /api/syncApi [get] +func (s *SystemApiApi) SyncApi(c *gin.Context) { + newApis, deleteApis, ignoreApis, err := apiService.SyncApi() + if err != nil { + global.GVA_LOG.Error("同步失败!", zap.Error(err)) + response.FailWithMessage("同步失败", c) + return + } + response.OkWithData(gin.H{ + "newApis": newApis, + "deleteApis": deleteApis, + "ignoreApis": ignoreApis, + }, c) +} + +// GetApiGroups +// @Tags SysApi +// @Summary 获取API分组 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "获取API分组" +// @Router /api/getApiGroups [get] +func (s *SystemApiApi) GetApiGroups(c *gin.Context) { + groups, apiGroupMap, err := apiService.GetApiGroups() + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败", c) + return + } + response.OkWithData(gin.H{ + "groups": groups, + "apiGroupMap": apiGroupMap, + }, c) +} + +// IgnoreApi +// @Tags IgnoreApi +// @Summary 忽略API +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "同步API" +// @Router /api/ignoreApi [post] +func (s *SystemApiApi) IgnoreApi(c *gin.Context) { + var ignoreApi system.SysIgnoreApi + err := c.ShouldBindJSON(&ignoreApi) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = apiService.IgnoreApi(ignoreApi) + if err != nil { + global.GVA_LOG.Error("忽略失败!", zap.Error(err)) + response.FailWithMessage("忽略失败", c) + return + } + response.Ok(c) +} + +// EnterSyncApi +// @Tags SysApi +// @Summary 确认同步API +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "确认同步API" +// @Router /api/enterSyncApi [post] +func (s *SystemApiApi) EnterSyncApi(c *gin.Context) { + var syncApi systemRes.SysSyncApis + err := c.ShouldBindJSON(&syncApi) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = apiService.EnterSyncApi(syncApi) + if err != nil { + global.GVA_LOG.Error("忽略失败!", zap.Error(err)) + response.FailWithMessage("忽略失败", c) + return + } + response.Ok(c) +} + // DeleteApi // @Tags SysApi // @Summary 删除api @@ -179,7 +270,8 @@ func (s *SystemApiApi) UpdateApi(c *gin.Context) { // @Success 200 {object} response.Response{data=systemRes.SysAPIListResponse,msg=string} "获取所有的Api 不分页,返回包括api列表" // @Router /api/getAllApis [post] func (s *SystemApiApi) GetAllApis(c *gin.Context) { - apis, err := apiService.GetAllApis() + authorityID := utils.GetUserAuthorityId(c) + apis, err := apiService.GetAllApis(authorityID) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) diff --git a/server/api/v1/system/sys_authority.go b/server/api/v1/system/sys_authority.go index 9fcbddee58..b34fc3a0b4 100644 --- a/server/api/v1/system/sys_authority.go +++ b/server/api/v1/system/sys_authority.go @@ -2,7 +2,6 @@ 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" "github.com/flipped-aurora/gin-vue-admin/server/model/system" systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" @@ -37,6 +36,10 @@ func (a *AuthorityApi) CreateAuthority(c *gin.Context) { return } + if *authority.ParentId == 0 && global.GVA_CONFIG.System.UseStrictAuth { + authority.ParentId = utils.Pointer(utils.GetUserAuthorityId(c)) + } + if authBack, err = authorityService.CreateAuthority(authority); err != nil { global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败"+err.Error(), c) @@ -77,7 +80,8 @@ func (a *AuthorityApi) CopyAuthority(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - authBack, err := authorityService.CopyAuthority(copyInfo) + adminAuthorityID := utils.GetUserAuthorityId(c) + authBack, err := authorityService.CopyAuthority(adminAuthorityID, copyInfo) if err != nil { global.GVA_LOG.Error("拷贝失败!", zap.Error(err)) response.FailWithMessage("拷贝失败"+err.Error(), c) @@ -124,7 +128,7 @@ func (a *AuthorityApi) DeleteAuthority(c *gin.Context) { // @Produce application/json // @Param data body system.SysAuthority true "权限id, 权限名, 父角色id" // @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "更新角色信息,返回包括系统角色详情" -// @Router /authority/updateAuthority [post] +// @Router /authority/updateAuthority [put] func (a *AuthorityApi) UpdateAuthority(c *gin.Context) { var auth system.SysAuthority err := c.ShouldBindJSON(&auth) @@ -156,29 +160,14 @@ func (a *AuthorityApi) UpdateAuthority(c *gin.Context) { // @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取角色列表,返回包括列表,总数,页码,每页数量" // @Router /authority/getAuthorityList [post] func (a *AuthorityApi) GetAuthorityList(c *gin.Context) { - var pageInfo request.PageInfo - err := c.ShouldBindJSON(&pageInfo) - if err != nil { - response.FailWithMessage(err.Error(), c) - return - } - err = utils.Verify(pageInfo, utils.PageInfoVerify) - if err != nil { - response.FailWithMessage(err.Error(), c) - return - } - list, total, err := authorityService.GetAuthorityInfoList(pageInfo) + authorityID := utils.GetUserAuthorityId(c) + list, err := authorityService.GetAuthorityInfoList(authorityID) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败"+err.Error(), c) return } - response.OkWithDetailed(response.PageResult{ - List: list, - Total: total, - Page: pageInfo.Page, - PageSize: pageInfo.PageSize, - }, "获取成功", c) + response.OkWithDetailed(list, "获取成功", c) } // SetDataAuthority @@ -202,7 +191,8 @@ func (a *AuthorityApi) SetDataAuthority(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - err = authorityService.SetDataAuthority(auth) + adminAuthorityID := utils.GetUserAuthorityId(c) + err = authorityService.SetDataAuthority(adminAuthorityID, auth) if err != nil { global.GVA_LOG.Error("设置失败!", zap.Error(err)) response.FailWithMessage("设置失败"+err.Error(), c) diff --git a/server/api/v1/system/sys_auto_code.go b/server/api/v1/system/sys_auto_code.go index 4e80944be8..0d4b09add8 100644 --- a/server/api/v1/system/sys_auto_code.go +++ b/server/api/v1/system/sys_auto_code.go @@ -1,108 +1,19 @@ package system import ( - "errors" - "fmt" - "net/url" - "os" + "github.com/goccy/go-json" + "io" "strings" "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" - "github.com/flipped-aurora/gin-vue-admin/server/utils" - + "github.com/flipped-aurora/gin-vue-admin/server/utils/request" "github.com/gin-gonic/gin" "go.uber.org/zap" ) type AutoCodeApi struct{} -// PreviewTemp -// @Tags AutoCode -// @Summary 预览创建后的代码 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body system.AutoCodeStruct true "预览创建代码" -// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "预览创建后的代码" -// @Router /autoCode/preview [post] -func (autoApi *AutoCodeApi) PreviewTemp(c *gin.Context) { - var a system.AutoCodeStruct - _ = c.ShouldBindJSON(&a) - if err := utils.Verify(a, utils.AutoCodeVerify); err != nil { - response.FailWithMessage(err.Error(), c) - return - } - a.Pretreatment() // 处理go关键字 - a.PackageT = utils.FirstUpper(a.Package) - autoCode, err := autoCodeService.PreviewTemp(a) - if err != nil { - global.GVA_LOG.Error("预览失败!", zap.Error(err)) - response.FailWithMessage("预览失败", c) - } else { - response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c) - } -} - -// CreateTemp -// @Tags AutoCode -// @Summary 自动代码模板 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body system.AutoCodeStruct true "创建自动代码" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" -// @Router /autoCode/createTemp [post] -func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) { - var a system.AutoCodeStruct - _ = c.ShouldBindJSON(&a) - if err := utils.Verify(a, utils.AutoCodeVerify); err != nil { - response.FailWithMessage(err.Error(), c) - return - } - a.Pretreatment() - var apiIds []uint - var menuId uint - if a.AutoCreateApiToSql { - if ids, err := autoCodeService.AutoCreateApi(&a); err != nil { - global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err)) - c.Writer.Header().Add("success", "false") - c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!")) - return - } else { - apiIds = ids - } - } - if a.AutoCreateMenuToSql { - if id, err := autoCodeService.AutoCreateMenu(&a); err != nil { - global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err)) - c.Writer.Header().Add("success", "false") - c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!")) - } else { - menuId = id - } - } - a.PackageT = utils.FirstUpper(a.Package) - err := autoCodeService.CreateTemp(a, menuId, apiIds...) - if err != nil { - if errors.Is(err, system.ErrAutoMove) { - c.Writer.Header().Add("success", "true") - c.Writer.Header().Add("msg", url.QueryEscape(err.Error())) - } else { - c.Writer.Header().Add("success", "false") - c.Writer.Header().Add("msg", url.QueryEscape(err.Error())) - _ = os.Remove("./ginvueadmin.zip") - } - } else { - c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "ginvueadmin.zip")) // fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名 - c.Writer.Header().Add("Content-Type", "application/json") - c.Writer.Header().Add("success", "true") - c.File("./ginvueadmin.zip") - _ = os.Remove("./ginvueadmin.zip") - } -} - // GetDB // @Tags AutoCode // @Summary 获取当前所有数据库 @@ -110,7 +21,7 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) { // @accept application/json // @Produce application/json // @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库" -// @Router /autoCode/getDatabase [get] +// @Router /autoCode/getDB [get] func (autoApi *AutoCodeApi) GetDB(c *gin.Context) { businessDB := c.Query("businessDB") dbs, err := autoCodeService.Database(businessDB).GetDB(businessDB) @@ -140,8 +51,19 @@ func (autoApi *AutoCodeApi) GetDB(c *gin.Context) { // @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前数据库所有表" // @Router /autoCode/getTables [get] func (autoApi *AutoCodeApi) GetTables(c *gin.Context) { - dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) + dbName := c.Query("dbName") businessDB := c.Query("businessDB") + if dbName == "" { + dbName = *global.GVA_ACTIVE_DBNAME + if businessDB != "" { + for _, db := range global.GVA_CONFIG.DBList { + if db.AliasName == businessDB { + dbName = db.Dbname + } + } + } + } + tables, err := autoCodeService.Database(businessDB).GetTables(businessDB, dbName) if err != nil { global.GVA_LOG.Error("查询table失败!", zap.Error(err)) @@ -161,7 +83,17 @@ func (autoApi *AutoCodeApi) GetTables(c *gin.Context) { // @Router /autoCode/getColumn [get] func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) { businessDB := c.Query("businessDB") - dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) + dbName := c.Query("dbName") + if dbName == "" { + dbName = *global.GVA_ACTIVE_DBNAME + if businessDB != "" { + for _, db := range global.GVA_CONFIG.DBList { + if db.AliasName == businessDB { + dbName = db.Dbname + } + } + } + } tableName := c.Query("tableName") columns, err := autoCodeService.Database(businessDB).GetColumn(businessDB, tableName, dbName) if err != nil { @@ -172,164 +104,44 @@ func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) { } } -// CreatePackage -// @Tags AutoCode -// @Summary 创建package -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body system.SysAutoCode true "创建package" -// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功" -// @Router /autoCode/createPackage [post] -func (autoApi *AutoCodeApi) CreatePackage(c *gin.Context) { - var a system.SysAutoCode - _ = c.ShouldBindJSON(&a) - if err := utils.Verify(a, utils.AutoPackageVerify); err != nil { - response.FailWithMessage(err.Error(), c) - return - } - // PackageName可能导致路径穿越的问题 / 和 \ 都要防止 - if strings.Contains(a.PackageName, "\\") || strings.Contains(a.PackageName, "/") || strings.Contains(a.PackageName, "..") { - response.FailWithMessage("包名不合法", c) - return - } - - err := autoCodeService.CreateAutoCode(&a) +func (autoApi *AutoCodeApi) LLMAuto(c *gin.Context) { + prompt := c.Query("prompt") + mode := c.Query("mode") + params := make(map[string]string) + params["prompt"] = prompt + params["mode"] = mode + path := strings.ReplaceAll(global.GVA_CONFIG.AutoCode.AiPath, "{FUNC}", "api/chat/ai") + res, err := request.HttpRequest( + path, + "POST", + nil, + params, + nil, + ) if err != nil { - - global.GVA_LOG.Error("创建失败!", zap.Error(err)) - response.FailWithMessage("创建失败", c) - } else { - response.OkWithMessage("创建成功", c) - } -} - -// GetPackage -// @Tags AutoCode -// @Summary 获取package -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功" -// @Router /autoCode/getPackage [post] -func (autoApi *AutoCodeApi) GetPackage(c *gin.Context) { - pkgs, err := autoCodeService.GetPackage() - if err != nil { - global.GVA_LOG.Error("获取失败!", zap.Error(err)) - response.FailWithMessage("获取失败", c) - } else { - response.OkWithDetailed(gin.H{"pkgs": pkgs}, "获取成功", c) - } -} - -// DelPackage -// @Tags AutoCode -// @Summary 删除package -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body system.SysAutoCode true "创建package" -// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "删除package成功" -// @Router /autoCode/delPackage [post] -func (autoApi *AutoCodeApi) DelPackage(c *gin.Context) { - var a system.SysAutoCode - _ = c.ShouldBindJSON(&a) - err := autoCodeService.DelPackage(a) - if err != nil { - global.GVA_LOG.Error("删除失败!", zap.Error(err)) - response.FailWithMessage("删除失败", c) - } else { - response.OkWithMessage("删除成功", c) - } -} - -// AutoPlug -// @Tags AutoCode -// @Summary 创建插件模板 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body system.SysAutoCode true "创建插件模板" -// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建插件模板成功" -// @Router /autoCode/createPlug [post] -func (autoApi *AutoCodeApi) AutoPlug(c *gin.Context) { - var a system.AutoPlugReq - err := c.ShouldBindJSON(&a) - if err != nil { - response.FailWithMessage(err.Error(), c) + global.GVA_LOG.Error("大模型生成失败!", zap.Error(err)) + response.FailWithMessage("大模型生成失败"+err.Error(), c) return } - if strings.Contains(a.PlugName, "\\") || strings.Contains(a.PlugName, "/") || strings.Contains(a.PlugName, "..") { - response.FailWithMessage("插件名称不合法", c) - return - } - - a.Snake = strings.ToLower(a.PlugName) - a.NeedModel = a.HasRequest || a.HasResponse - err = autoCodeService.CreatePlug(a) - if err != nil { - global.GVA_LOG.Error("预览失败!", zap.Error(err)) - response.FailWithMessage("预览失败", c) - return - } - response.Ok(c) -} - -// InstallPlugin -// @Tags AutoCode -// @Summary 安装插件 -// @Security ApiKeyAuth -// @accept multipart/form-data -// @Produce application/json -// @Param plug formData file true "this is a test file" -// @Success 200 {object} response.Response{data=[]interface{},msg=string} "安装插件成功" -// @Router /autoCode/installPlugin [post] -func (autoApi *AutoCodeApi) InstallPlugin(c *gin.Context) { - header, err := c.FormFile("plug") + var resStruct response.Response + b, err := io.ReadAll(res.Body) + defer res.Body.Close() if err != nil { - response.FailWithMessage(err.Error(), c) + global.GVA_LOG.Error("大模型生成失败!", zap.Error(err)) + response.FailWithMessage("大模型生成失败"+err.Error(), c) return } - web, server, err := autoCodeService.InstallPlugin(header) - webStr := "web插件安装成功" - serverStr := "server插件安装成功" - if web == -1 { - webStr = "web端插件未成功安装,请按照文档自行解压安装,如果为纯后端插件请忽略此条提示" - } - if server == -1 { - serverStr = "server端插件未成功安装,请按照文档自行解压安装,如果为纯前端插件请忽略此条提示" - } + err = json.Unmarshal(b, &resStruct) if err != nil { - response.FailWithMessage(err.Error(), c) + global.GVA_LOG.Error("大模型生成失败!", zap.Error(err)) + response.FailWithMessage("大模型生成失败"+err.Error(), c) return } - response.OkWithData([]interface{}{ - gin.H{ - "code": web, - "msg": webStr, - }, - gin.H{ - "code": server, - "msg": serverStr, - }}, c) -} -// PubPlug -// @Tags AutoCode -// @Summary 打包插件 -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/json -// @Param data body system.SysAutoCode true "打包插件" -// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功" -// @Router /autoCode/pubPlug [get] -func (autoApi *AutoCodeApi) PubPlug(c *gin.Context) { - plugName := c.Query("plugName") - zipPath, err := autoCodeService.PubPlug(plugName) - if err != nil { - global.GVA_LOG.Error("打包失败!", zap.Error(err)) - response.FailWithMessage("打包失败"+err.Error(), c) + if resStruct.Code == 7 { + global.GVA_LOG.Error("大模型生成失败!"+resStruct.Msg, zap.Error(err)) + response.FailWithMessage("大模型生成失败"+resStruct.Msg, c) return } - response.OkWithMessage(fmt.Sprintf("打包成功,文件路径为:%s", zipPath), c) + response.OkWithData(resStruct.Data, c) } diff --git a/server/api/v1/system/sys_captcha.go b/server/api/v1/system/sys_captcha.go index c61714e591..b9f2110ecf 100644 --- a/server/api/v1/system/sys_captcha.go +++ b/server/api/v1/system/sys_captcha.go @@ -44,7 +44,7 @@ func (b *BaseApi) Captcha(c *gin.Context) { driver := base64Captcha.NewDriverDigit(global.GVA_CONFIG.Captcha.ImgHeight, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.KeyLong, 0.7, 80) // cp := base64Captcha.NewCaptcha(driver, store.UseWithCtx(c)) // v8下使用redis cp := base64Captcha.NewCaptcha(driver, store) - id, b64s, err := cp.Generate() + id, b64s, _, err := cp.Generate() if err != nil { global.GVA_LOG.Error("验证码获取失败!", zap.Error(err)) response.FailWithMessage("验证码获取失败", c) diff --git a/server/api/v1/system/sys_casbin.go b/server/api/v1/system/sys_casbin.go index 632718e2cf..c1bf54894b 100644 --- a/server/api/v1/system/sys_casbin.go +++ b/server/api/v1/system/sys_casbin.go @@ -33,7 +33,8 @@ func (cas *CasbinApi) UpdateCasbin(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - err = casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos) + adminAuthorityID := utils.GetUserAuthorityId(c) + err = casbinService.UpdateCasbin(adminAuthorityID, cmr.AuthorityId, cmr.CasbinInfos) if err != nil { global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败", c) diff --git a/server/api/v1/system/sys_export_template.go b/server/api/v1/system/sys_export_template.go index 4eaaf47bf5..38b22965be 100644 --- a/server/api/v1/system/sys_export_template.go +++ b/server/api/v1/system/sys_export_template.go @@ -2,6 +2,8 @@ package system import ( "fmt" + "net/http" + "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" @@ -11,7 +13,6 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/utils" "github.com/gin-gonic/gin" "go.uber.org/zap" - "net/http" ) type SysExportTemplateApi struct { @@ -206,7 +207,7 @@ func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) { } } -// ExportExcel 导出表格模板 +// ExportTemplate 导出表格模板 // @Tags SysExportTemplate // @Summary 导出表格模板 // @Security ApiKeyAuth @@ -229,7 +230,7 @@ func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplate(c *gin.Context) } } -// ExportExcel 导入表格 +// ImportExcel 导入表格 // @Tags SysImportTemplate // @Summary 导入表格 // @Security ApiKeyAuth diff --git a/server/api/v1/system/sys_menu.go b/server/api/v1/system/sys_menu.go index 8889ae7f7b..864b61f385 100644 --- a/server/api/v1/system/sys_menu.go +++ b/server/api/v1/system/sys_menu.go @@ -45,7 +45,8 @@ func (a *AuthorityMenuApi) GetMenu(c *gin.Context) { // @Success 200 {object} response.Response{data=systemRes.SysBaseMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单列表" // @Router /menu/getBaseMenuTree [post] func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) { - menus, err := menuService.GetBaseMenuTree() + authority := utils.GetUserAuthorityId(c) + menus, err := menuService.GetBaseMenuTree(authority) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) @@ -74,7 +75,8 @@ func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - if err := menuService.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil { + adminAuthorityID := utils.GetUserAuthorityId(c) + if err := menuService.AddMenuAuthority(authorityMenu.Menus, adminAuthorityID, authorityMenu.AuthorityId); err != nil { global.GVA_LOG.Error("添加失败!", zap.Error(err)) response.FailWithMessage("添加失败", c) } else { @@ -171,7 +173,7 @@ func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) { err = baseMenuService.DeleteBaseMenu(menu.ID) if err != nil { global.GVA_LOG.Error("删除失败!", zap.Error(err)) - response.FailWithMessage("删除失败", c) + response.FailWithMessage("删除失败:"+err.Error(), c) return } response.OkWithMessage("删除成功", c) @@ -252,27 +254,12 @@ func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) { // @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取基础menu列表,返回包括列表,总数,页码,每页数量" // @Router /menu/getMenuList [post] func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) { - var pageInfo request.PageInfo - err := c.ShouldBindJSON(&pageInfo) - if err != nil { - response.FailWithMessage(err.Error(), c) - return - } - err = utils.Verify(pageInfo, utils.PageInfoVerify) - if err != nil { - response.FailWithMessage(err.Error(), c) - return - } - menuList, total, err := menuService.GetInfoList() + authorityID := utils.GetUserAuthorityId(c) + menuList, err := menuService.GetInfoList(authorityID) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) return } - response.OkWithDetailed(response.PageResult{ - List: menuList, - Total: total, - Page: pageInfo.Page, - PageSize: pageInfo.PageSize, - }, "获取成功", c) + response.OkWithDetailed(menuList, "获取成功", c) } diff --git a/server/api/v1/system/sys_system.go b/server/api/v1/system/sys_system.go index af6ab71334..aa41c2f469 100644 --- a/server/api/v1/system/sys_system.go +++ b/server/api/v1/system/sys_system.go @@ -6,7 +6,6 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/model/system" systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" "github.com/flipped-aurora/gin-vue-admin/server/utils" - "github.com/gin-gonic/gin" "go.uber.org/zap" ) diff --git a/server/api/v1/system/sys_user.go b/server/api/v1/system/sys_user.go index 77ba26f623..a8d2ea43d0 100644 --- a/server/api/v1/system/sys_user.go +++ b/server/api/v1/system/sys_user.go @@ -1,6 +1,7 @@ package system import ( + "gorm.io/datatypes" "strconv" "time" @@ -76,15 +77,7 @@ func (b *BaseApi) Login(c *gin.Context) { // TokenNext 登录以后签发jwt func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) { - j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 - claims := j.CreateClaims(systemReq.BaseClaims{ - UUID: user.UUID, - ID: user.ID, - NickName: user.NickName, - Username: user.Username, - AuthorityId: user.AuthorityId, - }) - token, err := j.CreateToken(claims) + token, claims, err := utils.LoginToken(&user) if err != nil { global.GVA_LOG.Error("获取token失败!", zap.Error(err)) response.FailWithMessage("获取token失败", c) @@ -122,7 +115,7 @@ func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) { response.FailWithMessage("jwt作废失败", c) return } - if err := jwtService.SetRedisJWT(token, user.Username); err != nil { + if err := jwtService.SetRedisJWT(token, user.GetUsername()); err != nil { response.FailWithMessage("设置登录状态失败", c) return } @@ -293,7 +286,8 @@ func (b *BaseApi) SetUserAuthorities(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - err = userService.SetUserAuthorities(sua.ID, sua.AuthorityIds) + authorityID := utils.GetUserAuthorityId(c) + err = userService.SetUserAuthorities(authorityID, sua.ID, sua.AuthorityIds) if err != nil { global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage("修改失败", c) @@ -358,9 +352,9 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - if len(user.AuthorityIds) != 0 { - err = userService.SetUserAuthorities(user.ID, user.AuthorityIds) + authorityID := utils.GetUserAuthorityId(c) + err = userService.SetUserAuthorities(authorityID, user.ID, user.AuthorityIds) if err != nil { global.GVA_LOG.Error("设置失败!", zap.Error(err)) response.FailWithMessage("设置失败", c) @@ -375,7 +369,6 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) { HeaderImg: user.HeaderImg, Phone: user.Phone, Email: user.Email, - SideMode: user.SideMode, Enable: user.Enable, }) if err != nil { @@ -411,7 +404,6 @@ func (b *BaseApi) SetSelfInfo(c *gin.Context) { HeaderImg: user.HeaderImg, Phone: user.Phone, Email: user.Email, - SideMode: user.SideMode, Enable: user.Enable, }) if err != nil { @@ -422,6 +414,32 @@ func (b *BaseApi) SetSelfInfo(c *gin.Context) { response.OkWithMessage("设置成功", c) } +// SetSelfSetting +// @Tags SysUser +// @Summary 设置用户配置 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body map[string]interface{} true "用户配置数据" +// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户配置" +// @Router /user/SetSelfSetting [put] +func (b *BaseApi) SetSelfSetting(c *gin.Context) { + var req datatypes.JSON + err := c.ShouldBindJSON(&req) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + + err = userService.SetSelfSetting(&req, utils.GetUserID(c)) + if err != nil { + global.GVA_LOG.Error("设置失败!", zap.Error(err)) + response.FailWithMessage("设置失败", c) + return + } + response.OkWithMessage("设置成功", c) +} + // GetUserInfo // @Tags SysUser // @Summary 获取用户信息 diff --git a/server/config.yaml b/server/config.yaml index 7b1a73abd0..b532a8cbb8 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -16,6 +16,7 @@ zap: encode-level: LowercaseColorLevelEncoder stacktrace-key: stacktrace log-in-console: true + retention-day: -1 # redis configuration redis: @@ -30,6 +31,17 @@ redis: - "172.21.0.4:7001" - "172.21.0.2:7002" +# redis-list configuration +redis-list: + - name: cache # 数据库的名称,注意: name 需要在 redis-list 中唯一 + useCluster: false # 是否使用redis集群模式 + addr: 127.0.0.1:6379 # 使用集群模式addr和db默认无效 + password: "" + db: 0 + clusterAddrs: + - "172.21.0.3:7000" + - "172.21.0.4:7001" + - "172.21.0.2:7002" # mongo configuration mongo: @@ -73,6 +85,8 @@ system: iplimit-time: 3600 # 路由全局前缀 router-prefix: "" + # 严格角色模式 打开后权限将会存在上下级关系 + use-strict-auth: false # captcha configuration captcha: @@ -164,22 +178,11 @@ local: # autocode configuration autocode: - transfer-restart: true - # root 自动适配项目根目录 - # 请不要手动配置,他会在项目加载的时候识别出根路径 - root: "" - server: /server - server-plug: /plugin/%s - server-api: /api/v1/%s - server-initialize: /initialize - server-model: /model/%s - server-request: /model/%s/request/ - server-router: /router/%s - server-service: /service/%s - web: /web/src - web-api: /api - web-form: /view - web-table: /view + web: web/src + root: "" # root 自动适配项目根目录, 请不要手动配置,他会在项目加载的时候识别出根路径 + server: server + module: 'github.com/flipped-aurora/gin-vue-admin/server' + ai-path: "" # AI服务路径 # qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址) qiniu: @@ -221,6 +224,15 @@ aws-s3: base-url: https://gin.vue.admin path-prefix: github.com/flipped-aurora/gin-vue-admin/server +# cloudflare r2 configuration +cloudflare-r2: + bucket: xxxx0bucket + base-url: https://gin.vue.admin.com + path: uploads + account-id: xxx_account_id + access-key-id: xxx_key_id + secret-access-key: xxx_secret_key + # huawei obs configuration hua-wei-obs: path: you-path @@ -233,6 +245,10 @@ hua-wei-obs: excel: dir: ./resource/excel/ +# disk usage configuration +disk-list: + - mount-point: "/" + # 跨域配置 # 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用 cors: @@ -248,4 +264,4 @@ cors: 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-credentials: true # 布尔值 \ No newline at end of file diff --git a/server/config/auto_code.go b/server/config/auto_code.go index d39d7af8eb..ade79a023e 100644 --- a/server/config/auto_code.go +++ b/server/config/auto_code.go @@ -1,18 +1,22 @@ package config +import ( + "path/filepath" + "strings" +) + type Autocode struct { - SModel string `mapstructure:"server-model" json:"server-model" yaml:"server-model"` - SRouter string `mapstructure:"server-router" json:"server-router" yaml:"server-router"` - Server string `mapstructure:"server" json:"server" yaml:"server"` - SApi string `mapstructure:"server-api" json:"server-api" yaml:"server-api"` - SPlug string `mapstructure:"server-plug" json:"server-plug" yaml:"server-plug"` - SInitialize string `mapstructure:"server-initialize" json:"server-initialize" yaml:"server-initialize"` - Root string `mapstructure:"root" json:"root" yaml:"root"` - WTable string `mapstructure:"web-table" json:"web-table" yaml:"web-table"` - Web string `mapstructure:"web" json:"web" yaml:"web"` - SService string `mapstructure:"server-service" json:"server-service" yaml:"server-service"` - SRequest string `mapstructure:"server-request" json:"server-request" yaml:"server-request"` - WApi string `mapstructure:"web-api" json:"web-api" yaml:"web-api"` - WForm string `mapstructure:"web-form" json:"web-form" yaml:"web-form"` - TransferRestart bool `mapstructure:"transfer-restart" json:"transfer-restart" yaml:"transfer-restart"` + Web string `mapstructure:"web" json:"web" yaml:"web"` + Root string `mapstructure:"root" json:"root" yaml:"root"` + Server string `mapstructure:"server" json:"server" yaml:"server"` + Module string `mapstructure:"module" json:"module" yaml:"module"` + AiPath string `mapstructure:"ai-path" json:"ai-path" yaml:"ai-path"` +} + +func (a *Autocode) WebRoot() string { + webs := strings.Split(a.Web, "/") + if len(webs) == 0 { + webs = strings.Split(a.Web, "\\") + } + return filepath.Join(webs...) } diff --git a/server/config/config.go b/server/config/config.go index edb7486cd9..6519333cb3 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -1,13 +1,14 @@ package config type Server struct { - JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"` - Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"` - Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"` - Mongo Mongo `mapstructure:"mongo" json:"mongo" yaml:"mongo"` - Email Email `mapstructure:"email" json:"email" yaml:"email"` - System System `mapstructure:"system" json:"system" yaml:"system"` - Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"` + JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"` + Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"` + Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"` + RedisList []Redis `mapstructure:"redis-list" json:"redis-list" yaml:"redis-list"` + Mongo Mongo `mapstructure:"mongo" json:"mongo" yaml:"mongo"` + Email Email `mapstructure:"email" json:"email" yaml:"email"` + System System `mapstructure:"system" json:"system" yaml:"system"` + Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"` // auto AutoCode Autocode `mapstructure:"autocode" json:"autocode" yaml:"autocode"` // gorm @@ -18,15 +19,18 @@ type Server struct { Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"` DBList []SpecializedDB `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:"aliyun-oss" yaml:"aliyun-oss"` - HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"hua-wei-obs" yaml:"hua-wei-obs"` - TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencent-cos" yaml:"tencent-cos"` - AwsS3 AwsS3 `mapstructure:"aws-s3" json:"aws-s3" yaml:"aws-s3"` + Local Local `mapstructure:"local" json:"local" yaml:"local"` + Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"` + AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyun-oss" yaml:"aliyun-oss"` + HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"hua-wei-obs" yaml:"hua-wei-obs"` + TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencent-cos" yaml:"tencent-cos"` + AwsS3 AwsS3 `mapstructure:"aws-s3" json:"aws-s3" yaml:"aws-s3"` + CloudflareR2 CloudflareR2 `mapstructure:"cloudflare-r2" json:"cloudflare-r2" yaml:"cloudflare-r2"` Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` + DiskList []DiskList `mapstructure:"disk-list" json:"disk-list" yaml:"disk-list"` + // 跨域配置 Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"` } diff --git a/server/config/db_list.go b/server/config/db_list.go index 17eaac9656..39767f53bf 100644 --- a/server/config/db_list.go +++ b/server/config/db_list.go @@ -1,5 +1,10 @@ package config +import ( + "gorm.io/gorm/logger" + "strings" +) + type DsnProvider interface { Dsn() string } @@ -9,21 +14,36 @@ type DsnProvider interface { // GeneralDB 也被 Pgsql 和 Mysql 原样使用 type GeneralDB struct { - Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` - Port string `mapstructure:"port" json:"port" yaml:"port"` - Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 - Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名 - Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库密码 - Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码 - Path string `mapstructure:"path" json:"path" yaml:"path"` - Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` //数据库引擎,默认InnoDB + Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 数据库前缀 + Port string `mapstructure:"port" json:"port" yaml:"port"` // 数据库端口 + Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 + Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名 + Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库账号 + Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码 + Path string `mapstructure:"path" json:"path" yaml:"path"` // 数据库地址 + Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` // 数据库引擎,默认InnoDB LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志 MaxIdleConns int `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数 MaxOpenConns int `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数 - Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` //是否开启全局禁用复数,true表示开启 + Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` // 是否开启全局禁用复数,true表示开启 LogZap bool `mapstructure:"log-zap" json:"log-zap" yaml:"log-zap"` // 是否通过zap写入日志文件 } +func (c GeneralDB) LogLevel() logger.LogLevel { + switch strings.ToLower(c.LogMode) { + case "silent", "Silent": + return logger.Silent + case "error", "Error": + return logger.Error + case "warn", "Warn": + return logger.Warn + case "info", "Info": + return logger.Info + default: + return logger.Info + } +} + type SpecializedDB struct { Type string `mapstructure:"type" json:"type" yaml:"type"` AliasName string `mapstructure:"alias-name" json:"alias-name" yaml:"alias-name"` diff --git a/server/config/disk.go b/server/config/disk.go new file mode 100644 index 0000000000..59a633259d --- /dev/null +++ b/server/config/disk.go @@ -0,0 +1,9 @@ +package config + +type Disk struct { + MountPoint string `mapstructure:"mount-point" json:"mount-point" yaml:"mount-point"` +} + +type DiskList struct { + Disk `yaml:",inline" mapstructure:",squash"` +} diff --git a/server/config/gorm_mssql.go b/server/config/gorm_mssql.go index db299e1e34..d187119484 100644 --- a/server/config/gorm_mssql.go +++ b/server/config/gorm_mssql.go @@ -3,11 +3,8 @@ package config type Mssql struct { GeneralDB `yaml:",inline" mapstructure:",squash"` } -//dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" + +// Dsn "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" func (m *Mssql) Dsn() string { return "sqlserver://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "?database=" + m.Dbname + "&encrypt=disable" } - -func (m *Mssql) GetLogMode() string { - return m.LogMode -} diff --git a/server/config/gorm_mysql.go b/server/config/gorm_mysql.go index 86911f37eb..77e0245391 100644 --- a/server/config/gorm_mysql.go +++ b/server/config/gorm_mysql.go @@ -7,7 +7,3 @@ type Mysql struct { func (m *Mysql) Dsn() string { return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config } - -func (m *Mysql) GetLogMode() string { - return m.LogMode -} diff --git a/server/config/gorm_oracle.go b/server/config/gorm_oracle.go index 44f9051c8a..1bbeb46abe 100644 --- a/server/config/gorm_oracle.go +++ b/server/config/gorm_oracle.go @@ -8,7 +8,3 @@ func (m *Oracle) Dsn() string { return "oracle://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "/" + m.Dbname + "?" + m.Config } - -func (m *Oracle) GetLogMode() string { - return m.LogMode -} diff --git a/server/config/gorm_pgsql.go b/server/config/gorm_pgsql.go index 17c5f5e95a..29fe03f43b 100644 --- a/server/config/gorm_pgsql.go +++ b/server/config/gorm_pgsql.go @@ -15,7 +15,3 @@ func (p *Pgsql) Dsn() string { func (p *Pgsql) LinkDsn(dbname string) string { return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + dbname + " port=" + p.Port + " " + p.Config } - -func (m *Pgsql) GetLogMode() string { - return m.LogMode -} diff --git a/server/config/gorm_sqlite.go b/server/config/gorm_sqlite.go index 5eebcae40b..46f2e19a5c 100644 --- a/server/config/gorm_sqlite.go +++ b/server/config/gorm_sqlite.go @@ -11,7 +11,3 @@ type Sqlite struct { func (s *Sqlite) Dsn() string { return filepath.Join(s.Path, s.Dbname+".db") } - -func (s *Sqlite) GetLogMode() string { - return s.LogMode -} diff --git a/server/config/oss_cloudflare.go b/server/config/oss_cloudflare.go new file mode 100644 index 0000000000..ab7a393dd5 --- /dev/null +++ b/server/config/oss_cloudflare.go @@ -0,0 +1,10 @@ +package config + +type CloudflareR2 struct { + Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` + BaseURL string `mapstructure:"base-url" json:"base-url" yaml:"base-url"` + Path string `mapstructure:"path" json:"path" yaml:"path"` + AccountID string `mapstructure:"account-id" json:"account-id" yaml:"account-id"` + AccessKeyID string `mapstructure:"access-key-id" json:"access-key-id" yaml:"access-key-id"` + SecretAccessKey string `mapstructure:"secret-access-key" json:"secret-access-key" yaml:"secret-access-key"` +} diff --git a/server/config/redis.go b/server/config/redis.go index 33c0ccbbb8..94b5bf6b59 100644 --- a/server/config/redis.go +++ b/server/config/redis.go @@ -1,6 +1,7 @@ package config type Redis struct { + Name string `mapstructure:"name" json:"name" yaml:"name"` // 代表当前实例的名字 Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口 Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码 DB int `mapstructure:"db" json:"db" yaml:"db"` // 单实例模式下redis的哪个数据库 diff --git a/server/config/system.go b/server/config/system.go index 398bf789b7..b47dbf64e6 100644 --- a/server/config/system.go +++ b/server/config/system.go @@ -7,7 +7,8 @@ type System struct { Addr int `mapstructure:"addr" json:"addr" yaml:"addr"` // 端口值 LimitCountIP int `mapstructure:"iplimit-count" json:"iplimit-count" yaml:"iplimit-count"` LimitTimeIP int `mapstructure:"iplimit-time" json:"iplimit-time" yaml:"iplimit-time"` - UseMultipoint bool `mapstructure:"use-multipoint" json:"use-multipoint" yaml:"use-multipoint"` // 多点登录拦截 - UseRedis bool `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"` // 使用redis - UseMongo bool `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo"` // 使用mongo + UseMultipoint bool `mapstructure:"use-multipoint" json:"use-multipoint" yaml:"use-multipoint"` // 多点登录拦截 + UseRedis bool `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"` // 使用redis + UseMongo bool `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo"` // 使用mongo + UseStrictAuth bool `mapstructure:"use-strict-auth" json:"use-strict-auth" yaml:"use-strict-auth"` // 使用树形角色分配模式 } diff --git a/server/config/zap.go b/server/config/zap.go index eefa48a66a..0e8ae2b293 100644 --- a/server/config/zap.go +++ b/server/config/zap.go @@ -2,7 +2,7 @@ package config import ( "go.uber.org/zap/zapcore" - "strings" + "time" ) type Zap struct { @@ -12,49 +12,60 @@ type Zap struct { Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹 EncodeLevel string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"` // 编码级 StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名 + ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行 + LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台 + RetentionDay int `mapstructure:"retention-day" json:"retention-day" yaml:"retention-day"` // 日志保留天数 +} - MaxAge int `mapstructure:"max-age" json:"max-age" yaml:"max-age"` // 日志留存时间 - ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行 - LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台 +// Levels 根据字符串转化为 zapcore.Levels +func (c *Zap) Levels() []zapcore.Level { + levels := make([]zapcore.Level, 0, 7) + level, err := zapcore.ParseLevel(c.Level) + if err != nil { + level = zapcore.DebugLevel + } + for ; level <= zapcore.FatalLevel; level++ { + levels = append(levels, level) + } + return levels } -// ZapEncodeLevel 根据 EncodeLevel 返回 zapcore.LevelEncoder +func (c *Zap) Encoder() zapcore.Encoder { + config := zapcore.EncoderConfig{ + TimeKey: "time", + NameKey: "name", + LevelKey: "level", + CallerKey: "caller", + MessageKey: "message", + StacktraceKey: c.StacktraceKey, + LineEnding: zapcore.DefaultLineEnding, + EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) { + encoder.AppendString(c.Prefix + t.Format("2006-01-02 15:04:05.000")) + }, + EncodeLevel: c.LevelEncoder(), + EncodeCaller: zapcore.FullCallerEncoder, + EncodeDuration: zapcore.SecondsDurationEncoder, + } + if c.Format == "json" { + return zapcore.NewJSONEncoder(config) + } + return zapcore.NewConsoleEncoder(config) + +} + +// LevelEncoder 根据 EncodeLevel 返回 zapcore.LevelEncoder // Author [SliverHorn](https://github.com/SliverHorn) -func (z *Zap) ZapEncodeLevel() zapcore.LevelEncoder { +func (c *Zap) LevelEncoder() zapcore.LevelEncoder { switch { - case z.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认) + case c.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认) return zapcore.LowercaseLevelEncoder - case z.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色 + case c.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色 return zapcore.LowercaseColorLevelEncoder - case z.EncodeLevel == "CapitalLevelEncoder": // 大写编码器 + case c.EncodeLevel == "CapitalLevelEncoder": // 大写编码器 return zapcore.CapitalLevelEncoder - case z.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色 + case c.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色 return zapcore.CapitalColorLevelEncoder default: return zapcore.LowercaseLevelEncoder } } - -// TransportLevel 根据字符串转化为 zapcore.Level -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *Zap) TransportLevel() zapcore.Level { - z.Level = strings.ToLower(z.Level) - switch z.Level { - case "debug": - return zapcore.DebugLevel - case "info": - return zapcore.InfoLevel - case "warn": - return zapcore.WarnLevel - case "error": - return zapcore.ErrorLevel - case "dpanic": - return zapcore.DPanicLevel - case "panic": - return zapcore.PanicLevel - case "fatal": - return zapcore.FatalLevel - default: - return zapcore.DebugLevel - } -} diff --git a/server/core/internal/cutter.go b/server/core/internal/cutter.go index 721a94bde1..e053af6e5d 100644 --- a/server/core/internal/cutter.go +++ b/server/core/internal/cutter.go @@ -3,34 +3,46 @@ package internal import ( "os" "path/filepath" - "regexp" - "strings" "sync" "time" ) +// Cutter 实现 io.Writer 接口 +// 用于日志切割, strings.Join([]string{director,layout, formats..., level+".log"}, os.PathSeparator) type Cutter struct { - level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal) - format string // 时间格式(2006-01-02) - Director string // 日志文件夹 - file *os.File // 文件句柄 - mutex *sync.RWMutex // 读写锁 + level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal) + layout string // 时间格式 2006-01-02 15:04:05 + formats []string // 自定义参数([]string{Director,"2006-01-02", "business"(此参数可不写), level+".log"} + director string // 日志文件夹 + retentionDay int //日志保留天数 + file *os.File // 文件句柄 + mutex *sync.RWMutex // 读写锁 } type CutterOption func(*Cutter) -// WithCutterFormat 设置时间格式 -func WithCutterFormat(format string) CutterOption { +// CutterWithLayout 时间格式 +func CutterWithLayout(layout string) CutterOption { return func(c *Cutter) { - c.format = format + c.layout = layout } } -func NewCutter(director string, level string, options ...CutterOption) *Cutter { +// CutterWithFormats 格式化参数 +func CutterWithFormats(format ...string) CutterOption { + return func(c *Cutter) { + if len(format) > 0 { + c.formats = format + } + } +} + +func NewCutter(director string, level string, retentionDay int, options ...CutterOption) *Cutter { rotate := &Cutter{ - level: level, - Director: director, - mutex: new(sync.RWMutex), + level: level, + director: director, + retentionDay: retentionDay, + mutex: new(sync.RWMutex), } for i := 0; i < len(options); i++ { options[i](rotate) @@ -51,41 +63,23 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) { } c.mutex.Unlock() }() - var business string - if strings.Contains(string(bytes), "business") { - var compile *regexp.Regexp - compile, err = regexp.Compile(`{"business": "([^,]+)"}`) - if err != nil { - return 0, err - } - if compile.Match(bytes) { - finds := compile.FindSubmatch(bytes) - business = string(finds[len(finds)-1]) - bytes = compile.ReplaceAll(bytes, []byte("")) - } - compile, err = regexp.Compile(`"business": "([^,]+)"`) - if err != nil { - return 0, err - } - if compile.Match(bytes) { - finds := compile.FindSubmatch(bytes) - business = string(finds[len(finds)-1]) - bytes = compile.ReplaceAll(bytes, []byte("")) - } + length := len(c.formats) + values := make([]string, 0, 3+length) + values = append(values, c.director) + if c.layout != "" { + values = append(values, time.Now().Format(c.layout)) } - format := time.Now().Format(c.format) - formats := make([]string, 0, 4) - formats = append(formats, c.Director) - if format != "" { - formats = append(formats, format) + for i := 0; i < length; i++ { + values = append(values, c.formats[i]) } - if business != "" { - formats = append(formats, business) + values = append(values, c.level+".log") + filename := filepath.Join(values...) + director := filepath.Dir(filename) + err = os.MkdirAll(director, os.ModePerm) + if err != nil { + return 0, err } - formats = append(formats, c.level+".log") - filename := filepath.Join(formats...) - dirname := filepath.Dir(filename) - err = os.MkdirAll(dirname, 0755) + err = removeNDaysFolders(c.director, c.retentionDay) if err != nil { return 0, err } @@ -95,3 +89,33 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) { } return c.file.Write(bytes) } + +func (c *Cutter) Sync() error { + c.mutex.Lock() + defer c.mutex.Unlock() + + if c.file != nil { + return c.file.Sync() + } + return nil +} + +// 增加日志目录文件清理 小于等于零的值默认忽略不再处理 +func removeNDaysFolders(dir string, days int) error { + if days <= 0 { + return nil + } + cutoff := time.Now().AddDate(0, 0, -days) + return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() && info.ModTime().Before(cutoff) && path != dir { + err = os.RemoveAll(path) + if err != nil { + return err + } + } + return nil + }) +} diff --git a/server/core/internal/file_rotatelogs.go b/server/core/internal/file_rotatelogs.go deleted file mode 100644 index 5d463e0211..0000000000 --- a/server/core/internal/file_rotatelogs.go +++ /dev/null @@ -1,21 +0,0 @@ -package internal - -import ( - "github.com/flipped-aurora/gin-vue-admin/server/global" - "go.uber.org/zap/zapcore" - "os" -) - -var FileRotatelogs = new(fileRotatelogs) - -type fileRotatelogs struct{} - -// GetWriteSyncer 获取 zapcore.WriteSyncer -// Author [SliverHorn](https://github.com/SliverHorn) -func (r *fileRotatelogs) GetWriteSyncer(level string) zapcore.WriteSyncer { - fileWriter := NewCutter(global.GVA_CONFIG.Zap.Director, level, WithCutterFormat("2006-01-02")) - if global.GVA_CONFIG.Zap.LogInConsole { - return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)) - } - return zapcore.AddSync(fileWriter) -} diff --git a/server/core/internal/zap.go b/server/core/internal/zap.go deleted file mode 100644 index 92c9f4b84d..0000000000 --- a/server/core/internal/zap.go +++ /dev/null @@ -1,101 +0,0 @@ -package internal - -import ( - "github.com/flipped-aurora/gin-vue-admin/server/global" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" - "time" -) - -var Zap = new(_zap) - -type _zap struct{} - -// GetEncoder 获取 zapcore.Encoder -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *_zap) GetEncoder() zapcore.Encoder { - if global.GVA_CONFIG.Zap.Format == "json" { - return zapcore.NewJSONEncoder(z.GetEncoderConfig()) - } - return zapcore.NewConsoleEncoder(z.GetEncoderConfig()) -} - -// GetEncoderConfig 获取zapcore.EncoderConfig -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *_zap) GetEncoderConfig() zapcore.EncoderConfig { - return zapcore.EncoderConfig{ - MessageKey: "message", - LevelKey: "level", - TimeKey: "time", - NameKey: "logger", - CallerKey: "caller", - StacktraceKey: global.GVA_CONFIG.Zap.StacktraceKey, - LineEnding: zapcore.DefaultLineEnding, - EncodeLevel: global.GVA_CONFIG.Zap.ZapEncodeLevel(), - EncodeTime: z.CustomTimeEncoder, - EncodeDuration: zapcore.SecondsDurationEncoder, - EncodeCaller: zapcore.FullCallerEncoder, - } -} - -// GetEncoderCore 获取Encoder的 zapcore.Core -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *_zap) GetEncoderCore(l zapcore.Level, level zap.LevelEnablerFunc) zapcore.Core { - writer := FileRotatelogs.GetWriteSyncer(l.String()) // 日志分割 - return zapcore.NewCore(z.GetEncoder(), writer, level) -} - -// CustomTimeEncoder 自定义日志输出时间格式 -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *_zap) CustomTimeEncoder(t time.Time, encoder zapcore.PrimitiveArrayEncoder) { - encoder.AppendString(global.GVA_CONFIG.Zap.Prefix + t.Format("2006/01/02 - 15:04:05.000")) -} - -// GetZapCores 根据配置文件的Level获取 []zapcore.Core -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *_zap) GetZapCores() []zapcore.Core { - cores := make([]zapcore.Core, 0, 7) - for level := global.GVA_CONFIG.Zap.TransportLevel(); level <= zapcore.FatalLevel; level++ { - cores = append(cores, z.GetEncoderCore(level, z.GetLevelPriority(level))) - } - return cores -} - -// GetLevelPriority 根据 zapcore.Level 获取 zap.LevelEnablerFunc -// Author [SliverHorn](https://github.com/SliverHorn) -func (z *_zap) GetLevelPriority(level zapcore.Level) zap.LevelEnablerFunc { - switch level { - case zapcore.DebugLevel: - return func(level zapcore.Level) bool { // 调试级别 - return level == zap.DebugLevel - } - case zapcore.InfoLevel: - return func(level zapcore.Level) bool { // 日志级别 - return level == zap.InfoLevel - } - case zapcore.WarnLevel: - return func(level zapcore.Level) bool { // 警告级别 - return level == zap.WarnLevel - } - case zapcore.ErrorLevel: - return func(level zapcore.Level) bool { // 错误级别 - return level == zap.ErrorLevel - } - case zapcore.DPanicLevel: - return func(level zapcore.Level) bool { // dpanic级别 - return level == zap.DPanicLevel - } - case zapcore.PanicLevel: - return func(level zapcore.Level) bool { // panic级别 - return level == zap.PanicLevel - } - case zapcore.FatalLevel: - return func(level zapcore.Level) bool { // 终止级别 - return level == zap.FatalLevel - } - default: - return func(level zapcore.Level) bool { // 调试级别 - return level == zap.DebugLevel - } - } -} diff --git a/server/core/internal/zap_core.go b/server/core/internal/zap_core.go new file mode 100644 index 0000000000..4648e60cba --- /dev/null +++ b/server/core/internal/zap_core.go @@ -0,0 +1,68 @@ +package internal + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "os" + "time" +) + +type ZapCore struct { + level zapcore.Level + zapcore.Core +} + +func NewZapCore(level zapcore.Level) *ZapCore { + entity := &ZapCore{level: level} + syncer := entity.WriteSyncer() + levelEnabler := zap.LevelEnablerFunc(func(l zapcore.Level) bool { + return l == level + }) + entity.Core = zapcore.NewCore(global.GVA_CONFIG.Zap.Encoder(), syncer, levelEnabler) + return entity +} + +func (z *ZapCore) WriteSyncer(formats ...string) zapcore.WriteSyncer { + cutter := NewCutter( + global.GVA_CONFIG.Zap.Director, + z.level.String(), + global.GVA_CONFIG.Zap.RetentionDay, + CutterWithLayout(time.DateOnly), + CutterWithFormats(formats...), + ) + if global.GVA_CONFIG.Zap.LogInConsole { + multiSyncer := zapcore.NewMultiWriteSyncer(os.Stdout, cutter) + return zapcore.AddSync(multiSyncer) + } + return zapcore.AddSync(cutter) +} + +func (z *ZapCore) Enabled(level zapcore.Level) bool { + return z.level == level +} + +func (z *ZapCore) With(fields []zapcore.Field) zapcore.Core { + return z.Core.With(fields) +} + +func (z *ZapCore) Check(entry zapcore.Entry, check *zapcore.CheckedEntry) *zapcore.CheckedEntry { + if z.Enabled(entry.Level) { + return check.AddCore(entry, z) + } + return check +} + +func (z *ZapCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { + for i := 0; i < len(fields); i++ { + if fields[i].Key == "business" || fields[i].Key == "folder" || fields[i].Key == "directory" { + syncer := z.WriteSyncer(fields[i].String) + z.Core = zapcore.NewCore(global.GVA_CONFIG.Zap.Encoder(), syncer, z.level) + } + } + return z.Core.Write(entry, fields) +} + +func (z *ZapCore) Sync() error { + return z.Core.Sync() +} diff --git a/server/core/server.go b/server/core/server.go index 9b7bd252ec..5107a5f9eb 100644 --- a/server/core/server.go +++ b/server/core/server.go @@ -16,7 +16,9 @@ func RunWindowsServer() { if global.GVA_CONFIG.System.UseMultipoint || global.GVA_CONFIG.System.UseRedis { // 初始化redis服务 initialize.Redis() + initialize.RedisList() } + if global.GVA_CONFIG.System.UseMongo { err := initialize.Mongo.Initialization() if err != nil { @@ -38,13 +40,17 @@ func RunWindowsServer() { fmt.Printf(` 欢迎使用 gin-vue-admin - 当前版本:v2.6.2 + 当前版本:v2.7.4 加群方式:微信号:shouzi_1994 QQ群:470239250 + 项目地址:https://github.com/flipped-aurora/gin-vue-admin 插件市场:https://plugin.gin-vue-admin.com GVA讨论社区:https://support.qq.com/products/371961 默认自动化文档地址:http://127.0.0.1%s/swagger/index.html 默认前端文件运行地址:http://127.0.0.1:8080 - 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/coffee/index.html + --------------------------------------版权声明-------------------------------------- + ** 版权所有方:flipped-aurora开源团队 ** + ** 版权持有公司:北京翻转极光科技有限责任公司 ** + ** 剔除授权标识需购买商用授权:https://gin-vue-admin.com/empower/index.html ** `, address) global.GVA_LOG.Error(s.ListenAndServe().Error()) } diff --git a/server/core/server_other.go b/server/core/server_other.go index b95e901163..83645fced0 100644 --- a/server/core/server_other.go +++ b/server/core/server_other.go @@ -12,8 +12,8 @@ import ( func initServer(address string, router *gin.Engine) server { s := endless.NewServer(address, router) - s.ReadHeaderTimeout = 20 * time.Second - s.WriteTimeout = 20 * time.Second + s.ReadHeaderTimeout = 10 * time.Minute + s.WriteTimeout = 10 * time.Minute s.MaxHeaderBytes = 1 << 20 return s } diff --git a/server/core/server_win.go b/server/core/server_win.go index 54c4c0768b..20cf44b9f2 100644 --- a/server/core/server_win.go +++ b/server/core/server_win.go @@ -14,8 +14,8 @@ func initServer(address string, router *gin.Engine) server { return &http.Server{ Addr: address, Handler: router, - ReadTimeout: 20 * time.Second, - WriteTimeout: 20 * time.Second, + ReadTimeout: 10 * time.Minute, + WriteTimeout: 10 * time.Minute, MaxHeaderBytes: 1 << 20, } } diff --git a/server/core/viper.go b/server/core/viper.go index 42b5893249..0f3c23afad 100644 --- a/server/core/viper.go +++ b/server/core/viper.go @@ -12,7 +12,6 @@ import ( "github.com/spf13/viper" "github.com/flipped-aurora/gin-vue-admin/server/global" - _ "github.com/flipped-aurora/gin-vue-admin/server/packfile" ) // Viper // @@ -29,14 +28,12 @@ func Viper(path ...string) *viper.Viper { switch gin.Mode() { case gin.DebugMode: config = internal.ConfigDefaultFile - fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigDefaultFile) case gin.ReleaseMode: config = internal.ConfigReleaseFile - fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigReleaseFile) case gin.TestMode: config = internal.ConfigTestFile - fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigTestFile) } + fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), config) } else { // internal.ConfigEnv 常量存储的环境变量不为空 将值赋值于config config = configEnv fmt.Printf("您正在使用%s环境变量,config的路径为%s\n", internal.ConfigEnv, config) diff --git a/server/core/zap.go b/server/core/zap.go index 7801194767..d7e08a44a0 100644 --- a/server/core/zap.go +++ b/server/core/zap.go @@ -17,10 +17,14 @@ func Zap() (logger *zap.Logger) { fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director) _ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm) } - - cores := internal.Zap.GetZapCores() + levels := global.GVA_CONFIG.Zap.Levels() + length := len(levels) + cores := make([]zapcore.Core, 0, length) + for i := 0; i < length; i++ { + core := internal.NewZapCore(levels[i]) + cores = append(cores, core) + } logger = zap.New(zapcore.NewTee(cores...)) - if global.GVA_CONFIG.Zap.ShowLine { logger = logger.WithOptions(zap.AddCaller()) } diff --git a/server/docs/docs.go b/server/docs/docs.go index 2626dd92dc..87f3feca1f 100644 --- a/server/docs/docs.go +++ b/server/docs/docs.go @@ -165,6 +165,45 @@ const docTemplate = `{ } } }, + "/api/enterSyncApi": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "确认同步API", + "responses": { + "200": { + "description": "确认同步API", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/freshCasbin": { "get": { "consumes": [ @@ -291,6 +330,45 @@ const docTemplate = `{ } } }, + "/api/getApiGroups": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "获取API分组", + "responses": { + "200": { + "description": "获取API分组", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/getApiList": { "post": { "security": [ @@ -344,6 +422,84 @@ const docTemplate = `{ } } }, + "/api/ignoreApi": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "IgnoreApi" + ], + "summary": "忽略API", + "responses": { + "200": { + "description": "同步API", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/api/syncApi": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "同步API", + "responses": { + "200": { + "description": "同步API", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/updateApi": { "post": { "security": [ @@ -848,7 +1004,7 @@ const docTemplate = `{ } } }, - "/autoCode/createPackage": { + "/autoCode/addFunc": { "post": { "security": [ { @@ -862,47 +1018,31 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AddFunc" ], - "summary": "创建package", + "summary": "增加方法", "parameters": [ { - "description": "创建package", + "description": "增加方法", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysAutoCode" + "$ref": "#/definitions/request.AutoCode" } } ], "responses": { "200": { - "description": "创建package成功", + "description": "{\"success\":true,\"data\":{},\"msg\":\"创建成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/autoCode/createPlug": { + "/autoCode/createPackage": { "post": { "security": [ { @@ -916,23 +1056,23 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePackage" ], - "summary": "创建插件模板", + "summary": "创建package", "parameters": [ { - "description": "创建插件模板", + "description": "创建package", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysAutoCode" + "$ref": "#/definitions/request.SysAutoCodePackageCreate" } } ], "responses": { "200": { - "description": "创建插件模板成功", + "description": "创建package成功", "schema": { "allOf": [ { @@ -970,7 +1110,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AutoCodeTemplate" ], "summary": "自动代码模板", "parameters": [ @@ -980,7 +1120,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.AutoCodeStruct" + "$ref": "#/definitions/request.AutoCode" } } ], @@ -1018,7 +1158,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysAutoCode" + "$ref": "#/definitions/request.GetById" } } ], @@ -1252,7 +1392,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePackage" ], "summary": "获取package", "responses": { @@ -1305,7 +1445,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.SysAutoHistory" + "$ref": "#/definitions/request.PageInfo" } } ], @@ -1377,6 +1517,49 @@ const docTemplate = `{ } } }, + "/autoCode/getTemplates": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePackage" + ], + "summary": "获取package", + "responses": { + "200": { + "description": "创建package成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/autoCode/installPlugin": { "post": { "security": [ @@ -1391,7 +1574,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePlugin" ], "summary": "安装插件", "parameters": [ @@ -1445,7 +1628,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AutoCodeTemplate" ], "summary": "预览创建后的代码", "parameters": [ @@ -1455,7 +1638,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.AutoCodeStruct" + "$ref": "#/definitions/request.AutoCode" } } ], @@ -1499,18 +1682,16 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePlugin" ], "summary": "打包插件", "parameters": [ { - "description": "打包插件", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/system.SysAutoCode" - } + "type": "string", + "description": "插件名称", + "name": "plugName", + "in": "query", + "required": true } ], "responses": { @@ -1563,7 +1744,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.RollBack" + "$ref": "#/definitions/request.SysAutoHistoryRollBack" } } ], @@ -2428,18 +2609,37 @@ const docTemplate = `{ } } }, - "/init/checkdb": { + "/info/createInfo": { "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "CheckDB" + "Info" + ], + "summary": "创建公告", + "parameters": [ + { + "description": "创建公告", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Info" + } + } ], - "summary": "初始化用户数据库", "responses": { "200": { - "description": "初始化用户数据库", + "description": "创建成功", "schema": { "allOf": [ { @@ -2448,10 +2648,6 @@ const docTemplate = `{ { "type": "object", "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, "msg": { "type": "string" } @@ -2463,29 +2659,37 @@ const docTemplate = `{ } } }, - "/init/initdb": { - "post": { - "produces": [ - "application/json" + "/info/deleteInfo": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" ], "tags": [ - "InitDB" + "Info" ], - "summary": "初始化用户数据库", + "summary": "删除公告", "parameters": [ { - "description": "初始化数据库参数", + "description": "删除公告", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.InitDB" + "$ref": "#/definitions/model.Info" } } ], "responses": { "200": { - "description": "初始化用户数据库", + "description": "删除成功", "schema": { "allOf": [ { @@ -2494,7 +2698,7 @@ const docTemplate = `{ { "type": "object", "properties": { - "data": { + "msg": { "type": "string" } } @@ -2505,8 +2709,8 @@ const docTemplate = `{ } } }, - "/jwt/jsonInBlacklist": { - "post": { + "/info/deleteInfoByIds": { + "delete": { "security": [ { "ApiKeyAuth": [] @@ -2519,12 +2723,12 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Jwt" + "Info" ], - "summary": "jwt加入黑名单", + "summary": "批量删除公告", "responses": { "200": { - "description": "jwt加入黑名单", + "description": "批量删除成功", "schema": { "allOf": [ { @@ -2544,8 +2748,8 @@ const docTemplate = `{ } } }, - "/menu/addBaseMenu": { - "post": { + "/info/findInfo": { + "get": { "security": [ { "ApiKeyAuth": [] @@ -2558,23 +2762,50 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Menu" + "Info" ], - "summary": "新增菜单", + "summary": "用id查询公告", "parameters": [ { - "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/system.SysBaseMenu" - } + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "内容", + "name": "content", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "标题", + "name": "title", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + }, + { + "type": "integer", + "description": "作者", + "name": "userID", + "in": "query" } ], "responses": { "200": { - "description": "新增菜单", + "description": "查询成功", "schema": { "allOf": [ { @@ -2583,6 +2814,9 @@ const docTemplate = `{ { "type": "object", "properties": { + "data": { + "$ref": "#/definitions/model.Info" + }, "msg": { "type": "string" } @@ -2594,13 +2828,8 @@ const docTemplate = `{ } } }, - "/menu/addMenuAuthority": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], + "/info/getInfoDataSource": { + "get": { "consumes": [ "application/json" ], @@ -2608,23 +2837,12 @@ const docTemplate = `{ "application/json" ], "tags": [ - "AuthorityMenu" - ], - "summary": "增加menu和角色关联关系", - "parameters": [ - { - "description": "角色ID", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AddMenuAuthorityInfo" - } - } + "Info" ], + "summary": "获取Info的数据源", "responses": { "200": { - "description": "增加menu和角色关联关系", + "description": "查询成功", "schema": { "allOf": [ { @@ -2633,6 +2851,9 @@ const docTemplate = `{ { "type": "object", "properties": { + "data": { + "type": "object" + }, "msg": { "type": "string" } @@ -2644,8 +2865,8 @@ const docTemplate = `{ } } }, - "/menu/deleteBaseMenu": { - "post": { + "/info/getInfoList": { + "get": { "security": [ { "ApiKeyAuth": [] @@ -2658,23 +2879,42 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Menu" + "Info" ], - "summary": "删除菜单", + "summary": "分页获取公告列表", "parameters": [ { - "description": "菜单id", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.GetById" - } + "type": "string", + "name": "endCreatedAt", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "startCreatedAt", + "in": "query" } ], "responses": { "200": { - "description": "删除菜单", + "description": "获取成功", "schema": { "allOf": [ { @@ -2683,6 +2923,9 @@ const docTemplate = `{ { "type": "object", "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, "msg": { "type": "string" } @@ -2694,13 +2937,8 @@ const docTemplate = `{ } } }, - "/menu/getBaseMenuById": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], + "/info/getInfoPublic": { + "get": { "consumes": [ "application/json" ], @@ -2708,23 +2946,42 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Menu" + "Info" ], - "summary": "根据id获取菜单", + "summary": "不需要鉴权的公告接口", "parameters": [ { - "description": "菜单id", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.GetById" - } + "type": "string", + "name": "endCreatedAt", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "startCreatedAt", + "in": "query" } ], "responses": { "200": { - "description": "根据id获取菜单,返回包括系统菜单列表", + "description": "获取成功", "schema": { "allOf": [ { @@ -2734,7 +2991,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/response.SysBaseMenuResponse" + "type": "object" }, "msg": { "type": "string" @@ -2747,34 +3004,37 @@ const docTemplate = `{ } } }, - "/menu/getBaseMenuTree": { - "post": { + "/info/updateInfo": { + "put": { "security": [ { "ApiKeyAuth": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "AuthorityMenu" + "Info" ], - "summary": "获取用户动态路由", + "summary": "更新公告", "parameters": [ { - "description": "空", + "description": "更新公告", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.Empty" + "$ref": "#/definitions/model.Info" } } ], "responses": { "200": { - "description": "获取用户动态路由,返回包括系统菜单列表", + "description": "更新成功", "schema": { "allOf": [ { @@ -2783,9 +3043,6 @@ const docTemplate = `{ { "type": "object", "properties": { - "data": { - "$ref": "#/definitions/response.SysBaseMenusResponse" - }, "msg": { "type": "string" } @@ -2797,34 +3054,18 @@ const docTemplate = `{ } } }, - "/menu/getMenu": { + "/init/checkdb": { "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], "produces": [ "application/json" ], "tags": [ - "AuthorityMenu" - ], - "summary": "获取用户动态路由", - "parameters": [ - { - "description": "空", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.Empty" - } - } + "CheckDB" ], + "summary": "初始化用户数据库", "responses": { "200": { - "description": "获取用户动态路由,返回包括系统菜单详情列表", + "description": "初始化用户数据库", "schema": { "allOf": [ { @@ -2834,7 +3075,8 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/response.SysMenusResponse" + "type": "object", + "additionalProperties": true }, "msg": { "type": "string" @@ -2847,37 +3089,29 @@ const docTemplate = `{ } } }, - "/menu/getMenuAuthority": { + "/init/initdb": { "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], "tags": [ - "AuthorityMenu" + "InitDB" ], - "summary": "获取指定角色menu", + "summary": "初始化用户数据库", "parameters": [ { - "description": "角色ID", + "description": "初始化数据库参数", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.GetAuthorityId" + "$ref": "#/definitions/request.InitDB" } } ], "responses": { "200": { - "description": "获取指定角色menu", + "description": "初始化用户数据库", "schema": { "allOf": [ { @@ -2887,10 +3121,6 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { "type": "string" } } @@ -2901,7 +3131,7 @@ const docTemplate = `{ } } }, - "/menu/getMenuList": { + "/jwt/jsonInBlacklist": { "post": { "security": [ { @@ -2915,23 +3145,698 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Menu" + "Jwt" ], - "summary": "分页获取基础menu列表", - "parameters": [ - { - "description": "页码, 每页大小", - "name": "data", - "in": "body", - "required": true, + "summary": "jwt加入黑名单", + "responses": { + "200": { + "description": "jwt加入黑名单", "schema": { - "$ref": "#/definitions/request.PageInfo" + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/addBaseMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "新增菜单", + "parameters": [ + { + "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysBaseMenu" + } + } + ], + "responses": { + "200": { + "description": "新增菜单", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/addMenuAuthority": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "增加menu和角色关联关系", + "parameters": [ + { + "description": "角色ID", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.AddMenuAuthorityInfo" + } + } + ], + "responses": { + "200": { + "description": "增加menu和角色关联关系", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/deleteBaseMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "删除菜单", + "parameters": [ + { + "description": "菜单id", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GetById" + } + } + ], + "responses": { + "200": { + "description": "删除菜单", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getBaseMenuById": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "根据id获取菜单", + "parameters": [ + { + "description": "菜单id", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GetById" + } + } + ], + "responses": { + "200": { + "description": "根据id获取菜单,返回包括系统菜单列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.SysBaseMenuResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getBaseMenuTree": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取用户动态路由", + "parameters": [ + { + "description": "空", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.Empty" + } + } + ], + "responses": { + "200": { + "description": "获取用户动态路由,返回包括系统菜单列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.SysBaseMenusResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取用户动态路由", + "parameters": [ + { + "description": "空", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.Empty" + } + } + ], + "responses": { + "200": { + "description": "获取用户动态路由,返回包括系统菜单详情列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.SysMenusResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getMenuAuthority": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取指定角色menu", + "parameters": [ + { + "description": "角色ID", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GetAuthorityId" + } + } + ], + "responses": { + "200": { + "description": "获取指定角色menu", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getMenuList": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "分页获取基础menu列表", + "parameters": [ + { + "description": "页码, 每页大小", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.PageInfo" + } + } + ], + "responses": { + "200": { + "description": "分页获取基础menu列表,返回包括列表,总数,页码,每页数量", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/updateBaseMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "更新菜单", + "parameters": [ + { + "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysBaseMenu" + } + } + ], + "responses": { + "200": { + "description": "更新菜单", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionary/createSysDictionary": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "创建SysDictionary", + "parameters": [ + { + "description": "SysDictionary模型", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysDictionary" + } + } + ], + "responses": { + "200": { + "description": "创建SysDictionary", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionary/deleteSysDictionary": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "删除SysDictionary", + "parameters": [ + { + "description": "SysDictionary模型", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysDictionary" + } + } + ], + "responses": { + "200": { + "description": "删除SysDictionary", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionary/findSysDictionary": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "用id查询SysDictionary", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "描述", + "name": "desc", + "in": "query" + }, + { + "type": "string", + "description": "字典名(中)", + "name": "name", + "in": "query" + }, + { + "type": "boolean", + "description": "状态", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "字典名(英)", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + } + ], + "responses": { + "200": { + "description": "用id查询SysDictionary", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] } } + } + } + }, + "/sysDictionary/getSysDictionaryList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" ], + "summary": "分页获取SysDictionary列表", "responses": { "200": { - "description": "分页获取基础menu列表,返回包括列表,总数,页码,每页数量", + "description": "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量", "schema": { "allOf": [ { @@ -2954,8 +3859,8 @@ const docTemplate = `{ } } }, - "/menu/updateBaseMenu": { - "post": { + "/sysDictionary/updateSysDictionary": { + "put": { "security": [ { "ApiKeyAuth": [] @@ -2968,23 +3873,23 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Menu" + "SysDictionary" ], - "summary": "更新菜单", + "summary": "更新SysDictionary", "parameters": [ { - "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", + "description": "SysDictionary模型", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysBaseMenu" + "$ref": "#/definitions/system.SysDictionary" } } ], "responses": { "200": { - "description": "更新菜单", + "description": "更新SysDictionary", "schema": { "allOf": [ { @@ -3004,7 +3909,7 @@ const docTemplate = `{ } } }, - "/sysDictionary/createSysDictionary": { + "/sysDictionaryDetail/createSysDictionaryDetail": { "post": { "security": [ { @@ -3018,23 +3923,23 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" ], - "summary": "创建SysDictionary", + "summary": "创建SysDictionaryDetail", "parameters": [ { - "description": "SysDictionary模型", + "description": "SysDictionaryDetail模型", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionary" + "$ref": "#/definitions/system.SysDictionaryDetail" } } ], "responses": { "200": { - "description": "创建SysDictionary", + "description": "创建SysDictionaryDetail", "schema": { "allOf": [ { @@ -3054,7 +3959,7 @@ const docTemplate = `{ } } }, - "/sysDictionary/deleteSysDictionary": { + "/sysDictionaryDetail/deleteSysDictionaryDetail": { "delete": { "security": [ { @@ -3068,23 +3973,23 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" ], - "summary": "删除SysDictionary", + "summary": "删除SysDictionaryDetail", "parameters": [ { - "description": "SysDictionary模型", + "description": "SysDictionaryDetail模型", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionary" + "$ref": "#/definitions/system.SysDictionaryDetail" } } ], "responses": { "200": { - "description": "删除SysDictionary", + "description": "删除SysDictionaryDetail", "schema": { "allOf": [ { @@ -3104,7 +4009,7 @@ const docTemplate = `{ } } }, - "/sysDictionary/findSysDictionary": { + "/sysDictionaryDetail/findSysDictionaryDetail": { "get": { "security": [ { @@ -3118,9 +4023,9 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" ], - "summary": "用id查询SysDictionary", + "summary": "用id查询SysDictionaryDetail", "parameters": [ { "type": "integer", @@ -3136,26 +4041,32 @@ const docTemplate = `{ }, { "type": "string", - "description": "描述", - "name": "desc", + "description": "扩展值", + "name": "extend", "in": "query" }, { "type": "string", - "description": "字典名(中)", - "name": "name", + "description": "展示值", + "name": "label", + "in": "query" + }, + { + "type": "integer", + "description": "排序标记", + "name": "sort", "in": "query" }, { "type": "boolean", - "description": "状态", + "description": "启用状态", "name": "status", "in": "query" }, { - "type": "string", - "description": "字典名(英)", - "name": "type", + "type": "integer", + "description": "关联标记", + "name": "sysDictionaryID", "in": "query" }, { @@ -3163,11 +4074,17 @@ const docTemplate = `{ "description": "更新时间", "name": "updatedAt", "in": "query" + }, + { + "type": "string", + "description": "字典值", + "name": "value", + "in": "query" } ], "responses": { "200": { - "description": "用id查询SysDictionary", + "description": "用id查询SysDictionaryDetail", "schema": { "allOf": [ { @@ -3191,7 +4108,7 @@ const docTemplate = `{ } } }, - "/sysDictionary/getSysDictionaryList": { + "/sysDictionaryDetail/getSysDictionaryDetailList": { "get": { "security": [ { @@ -3205,12 +4122,139 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" + ], + "summary": "分页获取SysDictionaryDetail列表", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "扩展值", + "name": "extend", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "展示值", + "name": "label", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "integer", + "description": "排序标记", + "name": "sort", + "in": "query" + }, + { + "type": "boolean", + "description": "启用状态", + "name": "status", + "in": "query" + }, + { + "type": "integer", + "description": "关联标记", + "name": "sysDictionaryID", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + }, + { + "type": "string", + "description": "字典值", + "name": "value", + "in": "query" + } + ], + "responses": { + "200": { + "description": "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/updateSysDictionaryDetail": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "更新SysDictionaryDetail", + "parameters": [ + { + "description": "更新SysDictionaryDetail", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + } ], - "summary": "分页获取SysDictionary列表", "responses": { "200": { - "description": "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量", + "description": "更新SysDictionaryDetail", "schema": { "allOf": [ { @@ -3219,9 +4263,6 @@ const docTemplate = `{ { "type": "object", "properties": { - "data": { - "$ref": "#/definitions/response.PageResult" - }, "msg": { "type": "string" } @@ -3233,8 +4274,8 @@ const docTemplate = `{ } } }, - "/sysDictionary/updateSysDictionary": { - "put": { + "/sysExportTemplate/createSysExportTemplate": { + "post": { "security": [ { "ApiKeyAuth": [] @@ -3247,44 +4288,32 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionary" + "SysExportTemplate" ], - "summary": "更新SysDictionary", + "summary": "创建导出模板", "parameters": [ { - "description": "SysDictionary模型", + "description": "创建导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionary" + "$ref": "#/definitions/system.SysExportTemplate" } } ], "responses": { "200": { - "description": "更新SysDictionary", + "description": "{\"success\":true,\"data\":{},\"msg\":\"创建成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/createSysDictionaryDetail": { - "post": { + "/sysExportTemplate/deleteSysExportTemplate": { + "delete": { "security": [ { "ApiKeyAuth": [] @@ -3297,43 +4326,31 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "创建SysDictionaryDetail", + "summary": "删除导出模板", "parameters": [ { - "description": "SysDictionaryDetail模型", + "description": "删除导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionaryDetail" + "$ref": "#/definitions/system.SysExportTemplate" } } ], "responses": { "200": { - "description": "创建SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"删除成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/deleteSysDictionaryDetail": { + "/sysExportTemplate/deleteSysExportTemplateByIds": { "delete": { "security": [ { @@ -3347,43 +4364,31 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "删除SysDictionaryDetail", + "summary": "批量删除导出模板", "parameters": [ { - "description": "SysDictionaryDetail模型", + "description": "批量删除导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionaryDetail" + "$ref": "#/definitions/request.IdsReq" } } ], "responses": { "200": { - "description": "删除SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"批量删除成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/findSysDictionaryDetail": { + "/sysExportTemplate/exportExcel": { "get": { "security": [ { @@ -3397,9 +4402,29 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "用id查询SysDictionaryDetail", + "summary": "导出表格模板", + "responses": {} + } + }, + "/sysExportTemplate/findSysExportTemplate": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysExportTemplate" + ], + "summary": "用id查询导出模板", "parameters": [ { "type": "integer", @@ -3415,74 +4440,62 @@ const docTemplate = `{ }, { "type": "string", - "description": "扩展值", - "name": "extend", + "description": "数据库名称", + "name": "dbName", + "in": "query" + }, + { + "type": "integer", + "name": "limit", "in": "query" }, { "type": "string", - "description": "展示值", - "name": "label", + "description": "模板名称", + "name": "name", "in": "query" }, { - "type": "integer", - "description": "排序标记", - "name": "sort", + "type": "string", + "name": "order", "in": "query" }, { - "type": "boolean", - "description": "启用状态", - "name": "status", + "type": "string", + "description": "表名称", + "name": "tableName", "in": "query" }, { - "type": "integer", - "description": "关联标记", - "name": "sysDictionaryID", + "type": "string", + "description": "模板标识", + "name": "templateID", "in": "query" }, { "type": "string", - "description": "更新时间", - "name": "updatedAt", + "description": "模板信息", + "name": "templateInfo", "in": "query" }, { - "type": "integer", - "description": "字典值", - "name": "value", + "type": "string", + "description": "更新时间", + "name": "updatedAt", "in": "query" } ], "responses": { "200": { - "description": "用id查询SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"查询成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/getSysDictionaryDetailList": { + "/sysExportTemplate/getSysExportTemplateList": { "get": { "security": [ { @@ -3496,9 +4509,9 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "分页获取SysDictionaryDetail列表", + "summary": "分页获取导出模板列表", "parameters": [ { "type": "integer", @@ -3514,8 +4527,13 @@ const docTemplate = `{ }, { "type": "string", - "description": "扩展值", - "name": "extend", + "description": "数据库名称", + "name": "dbName", + "in": "query" + }, + { + "type": "string", + "name": "endCreatedAt", "in": "query" }, { @@ -3524,10 +4542,20 @@ const docTemplate = `{ "name": "keyword", "in": "query" }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, { "type": "string", - "description": "展示值", - "name": "label", + "description": "模板名称", + "name": "name", + "in": "query" + }, + { + "type": "string", + "name": "order", "in": "query" }, { @@ -3543,62 +4571,66 @@ const docTemplate = `{ "in": "query" }, { - "type": "integer", - "description": "排序标记", - "name": "sort", + "type": "string", + "name": "startCreatedAt", "in": "query" }, { - "type": "boolean", - "description": "启用状态", - "name": "status", + "type": "string", + "description": "表名称", + "name": "tableName", "in": "query" }, { - "type": "integer", - "description": "关联标记", - "name": "sysDictionaryID", + "type": "string", + "description": "模板标识", + "name": "templateID", "in": "query" }, { "type": "string", - "description": "更新时间", - "name": "updatedAt", + "description": "模板信息", + "name": "templateInfo", "in": "query" }, { - "type": "integer", - "description": "字典值", - "name": "value", + "type": "string", + "description": "更新时间", + "name": "updatedAt", "in": "query" } ], "responses": { "200": { - "description": "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量", + "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/response.PageResult" - }, - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/updateSysDictionaryDetail": { + "/sysExportTemplate/importExcel": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysImportTemplate" + ], + "summary": "导入表格", + "responses": {} + } + }, + "/sysExportTemplate/updateSysExportTemplate": { "put": { "security": [ { @@ -3612,37 +4644,25 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "更新SysDictionaryDetail", + "summary": "更新导出模板", "parameters": [ { - "description": "更新SysDictionaryDetail", + "description": "更新导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionaryDetail" + "$ref": "#/definitions/system.SysExportTemplate" } } ], "responses": { "200": { - "description": "更新SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"更新成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } @@ -4741,49 +5761,22 @@ const docTemplate = `{ } } }, - "config.Autocode": { - "type": "object", - "properties": { - "root": { - "type": "string" - }, - "server": { - "type": "string" - }, - "server-api": { - "type": "string" - }, - "server-initialize": { - "type": "string" - }, - "server-model": { - "type": "string" - }, - "server-plug": { - "type": "string" - }, - "server-request": { - "type": "string" - }, - "server-router": { - "type": "string" - }, - "server-service": { + "config.Autocode": { + "type": "object", + "properties": { + "ai-path": { "type": "string" }, - "transfer-restart": { - "type": "boolean" - }, - "web": { + "module": { "type": "string" }, - "web-api": { + "root": { "type": "string" }, - "web-form": { + "server": { "type": "string" }, - "web-table": { + "web": { "type": "string" } } @@ -4879,6 +5872,37 @@ const docTemplate = `{ } } }, + "config.CloudflareR2": { + "type": "object", + "properties": { + "access-key-id": { + "type": "string" + }, + "account-id": { + "type": "string" + }, + "base-url": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "path": { + "type": "string" + }, + "secret-access-key": { + "type": "string" + } + } + }, + "config.DiskList": { + "type": "object", + "properties": { + "mount-point": { + "type": "string" + } + } + }, "config.Excel": { "type": "object", "properties": { @@ -4944,6 +5968,10 @@ const docTemplate = `{ "config.Mongo": { "type": "object", "properties": { + "auth-source": { + "description": "验证数据库", + "type": "string" + }, "coll": { "description": "collection name", "type": "string" @@ -5043,12 +6071,15 @@ const docTemplate = `{ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5056,7 +6087,7 @@ const docTemplate = `{ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5098,12 +6129,15 @@ const docTemplate = `{ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5111,7 +6145,7 @@ const docTemplate = `{ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5153,12 +6187,15 @@ const docTemplate = `{ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5166,7 +6203,7 @@ const docTemplate = `{ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5208,12 +6245,15 @@ const docTemplate = `{ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5221,7 +6261,7 @@ const docTemplate = `{ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5266,13 +6306,24 @@ const docTemplate = `{ "description": "服务器地址:端口", "type": "string" }, + "clusterAddrs": { + "description": "集群模式下的节点地址列表", + "type": "array", + "items": { + "type": "string" + } + }, "db": { - "description": "redis的哪个数据库", + "description": "单实例模式下redis的哪个数据库", "type": "integer" }, "password": { "description": "密码", "type": "string" + }, + "useCluster": { + "description": "是否使用集群模式", + "type": "boolean" } } }, @@ -5296,6 +6347,9 @@ const docTemplate = `{ "captcha": { "$ref": "#/definitions/config.Captcha" }, + "cloudflare-r2": { + "$ref": "#/definitions/config.CloudflareR2" + }, "cors": { "description": "跨域配置", "allOf": [ @@ -5310,6 +6364,12 @@ const docTemplate = `{ "$ref": "#/definitions/config.SpecializedDB" } }, + "disk-list": { + "type": "array", + "items": { + "$ref": "#/definitions/config.DiskList" + } + }, "email": { "$ref": "#/definitions/github_com_flipped-aurora_gin-vue-admin_server_config.Email" }, @@ -5413,12 +6473,15 @@ const docTemplate = `{ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5429,7 +6492,7 @@ const docTemplate = `{ "type": "string" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5471,12 +6534,15 @@ const docTemplate = `{ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5484,7 +6550,7 @@ const docTemplate = `{ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5500,10 +6566,6 @@ const docTemplate = `{ "description": "数据库类型:mysql(默认)|sqlite|sqlserver|postgresql", "type": "string" }, - "env": { - "description": "环境值", - "type": "string" - }, "iplimit-count": { "type": "integer" }, @@ -5518,7 +6580,7 @@ const docTemplate = `{ "type": "string" }, "use-mongo": { - "description": "使用redis", + "description": "使用mongo", "type": "boolean" }, "use-multipoint": { @@ -5577,14 +6639,14 @@ const docTemplate = `{ "description": "输出控制台", "type": "boolean" }, - "max-age": { - "description": "日志留存时间", - "type": "integer" - }, "prefix": { "description": "日志前缀", "type": "string" }, + "retention-day": { + "description": "日志保留天数", + "type": "integer" + }, "show-line": { "description": "显示行", "type": "boolean" @@ -5766,6 +6828,42 @@ const docTemplate = `{ } } }, + "model.Info": { + "type": "object", + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "attachments": { + "description": "附件", + "type": "array", + "items": { + "type": "object" + } + }, + "content": { + "description": "内容", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "title": { + "description": "标题", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + }, + "userID": { + "description": "作者", + "type": "integer" + } + } + }, "request.AddMenuAuthorityInfo": { "type": "object", "properties": { @@ -5781,6 +6879,9 @@ const docTemplate = `{ } } }, + "request.AutoCode": { + "type": "object" + }, "request.CasbinInReceive": { "type": "object", "properties": { @@ -5857,9 +6958,13 @@ const docTemplate = `{ "request.InitDB": { "type": "object", "required": [ + "adminPassword", "dbName" ], "properties": { + "adminPassword": { + "type": "string" + }, "dbName": { "description": "数据库名", "type": "string" @@ -5969,19 +7074,6 @@ const docTemplate = `{ } } }, - "request.RollBack": { - "type": "object", - "properties": { - "deleteTable": { - "description": "是否删除表", - "type": "boolean" - }, - "id": { - "description": "主键ID", - "type": "integer" - } - } - }, "request.SearchApiParams": { "type": "object", "properties": { @@ -6076,19 +7168,44 @@ const docTemplate = `{ } } }, - "request.SysAutoHistory": { + "request.SysAutoCodePackageCreate": { "type": "object", "properties": { - "keyword": { - "description": "关键字", - "type": "string" + "desc": { + "type": "string", + "example": "描述" }, - "page": { - "description": "页码", - "type": "integer" + "label": { + "type": "string", + "example": "展示名" }, - "pageSize": { - "description": "每页大小", + "packageName": { + "type": "string", + "example": "包名" + }, + "template": { + "type": "string", + "example": "模版" + } + } + }, + "request.SysAutoHistoryRollBack": { + "type": "object", + "properties": { + "deleteApi": { + "description": "是否删除接口", + "type": "boolean" + }, + "deleteMenu": { + "description": "是否删除菜单", + "type": "boolean" + }, + "deleteTable": { + "description": "是否删除表", + "type": "boolean" + }, + "id": { + "description": "主键ID", "type": "integer" } } @@ -6307,117 +7424,61 @@ const docTemplate = `{ } } }, - "system.AutoCodeStruct": { + "system.Condition": { "type": "object", "properties": { - "abbreviation": { - "description": "Struct简称", - "type": "string" - }, - "autoCreateApiToSql": { - "description": "是否自动创建api", - "type": "boolean" - }, - "autoCreateResource": { - "description": "是否自动创建资源标识", - "type": "boolean" - }, - "autoMoveFile": { - "description": "是否自动移动文件", - "type": "boolean" - }, - "businessDB": { - "description": "业务数据库", - "type": "string" + "ID": { + "description": "主键ID", + "type": "integer" }, - "description": { - "description": "Struct中文名称", + "column": { "type": "string" }, - "fields": { - "type": "array", - "items": { - "$ref": "#/definitions/system.Field" - } - }, - "hasTimer": { - "type": "boolean" - }, - "humpPackageName": { - "description": "go文件名称", + "createdAt": { + "description": "创建时间", "type": "string" }, - "package": { + "from": { "type": "string" }, - "packageName": { - "description": "文件名称", + "operator": { "type": "string" }, - "structName": { - "description": "Struct名称", + "templateID": { "type": "string" }, - "tableName": { - "description": "表名", + "updatedAt": { + "description": "更新时间", "type": "string" } } }, - "system.Field": { + "system.JoinTemplate": { "type": "object", "properties": { - "clearable": { - "description": "是否可清空", - "type": "boolean" - }, - "columnName": { - "description": "数据库字段", - "type": "string" - }, - "comment": { - "description": "数据库字段描述", - "type": "string" - }, - "dataTypeLong": { - "description": "数据库字段长度", - "type": "string" - }, - "dictType": { - "description": "字典", - "type": "string" + "ID": { + "description": "主键ID", + "type": "integer" }, - "errorText": { - "description": "校验失败文字", + "createdAt": { + "description": "创建时间", "type": "string" }, - "fieldDesc": { - "description": "中文名", + "joins": { "type": "string" }, - "fieldJson": { - "description": "FieldJson", + "on": { "type": "string" }, - "fieldName": { - "description": "Field名", + "table": { "type": "string" }, - "fieldSearchType": { - "description": "搜索条件", + "templateID": { "type": "string" }, - "fieldType": { - "description": "Field数据类型", + "updatedAt": { + "description": "更新时间", "type": "string" - }, - "require": { - "description": "是否必填", - "type": "boolean" - }, - "sort": { - "description": "是否增加排序", - "type": "boolean" } } }, @@ -6532,32 +7593,6 @@ const docTemplate = `{ } } }, - "system.SysAutoCode": { - "type": "object", - "properties": { - "ID": { - "description": "主键ID", - "type": "integer" - }, - "createdAt": { - "description": "创建时间", - "type": "string" - }, - "desc": { - "type": "string" - }, - "label": { - "type": "string" - }, - "packageName": { - "type": "string" - }, - "updatedAt": { - "description": "更新时间", - "type": "string" - } - } - }, "system.SysBaseMenu": { "type": "object", "properties": { @@ -6615,7 +7650,7 @@ const docTemplate = `{ }, "parentId": { "description": "父菜单ID", - "type": "string" + "type": "integer" }, "path": { "description": "路由path", @@ -6765,7 +7800,62 @@ const docTemplate = `{ }, "value": { "description": "字典值", + "type": "string" + } + } + }, + "system.SysExportTemplate": { + "type": "object", + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/system.Condition" + } + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "dbName": { + "description": "数据库名称", + "type": "string" + }, + "joinTemplate": { + "type": "array", + "items": { + "$ref": "#/definitions/system.JoinTemplate" + } + }, + "limit": { "type": "integer" + }, + "name": { + "description": "模板名称", + "type": "string" + }, + "order": { + "type": "string" + }, + "tableName": { + "description": "表名称", + "type": "string" + }, + "templateID": { + "description": "模板标识", + "type": "string" + }, + "templateInfo": { + "description": "模板信息", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" } } }, @@ -6813,7 +7903,7 @@ const docTemplate = `{ } }, "menuId": { - "type": "string" + "type": "integer" }, "meta": { "description": "附加属性", @@ -6835,7 +7925,7 @@ const docTemplate = `{ }, "parentId": { "description": "父菜单ID", - "type": "string" + "type": "integer" }, "path": { "description": "路由path", @@ -6918,10 +8008,6 @@ const docTemplate = `{ "description": "主键ID", "type": "integer" }, - "activeColor": { - "description": "活跃颜色", - "type": "string" - }, "authorities": { "type": "array", "items": { @@ -7001,7 +8087,7 @@ const docTemplate = `{ // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ - Version: "v2.6.2", + Version: "v2.7.4", Host: "", BasePath: "", Schemes: []string{}, diff --git a/server/docs/swagger.json b/server/docs/swagger.json index e6ef634e09..5c27ada772 100644 --- a/server/docs/swagger.json +++ b/server/docs/swagger.json @@ -4,7 +4,7 @@ "description": "使用gin+vue进行极速开发的全栈开发基础平台", "title": "Gin-Vue-Admin Swagger API接口文档", "contact": {}, - "version": "v2.6.2" + "version": "v2.7.4" }, "paths": { "/api/createApi": { @@ -157,6 +157,45 @@ } } }, + "/api/enterSyncApi": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "确认同步API", + "responses": { + "200": { + "description": "确认同步API", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/freshCasbin": { "get": { "consumes": [ @@ -283,6 +322,45 @@ } } }, + "/api/getApiGroups": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "获取API分组", + "responses": { + "200": { + "description": "获取API分组", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/getApiList": { "post": { "security": [ @@ -336,6 +414,84 @@ } } }, + "/api/ignoreApi": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "IgnoreApi" + ], + "summary": "忽略API", + "responses": { + "200": { + "description": "同步API", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/api/syncApi": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "同步API", + "responses": { + "200": { + "description": "同步API", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/updateApi": { "post": { "security": [ @@ -840,7 +996,7 @@ } } }, - "/autoCode/createPackage": { + "/autoCode/addFunc": { "post": { "security": [ { @@ -854,47 +1010,31 @@ "application/json" ], "tags": [ - "AutoCode" + "AddFunc" ], - "summary": "创建package", + "summary": "增加方法", "parameters": [ { - "description": "创建package", + "description": "增加方法", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysAutoCode" + "$ref": "#/definitions/request.AutoCode" } } ], "responses": { "200": { - "description": "创建package成功", + "description": "{\"success\":true,\"data\":{},\"msg\":\"创建成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/autoCode/createPlug": { + "/autoCode/createPackage": { "post": { "security": [ { @@ -908,23 +1048,23 @@ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePackage" ], - "summary": "创建插件模板", + "summary": "创建package", "parameters": [ { - "description": "创建插件模板", + "description": "创建package", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysAutoCode" + "$ref": "#/definitions/request.SysAutoCodePackageCreate" } } ], "responses": { "200": { - "description": "创建插件模板成功", + "description": "创建package成功", "schema": { "allOf": [ { @@ -962,7 +1102,7 @@ "application/json" ], "tags": [ - "AutoCode" + "AutoCodeTemplate" ], "summary": "自动代码模板", "parameters": [ @@ -972,7 +1112,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.AutoCodeStruct" + "$ref": "#/definitions/request.AutoCode" } } ], @@ -1010,7 +1150,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysAutoCode" + "$ref": "#/definitions/request.GetById" } } ], @@ -1244,7 +1384,7 @@ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePackage" ], "summary": "获取package", "responses": { @@ -1297,7 +1437,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.SysAutoHistory" + "$ref": "#/definitions/request.PageInfo" } } ], @@ -1369,6 +1509,49 @@ } } }, + "/autoCode/getTemplates": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePackage" + ], + "summary": "获取package", + "responses": { + "200": { + "description": "创建package成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/autoCode/installPlugin": { "post": { "security": [ @@ -1383,7 +1566,7 @@ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePlugin" ], "summary": "安装插件", "parameters": [ @@ -1437,7 +1620,7 @@ "application/json" ], "tags": [ - "AutoCode" + "AutoCodeTemplate" ], "summary": "预览创建后的代码", "parameters": [ @@ -1447,7 +1630,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.AutoCodeStruct" + "$ref": "#/definitions/request.AutoCode" } } ], @@ -1491,18 +1674,16 @@ "application/json" ], "tags": [ - "AutoCode" + "AutoCodePlugin" ], "summary": "打包插件", "parameters": [ { - "description": "打包插件", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/system.SysAutoCode" - } + "type": "string", + "description": "插件名称", + "name": "plugName", + "in": "query", + "required": true } ], "responses": { @@ -1555,7 +1736,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.RollBack" + "$ref": "#/definitions/request.SysAutoHistoryRollBack" } } ], @@ -2420,18 +2601,37 @@ } } }, - "/init/checkdb": { + "/info/createInfo": { "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "CheckDB" + "Info" + ], + "summary": "创建公告", + "parameters": [ + { + "description": "创建公告", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Info" + } + } ], - "summary": "初始化用户数据库", "responses": { "200": { - "description": "初始化用户数据库", + "description": "创建成功", "schema": { "allOf": [ { @@ -2440,10 +2640,6 @@ { "type": "object", "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, "msg": { "type": "string" } @@ -2455,29 +2651,37 @@ } } }, - "/init/initdb": { - "post": { - "produces": [ - "application/json" + "/info/deleteInfo": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" ], "tags": [ - "InitDB" + "Info" ], - "summary": "初始化用户数据库", + "summary": "删除公告", "parameters": [ { - "description": "初始化数据库参数", + "description": "删除公告", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.InitDB" + "$ref": "#/definitions/model.Info" } } ], "responses": { "200": { - "description": "初始化用户数据库", + "description": "删除成功", "schema": { "allOf": [ { @@ -2486,7 +2690,7 @@ { "type": "object", "properties": { - "data": { + "msg": { "type": "string" } } @@ -2497,8 +2701,8 @@ } } }, - "/jwt/jsonInBlacklist": { - "post": { + "/info/deleteInfoByIds": { + "delete": { "security": [ { "ApiKeyAuth": [] @@ -2511,12 +2715,12 @@ "application/json" ], "tags": [ - "Jwt" + "Info" ], - "summary": "jwt加入黑名单", + "summary": "批量删除公告", "responses": { "200": { - "description": "jwt加入黑名单", + "description": "批量删除成功", "schema": { "allOf": [ { @@ -2536,8 +2740,8 @@ } } }, - "/menu/addBaseMenu": { - "post": { + "/info/findInfo": { + "get": { "security": [ { "ApiKeyAuth": [] @@ -2550,23 +2754,50 @@ "application/json" ], "tags": [ - "Menu" + "Info" ], - "summary": "新增菜单", + "summary": "用id查询公告", "parameters": [ { - "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/system.SysBaseMenu" - } + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "内容", + "name": "content", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "标题", + "name": "title", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + }, + { + "type": "integer", + "description": "作者", + "name": "userID", + "in": "query" } ], "responses": { "200": { - "description": "新增菜单", + "description": "查询成功", "schema": { "allOf": [ { @@ -2575,6 +2806,9 @@ { "type": "object", "properties": { + "data": { + "$ref": "#/definitions/model.Info" + }, "msg": { "type": "string" } @@ -2586,13 +2820,8 @@ } } }, - "/menu/addMenuAuthority": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], + "/info/getInfoDataSource": { + "get": { "consumes": [ "application/json" ], @@ -2600,23 +2829,12 @@ "application/json" ], "tags": [ - "AuthorityMenu" - ], - "summary": "增加menu和角色关联关系", - "parameters": [ - { - "description": "角色ID", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AddMenuAuthorityInfo" - } - } + "Info" ], + "summary": "获取Info的数据源", "responses": { "200": { - "description": "增加menu和角色关联关系", + "description": "查询成功", "schema": { "allOf": [ { @@ -2625,6 +2843,9 @@ { "type": "object", "properties": { + "data": { + "type": "object" + }, "msg": { "type": "string" } @@ -2636,8 +2857,8 @@ } } }, - "/menu/deleteBaseMenu": { - "post": { + "/info/getInfoList": { + "get": { "security": [ { "ApiKeyAuth": [] @@ -2650,23 +2871,42 @@ "application/json" ], "tags": [ - "Menu" + "Info" ], - "summary": "删除菜单", + "summary": "分页获取公告列表", "parameters": [ { - "description": "菜单id", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.GetById" - } + "type": "string", + "name": "endCreatedAt", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "startCreatedAt", + "in": "query" } ], "responses": { "200": { - "description": "删除菜单", + "description": "获取成功", "schema": { "allOf": [ { @@ -2675,6 +2915,9 @@ { "type": "object", "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, "msg": { "type": "string" } @@ -2686,13 +2929,8 @@ } } }, - "/menu/getBaseMenuById": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], + "/info/getInfoPublic": { + "get": { "consumes": [ "application/json" ], @@ -2700,23 +2938,42 @@ "application/json" ], "tags": [ - "Menu" + "Info" ], - "summary": "根据id获取菜单", + "summary": "不需要鉴权的公告接口", "parameters": [ { - "description": "菜单id", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.GetById" - } + "type": "string", + "name": "endCreatedAt", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "startCreatedAt", + "in": "query" } ], "responses": { "200": { - "description": "根据id获取菜单,返回包括系统菜单列表", + "description": "获取成功", "schema": { "allOf": [ { @@ -2726,7 +2983,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/response.SysBaseMenuResponse" + "type": "object" }, "msg": { "type": "string" @@ -2739,34 +2996,37 @@ } } }, - "/menu/getBaseMenuTree": { - "post": { + "/info/updateInfo": { + "put": { "security": [ { "ApiKeyAuth": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "AuthorityMenu" + "Info" ], - "summary": "获取用户动态路由", + "summary": "更新公告", "parameters": [ { - "description": "空", + "description": "更新公告", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.Empty" + "$ref": "#/definitions/model.Info" } } ], "responses": { "200": { - "description": "获取用户动态路由,返回包括系统菜单列表", + "description": "更新成功", "schema": { "allOf": [ { @@ -2775,9 +3035,6 @@ { "type": "object", "properties": { - "data": { - "$ref": "#/definitions/response.SysBaseMenusResponse" - }, "msg": { "type": "string" } @@ -2789,34 +3046,18 @@ } } }, - "/menu/getMenu": { + "/init/checkdb": { "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], "produces": [ "application/json" ], "tags": [ - "AuthorityMenu" - ], - "summary": "获取用户动态路由", - "parameters": [ - { - "description": "空", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.Empty" - } - } + "CheckDB" ], + "summary": "初始化用户数据库", "responses": { "200": { - "description": "获取用户动态路由,返回包括系统菜单详情列表", + "description": "初始化用户数据库", "schema": { "allOf": [ { @@ -2826,7 +3067,8 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/response.SysMenusResponse" + "type": "object", + "additionalProperties": true }, "msg": { "type": "string" @@ -2839,37 +3081,29 @@ } } }, - "/menu/getMenuAuthority": { + "/init/initdb": { "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], "tags": [ - "AuthorityMenu" + "InitDB" ], - "summary": "获取指定角色menu", + "summary": "初始化用户数据库", "parameters": [ { - "description": "角色ID", + "description": "初始化数据库参数", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.GetAuthorityId" + "$ref": "#/definitions/request.InitDB" } } ], "responses": { "200": { - "description": "获取指定角色menu", + "description": "初始化用户数据库", "schema": { "allOf": [ { @@ -2879,10 +3113,6 @@ "type": "object", "properties": { "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { "type": "string" } } @@ -2893,7 +3123,7 @@ } } }, - "/menu/getMenuList": { + "/jwt/jsonInBlacklist": { "post": { "security": [ { @@ -2907,23 +3137,698 @@ "application/json" ], "tags": [ - "Menu" + "Jwt" ], - "summary": "分页获取基础menu列表", - "parameters": [ - { - "description": "页码, 每页大小", - "name": "data", - "in": "body", - "required": true, + "summary": "jwt加入黑名单", + "responses": { + "200": { + "description": "jwt加入黑名单", "schema": { - "$ref": "#/definitions/request.PageInfo" + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/addBaseMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "新增菜单", + "parameters": [ + { + "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysBaseMenu" + } + } + ], + "responses": { + "200": { + "description": "新增菜单", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/addMenuAuthority": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "增加menu和角色关联关系", + "parameters": [ + { + "description": "角色ID", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.AddMenuAuthorityInfo" + } + } + ], + "responses": { + "200": { + "description": "增加menu和角色关联关系", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/deleteBaseMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "删除菜单", + "parameters": [ + { + "description": "菜单id", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GetById" + } + } + ], + "responses": { + "200": { + "description": "删除菜单", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getBaseMenuById": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "根据id获取菜单", + "parameters": [ + { + "description": "菜单id", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GetById" + } + } + ], + "responses": { + "200": { + "description": "根据id获取菜单,返回包括系统菜单列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.SysBaseMenuResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getBaseMenuTree": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取用户动态路由", + "parameters": [ + { + "description": "空", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.Empty" + } + } + ], + "responses": { + "200": { + "description": "获取用户动态路由,返回包括系统菜单列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.SysBaseMenusResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取用户动态路由", + "parameters": [ + { + "description": "空", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.Empty" + } + } + ], + "responses": { + "200": { + "description": "获取用户动态路由,返回包括系统菜单详情列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.SysMenusResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getMenuAuthority": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取指定角色menu", + "parameters": [ + { + "description": "角色ID", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GetAuthorityId" + } + } + ], + "responses": { + "200": { + "description": "获取指定角色menu", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/getMenuList": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "分页获取基础menu列表", + "parameters": [ + { + "description": "页码, 每页大小", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.PageInfo" + } + } + ], + "responses": { + "200": { + "description": "分页获取基础menu列表,返回包括列表,总数,页码,每页数量", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/updateBaseMenu": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Menu" + ], + "summary": "更新菜单", + "parameters": [ + { + "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysBaseMenu" + } + } + ], + "responses": { + "200": { + "description": "更新菜单", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionary/createSysDictionary": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "创建SysDictionary", + "parameters": [ + { + "description": "SysDictionary模型", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysDictionary" + } + } + ], + "responses": { + "200": { + "description": "创建SysDictionary", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionary/deleteSysDictionary": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "删除SysDictionary", + "parameters": [ + { + "description": "SysDictionary模型", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysDictionary" + } + } + ], + "responses": { + "200": { + "description": "删除SysDictionary", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionary/findSysDictionary": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "用id查询SysDictionary", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "描述", + "name": "desc", + "in": "query" + }, + { + "type": "string", + "description": "字典名(中)", + "name": "name", + "in": "query" + }, + { + "type": "boolean", + "description": "状态", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "字典名(英)", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + } + ], + "responses": { + "200": { + "description": "用id查询SysDictionary", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] } } + } + } + }, + "/sysDictionary/getSysDictionaryList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" ], + "summary": "分页获取SysDictionary列表", "responses": { "200": { - "description": "分页获取基础menu列表,返回包括列表,总数,页码,每页数量", + "description": "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量", "schema": { "allOf": [ { @@ -2946,8 +3851,8 @@ } } }, - "/menu/updateBaseMenu": { - "post": { + "/sysDictionary/updateSysDictionary": { + "put": { "security": [ { "ApiKeyAuth": [] @@ -2960,23 +3865,23 @@ "application/json" ], "tags": [ - "Menu" + "SysDictionary" ], - "summary": "更新菜单", + "summary": "更新SysDictionary", "parameters": [ { - "description": "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记", + "description": "SysDictionary模型", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysBaseMenu" + "$ref": "#/definitions/system.SysDictionary" } } ], "responses": { "200": { - "description": "更新菜单", + "description": "更新SysDictionary", "schema": { "allOf": [ { @@ -2996,7 +3901,7 @@ } } }, - "/sysDictionary/createSysDictionary": { + "/sysDictionaryDetail/createSysDictionaryDetail": { "post": { "security": [ { @@ -3010,23 +3915,23 @@ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" ], - "summary": "创建SysDictionary", + "summary": "创建SysDictionaryDetail", "parameters": [ { - "description": "SysDictionary模型", + "description": "SysDictionaryDetail模型", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionary" + "$ref": "#/definitions/system.SysDictionaryDetail" } } ], "responses": { "200": { - "description": "创建SysDictionary", + "description": "创建SysDictionaryDetail", "schema": { "allOf": [ { @@ -3046,7 +3951,7 @@ } } }, - "/sysDictionary/deleteSysDictionary": { + "/sysDictionaryDetail/deleteSysDictionaryDetail": { "delete": { "security": [ { @@ -3060,23 +3965,23 @@ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" ], - "summary": "删除SysDictionary", + "summary": "删除SysDictionaryDetail", "parameters": [ { - "description": "SysDictionary模型", + "description": "SysDictionaryDetail模型", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionary" + "$ref": "#/definitions/system.SysDictionaryDetail" } } ], "responses": { "200": { - "description": "删除SysDictionary", + "description": "删除SysDictionaryDetail", "schema": { "allOf": [ { @@ -3096,7 +4001,7 @@ } } }, - "/sysDictionary/findSysDictionary": { + "/sysDictionaryDetail/findSysDictionaryDetail": { "get": { "security": [ { @@ -3110,9 +4015,9 @@ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" ], - "summary": "用id查询SysDictionary", + "summary": "用id查询SysDictionaryDetail", "parameters": [ { "type": "integer", @@ -3128,26 +4033,32 @@ }, { "type": "string", - "description": "描述", - "name": "desc", + "description": "扩展值", + "name": "extend", "in": "query" }, { "type": "string", - "description": "字典名(中)", - "name": "name", + "description": "展示值", + "name": "label", + "in": "query" + }, + { + "type": "integer", + "description": "排序标记", + "name": "sort", "in": "query" }, { "type": "boolean", - "description": "状态", + "description": "启用状态", "name": "status", "in": "query" }, { - "type": "string", - "description": "字典名(英)", - "name": "type", + "type": "integer", + "description": "关联标记", + "name": "sysDictionaryID", "in": "query" }, { @@ -3155,11 +4066,17 @@ "description": "更新时间", "name": "updatedAt", "in": "query" + }, + { + "type": "string", + "description": "字典值", + "name": "value", + "in": "query" } ], "responses": { "200": { - "description": "用id查询SysDictionary", + "description": "用id查询SysDictionaryDetail", "schema": { "allOf": [ { @@ -3183,7 +4100,7 @@ } } }, - "/sysDictionary/getSysDictionaryList": { + "/sysDictionaryDetail/getSysDictionaryDetailList": { "get": { "security": [ { @@ -3197,12 +4114,139 @@ "application/json" ], "tags": [ - "SysDictionary" + "SysDictionaryDetail" + ], + "summary": "分页获取SysDictionaryDetail列表", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "扩展值", + "name": "extend", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "展示值", + "name": "label", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "integer", + "description": "排序标记", + "name": "sort", + "in": "query" + }, + { + "type": "boolean", + "description": "启用状态", + "name": "status", + "in": "query" + }, + { + "type": "integer", + "description": "关联标记", + "name": "sysDictionaryID", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + }, + { + "type": "string", + "description": "字典值", + "name": "value", + "in": "query" + } + ], + "responses": { + "200": { + "description": "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/updateSysDictionaryDetail": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "更新SysDictionaryDetail", + "parameters": [ + { + "description": "更新SysDictionaryDetail", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + } ], - "summary": "分页获取SysDictionary列表", "responses": { "200": { - "description": "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量", + "description": "更新SysDictionaryDetail", "schema": { "allOf": [ { @@ -3211,9 +4255,6 @@ { "type": "object", "properties": { - "data": { - "$ref": "#/definitions/response.PageResult" - }, "msg": { "type": "string" } @@ -3225,8 +4266,8 @@ } } }, - "/sysDictionary/updateSysDictionary": { - "put": { + "/sysExportTemplate/createSysExportTemplate": { + "post": { "security": [ { "ApiKeyAuth": [] @@ -3239,44 +4280,32 @@ "application/json" ], "tags": [ - "SysDictionary" + "SysExportTemplate" ], - "summary": "更新SysDictionary", + "summary": "创建导出模板", "parameters": [ { - "description": "SysDictionary模型", + "description": "创建导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionary" + "$ref": "#/definitions/system.SysExportTemplate" } } ], "responses": { "200": { - "description": "更新SysDictionary", + "description": "{\"success\":true,\"data\":{},\"msg\":\"创建成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/createSysDictionaryDetail": { - "post": { + "/sysExportTemplate/deleteSysExportTemplate": { + "delete": { "security": [ { "ApiKeyAuth": [] @@ -3289,43 +4318,31 @@ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "创建SysDictionaryDetail", + "summary": "删除导出模板", "parameters": [ { - "description": "SysDictionaryDetail模型", + "description": "删除导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionaryDetail" + "$ref": "#/definitions/system.SysExportTemplate" } } ], "responses": { "200": { - "description": "创建SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"删除成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/deleteSysDictionaryDetail": { + "/sysExportTemplate/deleteSysExportTemplateByIds": { "delete": { "security": [ { @@ -3339,43 +4356,31 @@ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "删除SysDictionaryDetail", + "summary": "批量删除导出模板", "parameters": [ { - "description": "SysDictionaryDetail模型", + "description": "批量删除导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionaryDetail" + "$ref": "#/definitions/request.IdsReq" } } ], "responses": { "200": { - "description": "删除SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"批量删除成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/findSysDictionaryDetail": { + "/sysExportTemplate/exportExcel": { "get": { "security": [ { @@ -3389,9 +4394,29 @@ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "用id查询SysDictionaryDetail", + "summary": "导出表格模板", + "responses": {} + } + }, + "/sysExportTemplate/findSysExportTemplate": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysExportTemplate" + ], + "summary": "用id查询导出模板", "parameters": [ { "type": "integer", @@ -3407,74 +4432,62 @@ }, { "type": "string", - "description": "扩展值", - "name": "extend", + "description": "数据库名称", + "name": "dbName", + "in": "query" + }, + { + "type": "integer", + "name": "limit", "in": "query" }, { "type": "string", - "description": "展示值", - "name": "label", + "description": "模板名称", + "name": "name", "in": "query" }, { - "type": "integer", - "description": "排序标记", - "name": "sort", + "type": "string", + "name": "order", "in": "query" }, { - "type": "boolean", - "description": "启用状态", - "name": "status", + "type": "string", + "description": "表名称", + "name": "tableName", "in": "query" }, { - "type": "integer", - "description": "关联标记", - "name": "sysDictionaryID", + "type": "string", + "description": "模板标识", + "name": "templateID", "in": "query" }, { "type": "string", - "description": "更新时间", - "name": "updatedAt", + "description": "模板信息", + "name": "templateInfo", "in": "query" }, { - "type": "integer", - "description": "字典值", - "name": "value", + "type": "string", + "description": "更新时间", + "name": "updatedAt", "in": "query" } ], "responses": { "200": { - "description": "用id查询SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"查询成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/getSysDictionaryDetailList": { + "/sysExportTemplate/getSysExportTemplateList": { "get": { "security": [ { @@ -3488,9 +4501,9 @@ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "分页获取SysDictionaryDetail列表", + "summary": "分页获取导出模板列表", "parameters": [ { "type": "integer", @@ -3506,8 +4519,13 @@ }, { "type": "string", - "description": "扩展值", - "name": "extend", + "description": "数据库名称", + "name": "dbName", + "in": "query" + }, + { + "type": "string", + "name": "endCreatedAt", "in": "query" }, { @@ -3516,10 +4534,20 @@ "name": "keyword", "in": "query" }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, { "type": "string", - "description": "展示值", - "name": "label", + "description": "模板名称", + "name": "name", + "in": "query" + }, + { + "type": "string", + "name": "order", "in": "query" }, { @@ -3535,62 +4563,66 @@ "in": "query" }, { - "type": "integer", - "description": "排序标记", - "name": "sort", + "type": "string", + "name": "startCreatedAt", "in": "query" }, { - "type": "boolean", - "description": "启用状态", - "name": "status", + "type": "string", + "description": "表名称", + "name": "tableName", "in": "query" }, { - "type": "integer", - "description": "关联标记", - "name": "sysDictionaryID", + "type": "string", + "description": "模板标识", + "name": "templateID", "in": "query" }, { "type": "string", - "description": "更新时间", - "name": "updatedAt", + "description": "模板信息", + "name": "templateInfo", "in": "query" }, { - "type": "integer", - "description": "字典值", - "name": "value", + "type": "string", + "description": "更新时间", + "name": "updatedAt", "in": "query" } ], "responses": { "200": { - "description": "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量", + "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/response.PageResult" - }, - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } } }, - "/sysDictionaryDetail/updateSysDictionaryDetail": { + "/sysExportTemplate/importExcel": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysImportTemplate" + ], + "summary": "导入表格", + "responses": {} + } + }, + "/sysExportTemplate/updateSysExportTemplate": { "put": { "security": [ { @@ -3604,37 +4636,25 @@ "application/json" ], "tags": [ - "SysDictionaryDetail" + "SysExportTemplate" ], - "summary": "更新SysDictionaryDetail", + "summary": "更新导出模板", "parameters": [ { - "description": "更新SysDictionaryDetail", + "description": "更新导出模板", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/system.SysDictionaryDetail" + "$ref": "#/definitions/system.SysExportTemplate" } } ], "responses": { "200": { - "description": "更新SysDictionaryDetail", + "description": "{\"success\":true,\"data\":{},\"msg\":\"更新成功\"}", "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] + "type": "string" } } } @@ -4733,49 +5753,22 @@ } } }, - "config.Autocode": { - "type": "object", - "properties": { - "root": { - "type": "string" - }, - "server": { - "type": "string" - }, - "server-api": { - "type": "string" - }, - "server-initialize": { - "type": "string" - }, - "server-model": { - "type": "string" - }, - "server-plug": { - "type": "string" - }, - "server-request": { - "type": "string" - }, - "server-router": { - "type": "string" - }, - "server-service": { + "config.Autocode": { + "type": "object", + "properties": { + "ai-path": { "type": "string" }, - "transfer-restart": { - "type": "boolean" - }, - "web": { + "module": { "type": "string" }, - "web-api": { + "root": { "type": "string" }, - "web-form": { + "server": { "type": "string" }, - "web-table": { + "web": { "type": "string" } } @@ -4871,6 +5864,37 @@ } } }, + "config.CloudflareR2": { + "type": "object", + "properties": { + "access-key-id": { + "type": "string" + }, + "account-id": { + "type": "string" + }, + "base-url": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "path": { + "type": "string" + }, + "secret-access-key": { + "type": "string" + } + } + }, + "config.DiskList": { + "type": "object", + "properties": { + "mount-point": { + "type": "string" + } + } + }, "config.Excel": { "type": "object", "properties": { @@ -4936,6 +5960,10 @@ "config.Mongo": { "type": "object", "properties": { + "auth-source": { + "description": "验证数据库", + "type": "string" + }, "coll": { "description": "collection name", "type": "string" @@ -5035,12 +6063,15 @@ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5048,7 +6079,7 @@ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5090,12 +6121,15 @@ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5103,7 +6137,7 @@ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5145,12 +6179,15 @@ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5158,7 +6195,7 @@ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5200,12 +6237,15 @@ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5213,7 +6253,7 @@ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5258,13 +6298,24 @@ "description": "服务器地址:端口", "type": "string" }, + "clusterAddrs": { + "description": "集群模式下的节点地址列表", + "type": "array", + "items": { + "type": "string" + } + }, "db": { - "description": "redis的哪个数据库", + "description": "单实例模式下redis的哪个数据库", "type": "integer" }, "password": { "description": "密码", "type": "string" + }, + "useCluster": { + "description": "是否使用集群模式", + "type": "boolean" } } }, @@ -5288,6 +6339,9 @@ "captcha": { "$ref": "#/definitions/config.Captcha" }, + "cloudflare-r2": { + "$ref": "#/definitions/config.CloudflareR2" + }, "cors": { "description": "跨域配置", "allOf": [ @@ -5302,6 +6356,12 @@ "$ref": "#/definitions/config.SpecializedDB" } }, + "disk-list": { + "type": "array", + "items": { + "$ref": "#/definitions/config.DiskList" + } + }, "email": { "$ref": "#/definitions/github_com_flipped-aurora_gin-vue-admin_server_config.Email" }, @@ -5405,12 +6465,15 @@ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5421,7 +6484,7 @@ "type": "string" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5463,12 +6526,15 @@ "type": "string" }, "path": { + "description": "数据库地址", "type": "string" }, "port": { + "description": "数据库端口", "type": "string" }, "prefix": { + "description": "数据库前缀", "type": "string" }, "singular": { @@ -5476,7 +6542,7 @@ "type": "boolean" }, "username": { - "description": "数据库密码", + "description": "数据库账号", "type": "string" } } @@ -5492,10 +6558,6 @@ "description": "数据库类型:mysql(默认)|sqlite|sqlserver|postgresql", "type": "string" }, - "env": { - "description": "环境值", - "type": "string" - }, "iplimit-count": { "type": "integer" }, @@ -5510,7 +6572,7 @@ "type": "string" }, "use-mongo": { - "description": "使用redis", + "description": "使用mongo", "type": "boolean" }, "use-multipoint": { @@ -5569,14 +6631,14 @@ "description": "输出控制台", "type": "boolean" }, - "max-age": { - "description": "日志留存时间", - "type": "integer" - }, "prefix": { "description": "日志前缀", "type": "string" }, + "retention-day": { + "description": "日志保留天数", + "type": "integer" + }, "show-line": { "description": "显示行", "type": "boolean" @@ -5758,6 +6820,42 @@ } } }, + "model.Info": { + "type": "object", + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "attachments": { + "description": "附件", + "type": "array", + "items": { + "type": "object" + } + }, + "content": { + "description": "内容", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "title": { + "description": "标题", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + }, + "userID": { + "description": "作者", + "type": "integer" + } + } + }, "request.AddMenuAuthorityInfo": { "type": "object", "properties": { @@ -5773,6 +6871,9 @@ } } }, + "request.AutoCode": { + "type": "object" + }, "request.CasbinInReceive": { "type": "object", "properties": { @@ -5849,9 +6950,13 @@ "request.InitDB": { "type": "object", "required": [ + "adminPassword", "dbName" ], "properties": { + "adminPassword": { + "type": "string" + }, "dbName": { "description": "数据库名", "type": "string" @@ -5961,19 +7066,6 @@ } } }, - "request.RollBack": { - "type": "object", - "properties": { - "deleteTable": { - "description": "是否删除表", - "type": "boolean" - }, - "id": { - "description": "主键ID", - "type": "integer" - } - } - }, "request.SearchApiParams": { "type": "object", "properties": { @@ -6068,19 +7160,44 @@ } } }, - "request.SysAutoHistory": { + "request.SysAutoCodePackageCreate": { "type": "object", "properties": { - "keyword": { - "description": "关键字", - "type": "string" + "desc": { + "type": "string", + "example": "描述" }, - "page": { - "description": "页码", - "type": "integer" + "label": { + "type": "string", + "example": "展示名" }, - "pageSize": { - "description": "每页大小", + "packageName": { + "type": "string", + "example": "包名" + }, + "template": { + "type": "string", + "example": "模版" + } + } + }, + "request.SysAutoHistoryRollBack": { + "type": "object", + "properties": { + "deleteApi": { + "description": "是否删除接口", + "type": "boolean" + }, + "deleteMenu": { + "description": "是否删除菜单", + "type": "boolean" + }, + "deleteTable": { + "description": "是否删除表", + "type": "boolean" + }, + "id": { + "description": "主键ID", "type": "integer" } } @@ -6299,117 +7416,61 @@ } } }, - "system.AutoCodeStruct": { + "system.Condition": { "type": "object", "properties": { - "abbreviation": { - "description": "Struct简称", - "type": "string" - }, - "autoCreateApiToSql": { - "description": "是否自动创建api", - "type": "boolean" - }, - "autoCreateResource": { - "description": "是否自动创建资源标识", - "type": "boolean" - }, - "autoMoveFile": { - "description": "是否自动移动文件", - "type": "boolean" - }, - "businessDB": { - "description": "业务数据库", - "type": "string" + "ID": { + "description": "主键ID", + "type": "integer" }, - "description": { - "description": "Struct中文名称", + "column": { "type": "string" }, - "fields": { - "type": "array", - "items": { - "$ref": "#/definitions/system.Field" - } - }, - "hasTimer": { - "type": "boolean" - }, - "humpPackageName": { - "description": "go文件名称", + "createdAt": { + "description": "创建时间", "type": "string" }, - "package": { + "from": { "type": "string" }, - "packageName": { - "description": "文件名称", + "operator": { "type": "string" }, - "structName": { - "description": "Struct名称", + "templateID": { "type": "string" }, - "tableName": { - "description": "表名", + "updatedAt": { + "description": "更新时间", "type": "string" } } }, - "system.Field": { + "system.JoinTemplate": { "type": "object", "properties": { - "clearable": { - "description": "是否可清空", - "type": "boolean" - }, - "columnName": { - "description": "数据库字段", - "type": "string" - }, - "comment": { - "description": "数据库字段描述", - "type": "string" - }, - "dataTypeLong": { - "description": "数据库字段长度", - "type": "string" - }, - "dictType": { - "description": "字典", - "type": "string" + "ID": { + "description": "主键ID", + "type": "integer" }, - "errorText": { - "description": "校验失败文字", + "createdAt": { + "description": "创建时间", "type": "string" }, - "fieldDesc": { - "description": "中文名", + "joins": { "type": "string" }, - "fieldJson": { - "description": "FieldJson", + "on": { "type": "string" }, - "fieldName": { - "description": "Field名", + "table": { "type": "string" }, - "fieldSearchType": { - "description": "搜索条件", + "templateID": { "type": "string" }, - "fieldType": { - "description": "Field数据类型", + "updatedAt": { + "description": "更新时间", "type": "string" - }, - "require": { - "description": "是否必填", - "type": "boolean" - }, - "sort": { - "description": "是否增加排序", - "type": "boolean" } } }, @@ -6524,32 +7585,6 @@ } } }, - "system.SysAutoCode": { - "type": "object", - "properties": { - "ID": { - "description": "主键ID", - "type": "integer" - }, - "createdAt": { - "description": "创建时间", - "type": "string" - }, - "desc": { - "type": "string" - }, - "label": { - "type": "string" - }, - "packageName": { - "type": "string" - }, - "updatedAt": { - "description": "更新时间", - "type": "string" - } - } - }, "system.SysBaseMenu": { "type": "object", "properties": { @@ -6607,7 +7642,7 @@ }, "parentId": { "description": "父菜单ID", - "type": "string" + "type": "integer" }, "path": { "description": "路由path", @@ -6757,7 +7792,62 @@ }, "value": { "description": "字典值", + "type": "string" + } + } + }, + "system.SysExportTemplate": { + "type": "object", + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/system.Condition" + } + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "dbName": { + "description": "数据库名称", + "type": "string" + }, + "joinTemplate": { + "type": "array", + "items": { + "$ref": "#/definitions/system.JoinTemplate" + } + }, + "limit": { "type": "integer" + }, + "name": { + "description": "模板名称", + "type": "string" + }, + "order": { + "type": "string" + }, + "tableName": { + "description": "表名称", + "type": "string" + }, + "templateID": { + "description": "模板标识", + "type": "string" + }, + "templateInfo": { + "description": "模板信息", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" } } }, @@ -6805,7 +7895,7 @@ } }, "menuId": { - "type": "string" + "type": "integer" }, "meta": { "description": "附加属性", @@ -6827,7 +7917,7 @@ }, "parentId": { "description": "父菜单ID", - "type": "string" + "type": "integer" }, "path": { "description": "路由path", @@ -6910,10 +8000,6 @@ "description": "主键ID", "type": "integer" }, - "activeColor": { - "description": "活跃颜色", - "type": "string" - }, "authorities": { "type": "array", "items": { @@ -6989,4 +8075,4 @@ "in": "header" } } -} +} \ No newline at end of file diff --git a/server/docs/swagger.yaml b/server/docs/swagger.yaml index 7ebd7259ca..789d4db8aa 100644 --- a/server/docs/swagger.yaml +++ b/server/docs/swagger.yaml @@ -16,34 +16,16 @@ definitions: type: object config.Autocode: properties: - root: - type: string - server: - type: string - server-api: + ai-path: type: string - server-initialize: + module: type: string - server-model: - type: string - server-plug: - type: string - server-request: - type: string - server-router: + root: type: string - server-service: + server: type: string - transfer-restart: - type: boolean web: type: string - web-api: - type: string - web-form: - type: string - web-table: - type: string type: object config.AwsS3: properties: @@ -106,6 +88,26 @@ definitions: description: 防爆破验证码超时时间,单位:s(秒) type: integer type: object + config.CloudflareR2: + properties: + access-key-id: + type: string + account-id: + type: string + base-url: + type: string + bucket: + type: string + path: + type: string + secret-access-key: + type: string + type: object + config.DiskList: + properties: + mount-point: + type: string + type: object config.Excel: properties: dir: @@ -150,6 +152,9 @@ definitions: type: object config.Mongo: properties: + auth-source: + description: 验证数据库 + type: string coll: description: collection name type: string @@ -223,16 +228,19 @@ definitions: description: 数据库密码 type: string path: + description: 数据库地址 type: string port: + description: 数据库端口 type: string prefix: + description: 数据库前缀 type: string singular: description: 是否开启全局禁用复数,true表示开启 type: boolean username: - description: 数据库密码 + description: 数据库账号 type: string type: object config.Mysql: @@ -263,16 +271,19 @@ definitions: description: 数据库密码 type: string path: + description: 数据库地址 type: string port: + description: 数据库端口 type: string prefix: + description: 数据库前缀 type: string singular: description: 是否开启全局禁用复数,true表示开启 type: boolean username: - description: 数据库密码 + description: 数据库账号 type: string type: object config.Oracle: @@ -303,16 +314,19 @@ definitions: description: 数据库密码 type: string path: + description: 数据库地址 type: string port: + description: 数据库端口 type: string prefix: + description: 数据库前缀 type: string singular: description: 是否开启全局禁用复数,true表示开启 type: boolean username: - description: 数据库密码 + description: 数据库账号 type: string type: object config.Pgsql: @@ -343,16 +357,19 @@ definitions: description: 数据库密码 type: string path: + description: 数据库地址 type: string port: + description: 数据库端口 type: string prefix: + description: 数据库前缀 type: string singular: description: 是否开启全局禁用复数,true表示开启 type: boolean username: - description: 数据库密码 + description: 数据库账号 type: string type: object config.Qiniu: @@ -384,12 +401,20 @@ definitions: addr: description: 服务器地址:端口 type: string + clusterAddrs: + description: 集群模式下的节点地址列表 + items: + type: string + type: array db: - description: redis的哪个数据库 + description: 单实例模式下redis的哪个数据库 type: integer password: description: 密码 type: string + useCluster: + description: 是否使用集群模式 + type: boolean type: object config.Server: properties: @@ -403,6 +428,8 @@ definitions: $ref: '#/definitions/config.AwsS3' captcha: $ref: '#/definitions/config.Captcha' + cloudflare-r2: + $ref: '#/definitions/config.CloudflareR2' cors: allOf: - $ref: '#/definitions/config.CORS' @@ -411,6 +438,10 @@ definitions: items: $ref: '#/definitions/config.SpecializedDB' type: array + disk-list: + items: + $ref: '#/definitions/config.DiskList' + type: array email: $ref: '#/definitions/github_com_flipped-aurora_gin-vue-admin_server_config.Email' excel: @@ -480,10 +511,13 @@ definitions: description: 数据库密码 type: string path: + description: 数据库地址 type: string port: + description: 数据库端口 type: string prefix: + description: 数据库前缀 type: string singular: description: 是否开启全局禁用复数,true表示开启 @@ -491,7 +525,7 @@ definitions: type: type: string username: - description: 数据库密码 + description: 数据库账号 type: string type: object config.Sqlite: @@ -522,16 +556,19 @@ definitions: description: 数据库密码 type: string path: + description: 数据库地址 type: string port: + description: 数据库端口 type: string prefix: + description: 数据库前缀 type: string singular: description: 是否开启全局禁用复数,true表示开启 type: boolean username: - description: 数据库密码 + description: 数据库账号 type: string type: object config.System: @@ -542,9 +579,6 @@ definitions: db-type: description: 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql type: string - env: - description: 环境值 - type: string iplimit-count: type: integer iplimit-time: @@ -555,7 +589,7 @@ definitions: router-prefix: type: string use-mongo: - description: 使用redis + description: 使用mongo type: boolean use-multipoint: description: 多点登录拦截 @@ -596,12 +630,12 @@ definitions: log-in-console: description: 输出控制台 type: boolean - max-age: - description: 日志留存时间 - type: integer prefix: description: 日志前缀 type: string + retention-day: + description: 日志保留天数 + type: integer show-line: description: 显示行 type: boolean @@ -729,6 +763,32 @@ definitions: description: 收件人:多个以英文逗号分隔 例:a@qq.com b@qq.com 正式开发中请把此项目作为参数使用 type: string type: object + model.Info: + properties: + ID: + description: 主键ID + type: integer + attachments: + description: 附件 + items: + type: object + type: array + content: + description: 内容 + type: string + createdAt: + description: 创建时间 + type: string + title: + description: 标题 + type: string + updatedAt: + description: 更新时间 + type: string + userID: + description: 作者 + type: integer + type: object request.AddMenuAuthorityInfo: properties: authorityId: @@ -739,6 +799,8 @@ definitions: $ref: '#/definitions/system.SysBaseMenu' type: array type: object + request.AutoCode: + type: object request.CasbinInReceive: properties: authorityId: @@ -790,6 +852,8 @@ definitions: type: object request.InitDB: properties: + adminPassword: + type: string dbName: description: 数据库名 type: string @@ -812,6 +876,7 @@ definitions: description: 数据库用户名 type: string required: + - adminPassword - dbName type: object request.Login: @@ -871,15 +936,6 @@ definitions: example: 用户名 type: string type: object - request.RollBack: - properties: - deleteTable: - description: 是否删除表 - type: boolean - id: - description: 主键ID - type: integer - type: object request.SearchApiParams: properties: ID: @@ -946,16 +1002,34 @@ definitions: type: integer type: array type: object - request.SysAutoHistory: + request.SysAutoCodePackageCreate: properties: - keyword: - description: 关键字 + desc: + example: 描述 type: string - page: - description: 页码 - type: integer - pageSize: - description: 每页大小 + label: + example: 展示名 + type: string + packageName: + example: 包名 + type: string + template: + example: 模版 + type: string + type: object + request.SysAutoHistoryRollBack: + properties: + deleteApi: + description: 是否删除接口 + type: boolean + deleteMenu: + description: 是否删除菜单 + type: boolean + deleteTable: + description: 是否删除表 + type: boolean + id: + description: 主键ID type: integer type: object response.Email: @@ -1096,88 +1170,45 @@ definitions: user: $ref: '#/definitions/system.SysUser' type: object - system.AutoCodeStruct: + system.Condition: properties: - abbreviation: - description: Struct简称 - type: string - autoCreateApiToSql: - description: 是否自动创建api - type: boolean - autoCreateResource: - description: 是否自动创建资源标识 - type: boolean - autoMoveFile: - description: 是否自动移动文件 - type: boolean - businessDB: - description: 业务数据库 - type: string - description: - description: Struct中文名称 + ID: + description: 主键ID + type: integer + column: type: string - fields: - items: - $ref: '#/definitions/system.Field' - type: array - hasTimer: - type: boolean - humpPackageName: - description: go文件名称 + createdAt: + description: 创建时间 type: string - package: + from: type: string - packageName: - description: 文件名称 + operator: type: string - structName: - description: Struct名称 + templateID: type: string - tableName: - description: 表名 + updatedAt: + description: 更新时间 type: string type: object - system.Field: + system.JoinTemplate: properties: - clearable: - description: 是否可清空 - type: boolean - columnName: - description: 数据库字段 - type: string - comment: - description: 数据库字段描述 - type: string - dataTypeLong: - description: 数据库字段长度 - type: string - dictType: - description: 字典 - type: string - errorText: - description: 校验失败文字 + ID: + description: 主键ID + type: integer + createdAt: + description: 创建时间 type: string - fieldDesc: - description: 中文名 + joins: type: string - fieldJson: - description: FieldJson + "on": type: string - fieldName: - description: Field名 + table: type: string - fieldSearchType: - description: 搜索条件 + templateID: type: string - fieldType: - description: Field数据类型 + updatedAt: + description: 更新时间 type: string - require: - description: 是否必填 - type: boolean - sort: - description: 是否增加排序 - type: boolean type: object system.Meta: properties: @@ -1258,24 +1289,6 @@ definitions: description: 更新时间 type: string type: object - system.SysAutoCode: - properties: - ID: - description: 主键ID - type: integer - createdAt: - description: 创建时间 - type: string - desc: - type: string - label: - type: string - packageName: - type: string - updatedAt: - description: 更新时间 - type: string - type: object system.SysBaseMenu: properties: ID: @@ -1315,7 +1328,7 @@ definitions: type: array parentId: description: 父菜单ID - type: string + type: integer path: description: 路由path type: string @@ -1423,7 +1436,46 @@ definitions: type: string value: description: 字典值 + type: string + type: object + system.SysExportTemplate: + properties: + ID: + description: 主键ID + type: integer + conditions: + items: + $ref: '#/definitions/system.Condition' + type: array + createdAt: + description: 创建时间 + type: string + dbName: + description: 数据库名称 + type: string + joinTemplate: + items: + $ref: '#/definitions/system.JoinTemplate' + type: array + limit: type: integer + name: + description: 模板名称 + type: string + order: + type: string + tableName: + description: 表名称 + type: string + templateID: + description: 模板标识 + type: string + templateInfo: + description: 模板信息 + type: string + updatedAt: + description: 更新时间 + type: string type: object system.SysMenu: properties: @@ -1456,7 +1508,7 @@ definitions: $ref: '#/definitions/system.SysBaseMenuBtn' type: array menuId: - type: string + type: integer meta: allOf: - $ref: '#/definitions/system.Meta' @@ -1470,7 +1522,7 @@ definitions: type: array parentId: description: 父菜单ID - type: string + type: integer path: description: 路由path type: string @@ -1530,9 +1582,6 @@ definitions: ID: description: 主键ID type: integer - activeColor: - description: 活跃颜色 - type: string authorities: items: $ref: '#/definitions/system.SysAuthority' @@ -1585,7 +1634,7 @@ info: contact: {} description: 使用gin+vue进行极速开发的全栈开发基础平台 title: Gin-Vue-Admin Swagger API接口文档 - version: v2.6.2 + version: v2.7.4 paths: /api/createApi: post: @@ -1671,6 +1720,27 @@ paths: summary: 删除选中Api tags: - SysApi + /api/enterSyncApi: + post: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 确认同步API + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 确认同步API + tags: + - SysApi /api/freshCasbin: get: consumes: @@ -1741,6 +1811,27 @@ paths: summary: 根据id获取api tags: - SysApi + /api/getApiGroups: + post: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 获取API分组 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取API分组 + tags: + - SysApi /api/getApiList: post: consumes: @@ -1771,6 +1862,48 @@ paths: summary: 分页获取API列表 tags: - SysApi + /api/ignoreApi: + post: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 同步API + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 忽略API + tags: + - IgnoreApi + /api/syncApi: + get: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 同步API + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 同步API + tags: + - SysApi /api/updateApi: post: consumes: @@ -2054,53 +2187,45 @@ paths: summary: 设置权限按钮 tags: - AuthorityBtn - /autoCode/createPackage: + /autoCode/addFunc: post: consumes: - application/json parameters: - - description: 创建package + - description: 增加方法 in: body name: data required: true schema: - $ref: '#/definitions/system.SysAutoCode' + $ref: '#/definitions/request.AutoCode' produces: - application/json responses: "200": - description: 创建package成功 + description: '{"success":true,"data":{},"msg":"创建成功"}' schema: - allOf: - - $ref: '#/definitions/response.Response' - - properties: - data: - additionalProperties: true - type: object - msg: - type: string - type: object + type: string security: - ApiKeyAuth: [] - summary: 创建package + summary: 增加方法 tags: - - AutoCode - /autoCode/createPlug: + - AddFunc + /autoCode/createPackage: post: consumes: - application/json parameters: - - description: 创建插件模板 + - description: 创建package in: body name: data required: true schema: - $ref: '#/definitions/system.SysAutoCode' + $ref: '#/definitions/request.SysAutoCodePackageCreate' produces: - application/json responses: "200": - description: 创建插件模板成功 + description: 创建package成功 schema: allOf: - $ref: '#/definitions/response.Response' @@ -2113,9 +2238,9 @@ paths: type: object security: - ApiKeyAuth: [] - summary: 创建插件模板 + summary: 创建package tags: - - AutoCode + - AutoCodePackage /autoCode/createTemp: post: consumes: @@ -2126,7 +2251,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/system.AutoCodeStruct' + $ref: '#/definitions/request.AutoCode' produces: - application/json responses: @@ -2138,7 +2263,7 @@ paths: - ApiKeyAuth: [] summary: 自动代码模板 tags: - - AutoCode + - AutoCodeTemplate /autoCode/delPackage: post: consumes: @@ -2149,7 +2274,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/system.SysAutoCode' + $ref: '#/definitions/request.GetById' produces: - application/json responses: @@ -2300,7 +2425,7 @@ paths: - ApiKeyAuth: [] summary: 获取package tags: - - AutoCode + - AutoCodePackage /autoCode/getSysHistory: post: consumes: @@ -2311,7 +2436,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/request.SysAutoHistory' + $ref: '#/definitions/request.PageInfo' produces: - application/json responses: @@ -2355,6 +2480,30 @@ paths: summary: 获取当前数据库所有表 tags: - AutoCode + /autoCode/getTemplates: + get: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 创建package成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + additionalProperties: true + type: object + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取package + tags: + - AutoCodePackage /autoCode/installPlugin: post: consumes: @@ -2385,7 +2534,7 @@ paths: - ApiKeyAuth: [] summary: 安装插件 tags: - - AutoCode + - AutoCodePlugin /autoCode/preview: post: consumes: @@ -2396,7 +2545,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/system.AutoCodeStruct' + $ref: '#/definitions/request.AutoCode' produces: - application/json responses: @@ -2416,18 +2565,17 @@ paths: - ApiKeyAuth: [] summary: 预览创建后的代码 tags: - - AutoCode + - AutoCodeTemplate /autoCode/pubPlug: get: consumes: - application/json parameters: - - description: 打包插件 - in: body - name: data + - description: 插件名称 + in: query + name: plugName required: true - schema: - $ref: '#/definitions/system.SysAutoCode' + type: string produces: - application/json responses: @@ -2447,7 +2595,7 @@ paths: - ApiKeyAuth: [] summary: 打包插件 tags: - - AutoCode + - AutoCodePlugin /autoCode/rollback: post: consumes: @@ -2458,7 +2606,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/request.RollBack' + $ref: '#/definitions/request.SysAutoHistoryRollBack' produces: - application/json responses: @@ -2955,6 +3103,262 @@ paths: summary: 上传文件示例 tags: - ExaFileUploadAndDownload + /info/createInfo: + post: + consumes: + - application/json + parameters: + - description: 创建公告 + in: body + name: data + required: true + schema: + $ref: '#/definitions/model.Info' + produces: + - application/json + responses: + "200": + description: 创建成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 创建公告 + tags: + - Info + /info/deleteInfo: + delete: + consumes: + - application/json + parameters: + - description: 删除公告 + in: body + name: data + required: true + schema: + $ref: '#/definitions/model.Info' + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 删除公告 + tags: + - Info + /info/deleteInfoByIds: + delete: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 批量删除成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 批量删除公告 + tags: + - Info + /info/findInfo: + get: + consumes: + - application/json + parameters: + - description: 主键ID + in: query + name: ID + type: integer + - description: 内容 + in: query + name: content + type: string + - description: 创建时间 + in: query + name: createdAt + type: string + - description: 标题 + in: query + name: title + type: string + - description: 更新时间 + in: query + name: updatedAt + type: string + - description: 作者 + in: query + name: userID + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.Info' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 用id查询公告 + tags: + - Info + /info/getInfoDataSource: + get: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + type: object + msg: + type: string + type: object + summary: 获取Info的数据源 + tags: + - Info + /info/getInfoList: + get: + consumes: + - application/json + parameters: + - in: query + name: endCreatedAt + type: string + - description: 关键字 + in: query + name: keyword + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页大小 + in: query + name: pageSize + type: integer + - in: query + name: startCreatedAt + type: string + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/response.PageResult' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 分页获取公告列表 + tags: + - Info + /info/getInfoPublic: + get: + consumes: + - application/json + parameters: + - in: query + name: endCreatedAt + type: string + - description: 关键字 + in: query + name: keyword + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页大小 + in: query + name: pageSize + type: integer + - in: query + name: startCreatedAt + type: string + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + type: object + msg: + type: string + type: object + summary: 不需要鉴权的公告接口 + tags: + - Info + /info/updateInfo: + put: + consumes: + - application/json + parameters: + - description: 更新公告 + in: body + name: data + required: true + schema: + $ref: '#/definitions/model.Info' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 更新公告 + tags: + - Info /init/checkdb: post: produces: @@ -3535,7 +3939,7 @@ paths: - description: 字典值 in: query name: value - type: integer + type: string produces: - application/json responses: @@ -3608,7 +4012,7 @@ paths: - description: 字典值 in: query name: value - type: integer + type: string produces: - application/json responses: @@ -3656,6 +4060,250 @@ paths: summary: 更新SysDictionaryDetail tags: - SysDictionaryDetail + /sysExportTemplate/createSysExportTemplate: + post: + consumes: + - application/json + parameters: + - description: 创建导出模板 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysExportTemplate' + produces: + - application/json + responses: + "200": + description: '{"success":true,"data":{},"msg":"创建成功"}' + schema: + type: string + security: + - ApiKeyAuth: [] + summary: 创建导出模板 + tags: + - SysExportTemplate + /sysExportTemplate/deleteSysExportTemplate: + delete: + consumes: + - application/json + parameters: + - description: 删除导出模板 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysExportTemplate' + produces: + - application/json + responses: + "200": + description: '{"success":true,"data":{},"msg":"删除成功"}' + schema: + type: string + security: + - ApiKeyAuth: [] + summary: 删除导出模板 + tags: + - SysExportTemplate + /sysExportTemplate/deleteSysExportTemplateByIds: + delete: + consumes: + - application/json + parameters: + - description: 批量删除导出模板 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.IdsReq' + produces: + - application/json + responses: + "200": + description: '{"success":true,"data":{},"msg":"批量删除成功"}' + schema: + type: string + security: + - ApiKeyAuth: [] + summary: 批量删除导出模板 + tags: + - SysExportTemplate + /sysExportTemplate/exportExcel: + get: + consumes: + - application/json + produces: + - application/json + responses: {} + security: + - ApiKeyAuth: [] + summary: 导出表格模板 + tags: + - SysExportTemplate + /sysExportTemplate/findSysExportTemplate: + get: + consumes: + - application/json + parameters: + - description: 主键ID + in: query + name: ID + type: integer + - description: 创建时间 + in: query + name: createdAt + type: string + - description: 数据库名称 + in: query + name: dbName + type: string + - in: query + name: limit + type: integer + - description: 模板名称 + in: query + name: name + type: string + - in: query + name: order + type: string + - description: 表名称 + in: query + name: tableName + type: string + - description: 模板标识 + in: query + name: templateID + type: string + - description: 模板信息 + in: query + name: templateInfo + type: string + - description: 更新时间 + in: query + name: updatedAt + type: string + produces: + - application/json + responses: + "200": + description: '{"success":true,"data":{},"msg":"查询成功"}' + schema: + type: string + security: + - ApiKeyAuth: [] + summary: 用id查询导出模板 + tags: + - SysExportTemplate + /sysExportTemplate/getSysExportTemplateList: + get: + consumes: + - application/json + parameters: + - description: 主键ID + in: query + name: ID + type: integer + - description: 创建时间 + in: query + name: createdAt + type: string + - description: 数据库名称 + in: query + name: dbName + type: string + - in: query + name: endCreatedAt + type: string + - description: 关键字 + in: query + name: keyword + type: string + - in: query + name: limit + type: integer + - description: 模板名称 + in: query + name: name + type: string + - in: query + name: order + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页大小 + in: query + name: pageSize + type: integer + - in: query + name: startCreatedAt + type: string + - description: 表名称 + in: query + name: tableName + type: string + - description: 模板标识 + in: query + name: templateID + type: string + - description: 模板信息 + in: query + name: templateInfo + type: string + - description: 更新时间 + in: query + name: updatedAt + type: string + produces: + - application/json + responses: + "200": + description: '{"success":true,"data":{},"msg":"获取成功"}' + schema: + type: string + security: + - ApiKeyAuth: [] + summary: 分页获取导出模板列表 + tags: + - SysExportTemplate + /sysExportTemplate/importExcel: + post: + consumes: + - application/json + produces: + - application/json + responses: {} + security: + - ApiKeyAuth: [] + summary: 导入表格 + tags: + - SysImportTemplate + /sysExportTemplate/updateSysExportTemplate: + put: + consumes: + - application/json + parameters: + - description: 更新导出模板 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysExportTemplate' + produces: + - application/json + responses: + "200": + description: '{"success":true,"data":{},"msg":"更新成功"}' + schema: + type: string + security: + - ApiKeyAuth: [] + summary: 更新导出模板 + tags: + - SysExportTemplate /sysOperationRecord/createSysOperationRecord: post: consumes: diff --git a/server/global/global.go b/server/global/global.go index 8310250e70..7291d2a307 100644 --- a/server/global/global.go +++ b/server/global/global.go @@ -1,9 +1,12 @@ package global import ( - "github.com/qiniu/qmgo" + "fmt" "sync" + "github.com/gin-gonic/gin" + "github.com/qiniu/qmgo" + "github.com/flipped-aurora/gin-vue-admin/server/utils/timer" "github.com/songzhibin97/gkit/cache/local_cache" @@ -19,19 +22,21 @@ import ( ) var ( - GVA_DB *gorm.DB - GVA_DBList map[string]*gorm.DB - GVA_REDIS redis.UniversalClient - GVA_MONGO *qmgo.QmgoClient - GVA_CONFIG config.Server - GVA_VP *viper.Viper + GVA_DB *gorm.DB + GVA_DBList map[string]*gorm.DB + GVA_REDIS redis.UniversalClient + GVA_REDISList map[string]redis.UniversalClient + GVA_MONGO *qmgo.QmgoClient + GVA_CONFIG config.Server + GVA_VP *viper.Viper // 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 + GVA_ROUTERS gin.RoutesInfo + GVA_ACTIVE_DBNAME *string + BlackCache local_cache.Cache + lock sync.RWMutex ) // GetGlobalDBByDBName 通过名称获取db list中的db @@ -51,3 +56,11 @@ func MustGetGlobalDBByDBName(dbname string) *gorm.DB { } return db } + +func GetRedis(name string) redis.UniversalClient { + redis, ok := GVA_REDISList[name] + if !ok || redis == nil { + panic(fmt.Sprintf("redis `%s` no init", name)) + } + return redis +} diff --git a/server/go.mod b/server/go.mod index f173e04e3e..e7b4d92446 100644 --- a/server/go.mod +++ b/server/go.mod @@ -1,24 +1,26 @@ module github.com/flipped-aurora/gin-vue-admin/server -go 1.20 +go 1.22 require ( github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible github.com/aws/aws-sdk-go v1.44.307 - github.com/casbin/casbin/v2 v2.71.1 + github.com/casbin/casbin/v2 v2.87.1 github.com/casbin/gorm-adapter/v3 v3.18.0 github.com/flipped-aurora/ws v1.0.2 github.com/fsnotify/fsnotify v1.6.0 github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.9.1 github.com/glebarez/sqlite v1.8.0 - github.com/go-sql-driver/mysql v1.7.1 + github.com/go-sql-driver/mysql v1.8.1 + github.com/goccy/go-json v0.10.2 github.com/gofrs/uuid/v5 v5.0.0 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/gookit/color v1.5.4 github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 - github.com/mojocn/base64Captcha v1.3.5 + github.com/mholt/archiver/v4 v4.0.0-alpha.8 + github.com/mojocn/base64Captcha v1.3.6 github.com/otiai10/copy v1.7.0 github.com/pkg/errors v0.9.1 github.com/qiniu/api.v7/v7 v7.4.1 @@ -38,25 +40,34 @@ require ( go.mongodb.org/mongo-driver v1.12.1 go.uber.org/automaxprocs v1.5.3 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.16.0 - golang.org/x/sync v0.5.0 + golang.org/x/crypto v0.22.0 + golang.org/x/sync v0.6.0 golang.org/x/text v0.14.0 + gorm.io/datatypes v1.2.1 gorm.io/driver/mysql v1.5.6 gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlserver v1.5.1 - gorm.io/gorm v1.25.9 + gorm.io/gen v0.3.26 + gorm.io/gorm v1.25.10 nhooyr.io/websocket v1.8.7 ) require ( - github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect + filippo.io/edwards25519 v1.1.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/bodgit/plumbing v1.2.0 // indirect + github.com/bodgit/sevenzip v1.3.0 // indirect + github.com/bodgit/windows v1.0.0 // indirect github.com/bytedance/sonic v1.9.1 // indirect + github.com/casbin/govaluate v1.1.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/clbanning/mxj v1.8.4 // indirect + github.com/connesc/cipherio v0.2.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dsnet/compress v0.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect @@ -69,24 +80,27 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/golang/snappy v0.0.1 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.4.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/compress v1.15.9 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -99,7 +113,9 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/montanaflynn/stats v0.7.0 // indirect github.com/mozillazg/go-httpheader v0.2.1 // indirect + github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect @@ -111,10 +127,12 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect + github.com/therootcompany/xz v1.0.1 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + github.com/ulikunitz/xz v0.5.10 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect @@ -125,17 +143,19 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect + go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/image v0.11.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/image v0.15.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/time v0.1.0 // indirect - golang.org/x/tools v0.16.1 // indirect - google.golang.org/protobuf v1.30.0 // indirect + golang.org/x/tools v0.17.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gorm.io/datatypes v1.2.0 // indirect - gorm.io/plugin/dbresolver v1.4.1 // indirect + gorm.io/hints v1.1.0 // indirect + gorm.io/plugin/dbresolver v1.5.0 // indirect modernc.org/libc v1.24.1 // indirect modernc.org/mathutil v1.5.0 // indirect modernc.org/memory v1.6.0 // indirect diff --git a/server/go.sum b/server/go.sum index 2a2b722a3e..96febc80d3 100644 --- a/server/go.sum +++ b/server/go.sum @@ -36,31 +36,45 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible h1:KpbJFXwhVeuxNtBJ74MCGbIoaBok2uZvkD7QXp2+Wis= github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/aws/aws-sdk-go v1.44.307 h1:2R0/EPgpZcFSUwZhYImq/srjaOrOfLv5MNRzrFyAM38= github.com/aws/aws-sdk-go v1.44.307/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/bodgit/plumbing v1.2.0 h1:gg4haxoKphLjml+tgnecR4yLBV5zo4HAZGCtAh3xCzM= +github.com/bodgit/plumbing v1.2.0/go.mod h1:b9TeRi7Hvc6Y05rjm8VML3+47n4XTZPtQ/5ghqic2n8= +github.com/bodgit/sevenzip v1.3.0 h1:1ljgELgtHqvgIp8W8kgeEGHIWP4ch3xGI8uOBZgLVKY= +github.com/bodgit/sevenzip v1.3.0/go.mod h1:omwNcgZTEooWM8gA/IJ2Nk/+ZQ94+GsytRzOJJ8FBlM= +github.com/bodgit/windows v1.0.0 h1:rLQ/XjsleZvx4fR1tB/UxQrK+SJ2OFHzfPjLWWOhDIA= +github.com/bodgit/windows v1.0.0/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= +github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/casbin/casbin/v2 v2.71.1 h1:LRHyqM0S1LzM/K59PmfUIN0ZJfLgcOjL4OhOQI/FNXU= -github.com/casbin/casbin/v2 v2.71.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +github.com/casbin/casbin/v2 v2.87.1 h1:7H+ENAfYt3HmZJVw++tJsxx/ko7WEHsfNzpOdYTkpYo= +github.com/casbin/casbin/v2 v2.87.1/go.mod h1:jX8uoN4veP85O/n2674r2qtfSXI6myvxW85f6TH50fw= github.com/casbin/gorm-adapter/v3 v3.18.0 h1:0td7v030eK3H5ftXRHx1d5wVPbuYEJP2ObMSUHtA0Ek= github.com/casbin/gorm-adapter/v3 v3.18.0/go.mod h1:ekufPNBgVIQvv9JffVGsg7KUv4DjnevTh6AQnBNkoK8= +github.com/casbin/govaluate v1.1.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= +github.com/casbin/govaluate v1.1.1 h1:J1rFKIBhiC5xr0APd5HP6rDL+xt+BRoyq1pa4o2i/5c= +github.com/casbin/govaluate v1.1.1/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -76,6 +90,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/connesc/cipherio v0.2.1 h1:FGtpTPMbKNNWByNrr9aEBtaJtXjqOzkIXNYJp6OEycw= +github.com/connesc/cipherio v0.2.1/go.mod h1:ukY0MWJDFnJEbXMQtOcn2VmTpRfzcTz4OoVrWGGJZcA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -83,6 +99,9 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -94,6 +113,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/flipped-aurora/ws v1.0.2 h1:oEUz7sgrbPENvgli7Q4QpC0NIEbJucgR4yjcDMg/AjY= github.com/flipped-aurora/ws v1.0.2/go.mod h1:RdyM2Fnvxx7f7A6WSmU1aAhDrQIAVW7LS/0LsAUE5mE= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc= @@ -101,6 +121,7 @@ github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yH github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= +github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= @@ -125,6 +146,7 @@ github.com/go-openapi/swag v0.22.5 h1:fVS63IE3M0lsuWRzuom3RLwUMVI2peDH01s6M70ugy github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -137,8 +159,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= 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= @@ -184,10 +206,11 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -199,7 +222,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -220,6 +242,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -234,6 +257,11 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -246,10 +274,12 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= @@ -258,6 +288,7 @@ github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= 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.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -275,23 +306,31 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -301,6 +340,11 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrSSDunscGsRM= +github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A= github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu2lKYc= github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -315,13 +359,15 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= -github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= +github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew03H+Tw= +github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= +github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q0rDaRO0MPaOk= +github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -331,6 +377,8 @@ github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI= github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -341,6 +389,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/qiniu/api.v7/v7 v7.4.1 h1:BnNUBimLk6nrA/mIwsww9yJRupmViSsb1ndLMC7a9OY= github.com/qiniu/api.v7/v7 v7.4.1/go.mod h1:VE5oC5rkE1xul0u1S2N0b2Uxq9/6hZzhyqjgK25XDcM= @@ -360,6 +409,8 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/shirou/gopsutil/v3 v3.23.6 h1:5y46WPI9QBKBbK7EEccUPNXpJpNrvPuTD0O2zHEHT08= github.com/shirou/gopsutil/v3 v3.23.6/go.mod h1:j7QX50DrXYggrpN30W0Mo+I4/8U2UUIQrnrhqUeWrAU= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -407,6 +458,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0= github.com/tencentyun/cos-go-sdk-v5 v0.7.42 h1:Up1704BJjI5orycXKjpVpvuOInt9GC5pqY4knyE9Uds= github.com/tencentyun/cos-go-sdk-v5 v0.7.42/go.mod h1:LUFnaqRmGk6pEHOaRmdn2dCZR2j0cSsM5xowWFPTPao= +github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= +github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= @@ -418,6 +471,9 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk= github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -461,6 +517,7 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= @@ -468,6 +525,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU= +go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -484,8 +543,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -497,10 +556,11 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= +golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= +golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= +golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -525,6 +585,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -564,8 +625,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -588,8 +649,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -640,8 +701,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -663,6 +724,7 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -721,8 +783,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= 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= @@ -815,12 +877,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -835,22 +897,32 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04= +gorm.io/datatypes v1.2.1 h1:r+g0bk4LPCW2v4+Ls7aeNgGme7JYdNDQ2VtvlNUfBh0= +gorm.io/datatypes v1.2.1/go.mod h1:hYK6OTb/1x+m96PgoZZq10UXJ6RvEBb9kRDQ2yyhzGs= gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8= gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= +gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8= +gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU= +gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI= gorm.io/driver/sqlserver v1.5.1 h1:wpyW/pR26U94uaujltiFGXY7fd2Jw5hC9PB1ZF/Y5s4= gorm.io/driver/sqlserver v1.5.1/go.mod h1:AYHzzte2msKTmYBYsSIq8ZUsznLJwBdkB2wpI+kt0nM= +gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY= +gorm.io/gen v0.3.26/go.mod h1:a5lq5y3w4g5LMxBcw0wnO6tYUCdNutWODq5LrIt75LE= +gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8= -gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/plugin/dbresolver v1.4.1 h1:Ug4LcoPhrvqq71UhxtF346f+skTYoCa/nEsdjvHwEzk= -gorm.io/plugin/dbresolver v1.4.1/go.mod h1:CTbCtMWhsjXSiJqiW2R8POvJ2cq18RVOl4WGyT5nhNc= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw= +gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y= +gorm.io/plugin/dbresolver v1.5.0 h1:XVHLxh775eP0CqVh3vcfJtYqja3uFl5Wr3cKlY8jgDY= +gorm.io/plugin/dbresolver v1.5.0/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0= 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= diff --git a/server/initialize/ensure_tables.go b/server/initialize/ensure_tables.go index 2a57541b71..389c35ed20 100644 --- a/server/initialize/ensure_tables.go +++ b/server/initialize/ensure_tables.go @@ -47,7 +47,7 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error sysModel.SysBaseMenuParameter{}, sysModel.SysBaseMenuBtn{}, sysModel.SysAuthorityBtn{}, - sysModel.SysAutoCode{}, + sysModel.SysAutoCodePackage{}, sysModel.SysExportTemplate{}, sysModel.Condition{}, sysModel.JoinTemplate{}, @@ -85,7 +85,7 @@ func (e *ensureTables) TableCreated(ctx context.Context) bool { sysModel.SysBaseMenuParameter{}, sysModel.SysBaseMenuBtn{}, sysModel.SysAuthorityBtn{}, - sysModel.SysAutoCode{}, + sysModel.SysAutoCodePackage{}, sysModel.SysExportTemplate{}, sysModel.Condition{}, sysModel.JoinTemplate{}, diff --git a/server/initialize/gorm.go b/server/initialize/gorm.go index 10f5c8e833..fd5f6445c6 100644 --- a/server/initialize/gorm.go +++ b/server/initialize/gorm.go @@ -14,16 +14,22 @@ import ( func Gorm() *gorm.DB { switch global.GVA_CONFIG.System.DbType { case "mysql": + global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mysql.Dbname return GormMysql() case "pgsql": + global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Pgsql.Dbname return GormPgSql() case "oracle": + global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Oracle.Dbname return GormOracle() case "mssql": + global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mssql.Dbname return GormMssql() case "sqlite": + global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Sqlite.Dbname return GormSqlite() default: + global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mysql.Dbname return GormMysql() } } @@ -33,6 +39,7 @@ func RegisterTables() { err := db.AutoMigrate( system.SysApi{}, + system.SysIgnoreApi{}, system.SysUser{}, system.SysBaseMenu{}, system.JwtBlacklist{}, @@ -44,7 +51,7 @@ func RegisterTables() { system.SysBaseMenuParameter{}, system.SysBaseMenuBtn{}, system.SysAuthorityBtn{}, - system.SysAutoCode{}, + system.SysAutoCodePackage{}, system.SysExportTemplate{}, system.Condition{}, system.JoinTemplate{}, @@ -58,5 +65,12 @@ func RegisterTables() { global.GVA_LOG.Error("register table failed", zap.Error(err)) os.Exit(0) } + + err = bizModel() + + if err != nil { + global.GVA_LOG.Error("register biz_table failed", zap.Error(err)) + os.Exit(0) + } global.GVA_LOG.Info("register table success") } diff --git a/server/initialize/gorm_biz.go b/server/initialize/gorm_biz.go new file mode 100644 index 0000000000..9316ccc889 --- /dev/null +++ b/server/initialize/gorm_biz.go @@ -0,0 +1,14 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" +) + +func bizModel() error { + db := global.GVA_DB + err := db.AutoMigrate() + if err != nil { + return err + } + return nil +} diff --git a/server/initialize/internal/gorm.go b/server/initialize/internal/gorm.go index 22a9ce3925..dcf388bea2 100644 --- a/server/initialize/internal/gorm.go +++ b/server/initialize/internal/gorm.go @@ -1,20 +1,16 @@ package internal import ( + "github.com/flipped-aurora/gin-vue-admin/server/config" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "gorm.io/gorm" + "gorm.io/gorm/logger" "gorm.io/gorm/schema" "log" "os" "time" - - "github.com/flipped-aurora/gin-vue-admin/server/global" - "gorm.io/gorm" - "gorm.io/gorm/logger" ) -type DBBASE interface { - GetLogMode() string -} - var Gorm = new(_gorm) type _gorm struct{} @@ -22,41 +18,31 @@ type _gorm struct{} // Config gorm 自定义配置 // Author [SliverHorn](https://github.com/SliverHorn) func (g *_gorm) Config(prefix string, singular bool) *gorm.Config { - config := &gorm.Config{ - NamingStrategy: schema.NamingStrategy{ - TablePrefix: prefix, - SingularTable: singular, - }, - DisableForeignKeyConstraintWhenMigrating: true, - } - _default := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{ - SlowThreshold: 200 * time.Millisecond, - LogLevel: logger.Warn, - Colorful: true, - }) - var logMode DBBASE + var general config.GeneralDB switch global.GVA_CONFIG.System.DbType { case "mysql": - logMode = &global.GVA_CONFIG.Mysql + general = global.GVA_CONFIG.Mysql.GeneralDB case "pgsql": - logMode = &global.GVA_CONFIG.Pgsql + general = global.GVA_CONFIG.Pgsql.GeneralDB case "oracle": - logMode = &global.GVA_CONFIG.Oracle + general = global.GVA_CONFIG.Oracle.GeneralDB + case "sqlite": + general = global.GVA_CONFIG.Sqlite.GeneralDB + case "mssql": + general = global.GVA_CONFIG.Mssql.GeneralDB default: - logMode = &global.GVA_CONFIG.Mysql + general = global.GVA_CONFIG.Mysql.GeneralDB } - - switch logMode.GetLogMode() { - case "silent", "Silent": - config.Logger = _default.LogMode(logger.Silent) - case "error", "Error": - config.Logger = _default.LogMode(logger.Error) - case "warn", "Warn": - config.Logger = _default.LogMode(logger.Warn) - case "info", "Info": - config.Logger = _default.LogMode(logger.Info) - default: - config.Logger = _default.LogMode(logger.Info) + return &gorm.Config{ + Logger: logger.New(NewWriter(general, log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{ + SlowThreshold: 200 * time.Millisecond, + LogLevel: general.LogLevel(), + Colorful: true, + }), + NamingStrategy: schema.NamingStrategy{ + TablePrefix: prefix, + SingularTable: singular, + }, + DisableForeignKeyConstraintWhenMigrating: true, } - return config } diff --git a/server/initialize/internal/gorm_logger_writer.go b/server/initialize/internal/gorm_logger_writer.go new file mode 100644 index 0000000000..955503d873 --- /dev/null +++ b/server/initialize/internal/gorm_logger_writer.go @@ -0,0 +1,37 @@ +package internal + +import ( + "fmt" + "github.com/flipped-aurora/gin-vue-admin/server/config" + "go.uber.org/zap" + "gorm.io/gorm/logger" +) + +type Writer struct { + config config.GeneralDB + writer logger.Writer +} + +func NewWriter(config config.GeneralDB, writer logger.Writer) *Writer { + return &Writer{config: config, writer: writer} +} + +// Printf 格式化打印日志 +func (c *Writer) Printf(message string, data ...any) { + if c.config.LogZap { + switch c.config.LogLevel() { + case logger.Silent: + zap.L().Debug(fmt.Sprintf(message, data...)) + case logger.Error: + zap.L().Error(fmt.Sprintf(message, data...)) + case logger.Warn: + zap.L().Warn(fmt.Sprintf(message, data...)) + case logger.Info: + zap.L().Info(fmt.Sprintf(message, data...)) + default: + zap.L().Info(fmt.Sprintf(message, data...)) + } + return + } + c.writer.Printf(message, data...) +} diff --git a/server/initialize/internal/logger.go b/server/initialize/internal/logger.go deleted file mode 100644 index f8d2f34ef1..0000000000 --- a/server/initialize/internal/logger.go +++ /dev/null @@ -1,35 +0,0 @@ -package internal - -import ( - "fmt" - - "github.com/flipped-aurora/gin-vue-admin/server/global" - "gorm.io/gorm/logger" -) - -type writer struct { - logger.Writer -} - -// NewWriter writer 构造函数 -// Author [SliverHorn](https://github.com/SliverHorn) -func NewWriter(w logger.Writer) *writer { - return &writer{Writer: w} -} - -// Printf 格式化打印日志 -// Author [SliverHorn](https://github.com/SliverHorn) -func (w *writer) Printf(message string, data ...interface{}) { - var logZap bool - switch global.GVA_CONFIG.System.DbType { - case "mysql": - logZap = global.GVA_CONFIG.Mysql.LogZap - case "pgsql": - logZap = global.GVA_CONFIG.Pgsql.LogZap - } - if logZap { - global.GVA_LOG.Info(fmt.Sprintf(message+"\n", data...)) - } else { - w.Writer.Printf(message, data...) - } -} diff --git a/server/initialize/other.go b/server/initialize/other.go index 5d23aeb7fe..f272a812a9 100644 --- a/server/initialize/other.go +++ b/server/initialize/other.go @@ -1,7 +1,10 @@ package initialize import ( + "bufio" "github.com/songzhibin97/gkit/cache/local_cache" + "os" + "strings" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/utils" @@ -20,4 +23,10 @@ func OtherInit() { global.BlackCache = local_cache.NewCache( local_cache.SetDefaultExpire(dr), ) + file, err := os.Open("go.mod") + if err == nil && global.GVA_CONFIG.AutoCode.Module == "" { + scanner := bufio.NewScanner(file) + scanner.Scan() + global.GVA_CONFIG.AutoCode.Module = strings.TrimPrefix(scanner.Text(), "module ") + } } diff --git a/server/initialize/plugin.go b/server/initialize/plugin.go index 7155ffb075..16913b18f8 100644 --- a/server/initialize/plugin.go +++ b/server/initialize/plugin.go @@ -1,36 +1,15 @@ package initialize import ( - "fmt" - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/middleware" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/email" - "github.com/flipped-aurora/gin-vue-admin/server/utils/plugin" "github.com/gin-gonic/gin" ) -func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) { - for i := range Plugin { - PluginGroup := group.Group(Plugin[i].RouterPath()) - Plugin[i].Register(PluginGroup) +func InstallPlugin(PrivateGroup *gin.RouterGroup, PublicRouter *gin.RouterGroup, engine *gin.Engine) { + if global.GVA_DB == nil { + global.GVA_LOG.Info("项目暂未初始化,无法安装插件,初始化后重启项目即可完成插件安装") + return } -} - -func InstallPlugin(Router *gin.Engine) { - PublicGroup := Router.Group("") - fmt.Println("无鉴权插件安装==》", PublicGroup) - PrivateGroup := Router.Group("") - fmt.Println("鉴权插件安装==》", PrivateGroup) - PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) - // 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同 - PluginInit(PrivateGroup, email.CreateEmailPlug( - global.GVA_CONFIG.Email.To, - global.GVA_CONFIG.Email.From, - global.GVA_CONFIG.Email.Host, - global.GVA_CONFIG.Email.Secret, - global.GVA_CONFIG.Email.Nickname, - global.GVA_CONFIG.Email.Port, - global.GVA_CONFIG.Email.IsSSL, - )) + bizPluginV1(PrivateGroup, PublicRouter) + bizPluginV2(engine) } diff --git a/server/initialize/plugin_biz_v1.go b/server/initialize/plugin_biz_v1.go new file mode 100644 index 0000000000..7366c65d9f --- /dev/null +++ b/server/initialize/plugin_biz_v1.go @@ -0,0 +1,34 @@ +package initialize + +import ( + "fmt" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/email" + "github.com/flipped-aurora/gin-vue-admin/server/utils/plugin" + "github.com/gin-gonic/gin" +) + +func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) { + for i := range Plugin { + fmt.Println(Plugin[i].RouterPath(), "注册开始!") + PluginGroup := group.Group(Plugin[i].RouterPath()) + Plugin[i].Register(PluginGroup) + fmt.Println(Plugin[i].RouterPath(), "注册成功!") + } +} + +func bizPluginV1(group ...*gin.RouterGroup) { + private := group[0] + public := group[1] + // 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同 + PluginInit(private, email.CreateEmailPlug( + global.GVA_CONFIG.Email.To, + global.GVA_CONFIG.Email.From, + global.GVA_CONFIG.Email.Host, + global.GVA_CONFIG.Email.Secret, + global.GVA_CONFIG.Email.Nickname, + global.GVA_CONFIG.Email.Port, + global.GVA_CONFIG.Email.IsSSL, + )) + holder(public, private) +} diff --git a/server/initialize/plugin_biz_v2.go b/server/initialize/plugin_biz_v2.go new file mode 100644 index 0000000000..9d13bbe02f --- /dev/null +++ b/server/initialize/plugin_biz_v2.go @@ -0,0 +1,16 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement" + "github.com/flipped-aurora/gin-vue-admin/server/utils/plugin/v2" + "github.com/gin-gonic/gin" +) + +func PluginInitV2(group *gin.Engine, plugins ...plugin.Plugin) { + for i := 0; i < len(plugins); i++ { + plugins[i].Register(group) + } +} +func bizPluginV2(engine *gin.Engine) { + PluginInitV2(engine, announcement.Plugin) +} diff --git a/server/initialize/redis.go b/server/initialize/redis.go index 41dfd76e01..2d9c8f4eb8 100644 --- a/server/initialize/redis.go +++ b/server/initialize/redis.go @@ -3,14 +3,14 @@ package initialize import ( "context" + "github.com/flipped-aurora/gin-vue-admin/server/config" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/redis/go-redis/v9" "go.uber.org/zap" ) -func Redis() { - redisCfg := global.GVA_CONFIG.Redis +func initRedisClient(redisCfg config.Redis) (redis.UniversalClient, error) { var client redis.UniversalClient // 使用集群模式 if redisCfg.UseCluster { @@ -28,10 +28,32 @@ func Redis() { } pong, err := client.Ping(context.Background()).Result() if err != nil { - global.GVA_LOG.Error("redis connect ping failed, err:", zap.Error(err)) + global.GVA_LOG.Error("redis connect ping failed, err:", zap.String("name", redisCfg.Name), zap.Error(err)) + return nil, err + } + + global.GVA_LOG.Info("redis connect ping response:", zap.String("name", redisCfg.Name), zap.String("pong", pong)) + return client, nil +} + +func Redis() { + redisClient, err := initRedisClient(global.GVA_CONFIG.Redis) + if err != nil { panic(err) - } else { - global.GVA_LOG.Info("redis connect ping response:", zap.String("pong", pong)) - global.GVA_REDIS = client } + global.GVA_REDIS = redisClient +} + +func RedisList() { + redisMap := make(map[string]redis.UniversalClient) + + for _, redisCfg := range global.GVA_CONFIG.RedisList { + client, err := initRedisClient(redisCfg) + if err != nil { + panic(err) + } + redisMap[redisCfg.Name] = client + } + + global.GVA_REDISList = redisMap } diff --git a/server/initialize/router.go b/server/initialize/router.go index 3b90889b48..f70a92a4ff 100644 --- a/server/initialize/router.go +++ b/server/initialize/router.go @@ -1,6 +1,9 @@ package initialize import ( + "net/http" + "os" + "github.com/flipped-aurora/gin-vue-admin/server/docs" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/middleware" @@ -8,8 +11,6 @@ import ( "github.com/gin-gonic/gin" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" - "net/http" - "os" ) type justFilesFilesystem struct { @@ -39,28 +40,31 @@ func Routers() *gin.Engine { Router.Use(gin.Logger()) } - InstallPlugin(Router) // 安装插件 systemRouter := router.RouterGroupApp.System exampleRouter := router.RouterGroupApp.Example // 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的 // VUE_APP_BASE_API = / // VUE_APP_BASE_PATH = http://localhost // 然后执行打包命令 npm run build。在打开下面3行注释 - //Router.Static("/favicon.ico", "./dist/favicon.ico") - //Router.Static("/assets", "./dist/assets") // dist里面的静态资源 - //Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面 + // Router.Static("/favicon.ico", "./dist/favicon.ico") + // Router.Static("/assets", "./dist/assets") // dist里面的静态资源 + // Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面 Router.StaticFS(global.GVA_CONFIG.Local.StorePath, justFilesFilesystem{http.Dir(global.GVA_CONFIG.Local.StorePath)}) // Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件") // 跨域,如需跨域可以打开下面的注释 // Router.Use(middleware.Cors()) // 直接放行全部跨域请求 // Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求 - //global.GVA_LOG.Info("use middleware cors") + // global.GVA_LOG.Info("use middleware cors") docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) global.GVA_LOG.Info("register swagger handler") // 方便统一添加路由组前缀 多服务器上线使用 PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) + PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) + + PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + { // 健康监测 PublicGroup.GET("/health", func(c *gin.Context) { @@ -71,8 +75,7 @@ func Routers() *gin.Engine { systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权 systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关 } - PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) - PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + { systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由 systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由 @@ -80,19 +83,27 @@ func Routers() *gin.Engine { systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由 systemRouter.InitSystemRouter(PrivateGroup) // system相关路由 systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由 - systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码 + systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码 systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由 systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理 systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史 systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 - systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 字典详情管理 + systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理 systemRouter.InitSysExportTemplateRouter(PrivateGroup) // 导出模板 exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由 exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 } + //插件路由安装 + InstallPlugin(PrivateGroup, PublicGroup, Router) + + // 注册业务路由 + initBizRouter(PrivateGroup, PublicGroup) + + global.GVA_ROUTERS = Router.Routes() + global.GVA_LOG.Info("router register success") return Router } diff --git a/server/initialize/router_biz.go b/server/initialize/router_biz.go new file mode 100644 index 0000000000..279127d3a0 --- /dev/null +++ b/server/initialize/router_biz.go @@ -0,0 +1,19 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/router" + "github.com/gin-gonic/gin" +) + +// 占位方法,保证文件可以正确加载,避免go空变量检测报错,请勿删除。 +func holder(routers ...*gin.RouterGroup) { + _ = routers + _ = router.RouterGroupApp +} + +func initBizRouter(routers ...*gin.RouterGroup) { + privateGroup := routers[0] + publicGroup := routers[1] + + holder(publicGroup, privateGroup) +} diff --git a/server/main.go b/server/main.go index a6034ed6bb..38ad106211 100644 --- a/server/main.go +++ b/server/main.go @@ -15,7 +15,7 @@ import ( //go:generate go mod download // @title Gin-Vue-Admin Swagger API接口文档 -// @version v2.6.2 +// @version v2.7.4 // @description 使用gin+vue进行极速开发的全栈开发基础平台 // @securityDefinitions.apikey ApiKeyAuth // @in header diff --git a/server/middleware/jwt.go b/server/middleware/jwt.go index aa7ca37bb3..38b56dcf33 100644 --- a/server/middleware/jwt.go +++ b/server/middleware/jwt.go @@ -3,10 +3,8 @@ package middleware import ( "errors" "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/utils" "github.com/golang-jwt/jwt/v4" - "go.uber.org/zap" "strconv" "time" @@ -67,13 +65,7 @@ func JWTAuth() gin.HandlerFunc { c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt.Unix(), 10)) utils.SetToken(c, newToken, int(dr.Seconds())) if global.GVA_CONFIG.System.UseMultipoint { - RedisJwtToken, err := jwtService.GetRedisJWT(newClaims.Username) - if err != nil { - global.GVA_LOG.Error("get redis jwt failed", zap.Error(err)) - } else { // 当之前的取成功时才进行拉黑操作 - _ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken}) - } - // 无论如何都要记录当前的活跃状态 + // 记录新的活跃jwt _ = jwtService.SetRedisJWT(newToken, newClaims.Username) } } diff --git a/server/model/common/basetypes.go b/server/model/common/basetypes.go new file mode 100644 index 0000000000..870d975c62 --- /dev/null +++ b/server/model/common/basetypes.go @@ -0,0 +1,36 @@ +package common + +import ( + "database/sql/driver" + "encoding/json" + "errors" +) + +type JSONMap map[string]interface{} + +func (m JSONMap) Value() (driver.Value, error) { + if m == nil { + return nil, nil + } + return json.Marshal(m) +} + +func (m *JSONMap) Scan(value interface{}) error { + if value == nil { + *m = make(map[string]interface{}) + return nil + } + var err error + switch value.(type) { + case []byte: + err = json.Unmarshal(value.([]byte), m) + case string: + err = json.Unmarshal([]byte(value.(string)), m) + default: + err = errors.New("basetypes.JSONMap.Scan: invalid value type") + } + if err != nil { + return err + } + return nil +} diff --git a/server/model/common/request/common.go b/server/model/common/request/common.go index 78374e0631..c729f3db2f 100644 --- a/server/model/common/request/common.go +++ b/server/model/common/request/common.go @@ -1,10 +1,30 @@ package request +import ( + "gorm.io/gorm" +) + // PageInfo Paging common input parameter structure type PageInfo struct { Page int `json:"page" form:"page"` // 页码 PageSize int `json:"pageSize" form:"pageSize"` // 每页大小 - Keyword string `json:"keyword" form:"keyword"` //关键字 + Keyword string `json:"keyword" form:"keyword"` // 关键字 +} + +func (r *PageInfo) Paginate() func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + if r.Page <= 0 { + r.Page = 1 + } + switch { + case r.PageSize > 100: + r.PageSize = 100 + case r.PageSize <= 0: + r.PageSize = 10 + } + offset := (r.Page - 1) * r.PageSize + return db.Offset(offset).Limit(r.PageSize) + } } // GetById Find by id structure diff --git a/server/model/common/response/response.go b/server/model/common/response/response.go index fcd6953855..a429b12e12 100644 --- a/server/model/common/response/response.go +++ b/server/model/common/response/response.go @@ -35,7 +35,7 @@ func OkWithMessage(message string, c *gin.Context) { } func OkWithData(data interface{}, c *gin.Context) { - Result(SUCCESS, data, "查询成功", c) + Result(SUCCESS, data, "成功", c) } func OkWithDetailed(data interface{}, message string, c *gin.Context) { diff --git a/server/model/system/request/sys_auto_code.go b/server/model/system/request/sys_auto_code.go new file mode 100644 index 0000000000..ae04aa7835 --- /dev/null +++ b/server/model/system/request/sys_auto_code.go @@ -0,0 +1,260 @@ +package request + +import ( + "encoding/json" + "fmt" + model "github.com/flipped-aurora/gin-vue-admin/server/model/system" + "github.com/pkg/errors" + "go/token" + "strings" +) + +type AutoCode struct { + Package string `json:"package"` + PackageT string `json:"-"` + TableName string `json:"tableName" example:"表名"` // 表名 + BusinessDB string `json:"businessDB" example:"业务数据库"` // 业务数据库 + StructName string `json:"structName" example:"Struct名称"` // Struct名称 + PackageName string `json:"packageName" example:"文件名称"` // 文件名称 + Description string `json:"description" example:"Struct中文名称"` // Struct中文名称 + Abbreviation string `json:"abbreviation" example:"Struct简称"` // Struct简称 + HumpPackageName string `json:"humpPackageName" example:"go文件名称"` // go文件名称 + GvaModel bool `json:"gvaModel" example:"false"` // 是否使用gva默认Model + AutoMigrate bool `json:"autoMigrate" example:"false"` // 是否自动迁移表结构 + AutoCreateResource bool `json:"autoCreateResource" example:"false"` // 是否自动创建资源标识 + AutoCreateApiToSql bool `json:"autoCreateApiToSql" example:"false"` // 是否自动创建api + AutoCreateMenuToSql bool `json:"autoCreateMenuToSql" example:"false"` // 是否自动创建menu + AutoCreateBtnAuth bool `json:"autoCreateBtnAuth" example:"false"` // 是否自动创建按钮权限 + OnlyTemplate bool `json:"onlyTemplate" example:"false"` // 是否只生成模板 + Fields []*AutoCodeField `json:"fields"` + DictTypes []string `json:"-"` + PrimaryField *AutoCodeField `json:"primaryField"` + DataSourceMap map[string]*DataSource `json:"-"` + HasPic bool `json:"-"` + HasFile bool `json:"-"` + HasTimer bool `json:"-"` + NeedSort bool `json:"-"` + NeedJSON bool `json:"-"` + HasRichText bool `json:"-"` + HasDataSource bool `json:"-"` + HasSearchTimer bool `json:"-"` + HasArray bool `json:"-"` + HasExcel bool `json:"-"` +} + +type DataSource struct { + Table string `json:"table"` + Label string `json:"label"` + Value string `json:"value"` + Association int `json:"association"` // 关联关系 1 一对一 2 一对多 +} + +func (r *AutoCode) Apis() []model.SysApi { + return []model.SysApi{ + { + Path: "/" + r.Abbreviation + "/" + "create" + r.StructName, + Description: "新增" + r.Description, + ApiGroup: r.Description, + Method: "POST", + }, + { + Path: "/" + r.Abbreviation + "/" + "delete" + r.StructName, + Description: "删除" + r.Description, + ApiGroup: r.Description, + Method: "DELETE", + }, + { + Path: "/" + r.Abbreviation + "/" + "delete" + r.StructName + "ByIds", + Description: "批量删除" + r.Description, + ApiGroup: r.Description, + Method: "DELETE", + }, + { + Path: "/" + r.Abbreviation + "/" + "update" + r.StructName, + Description: "更新" + r.Description, + ApiGroup: r.Description, + Method: "PUT", + }, + { + Path: "/" + r.Abbreviation + "/" + "find" + r.StructName, + Description: "根据ID获取" + r.Description, + ApiGroup: r.Description, + Method: "GET", + }, + { + Path: "/" + r.Abbreviation + "/" + "get" + r.StructName + "List", + Description: "获取" + r.Description + "列表", + ApiGroup: r.Description, + Method: "GET", + }, + } +} + +func (r *AutoCode) Menu(template string) model.SysBaseMenu { + component := fmt.Sprintf("view/%s/%s/%s.vue", r.Package, r.PackageName, r.PackageName) + if template != "package" { + component = fmt.Sprintf("plugin/%s/view/%s.vue", r.Package, r.PackageName) + } + return model.SysBaseMenu{ + ParentId: 0, + Path: r.Abbreviation, + Name: r.Abbreviation, + Component: component, + Meta: model.Meta{ + Title: r.Description, + }, + } +} + +// Pretreatment 预处理 +// Author [SliverHorn](https://github.com/SliverHorn) +func (r *AutoCode) Pretreatment() error { + if token.IsKeyword(r.Abbreviation) { + r.Abbreviation = r.Abbreviation + "_" + } // go 关键字处理 + if strings.HasSuffix(r.HumpPackageName, "test") { + r.HumpPackageName = r.HumpPackageName + "_" + } // test + length := len(r.Fields) + dict := make(map[string]string, length) + r.DataSourceMap = make(map[string]*DataSource, length) + for i := 0; i < length; i++ { + if r.Fields[i].Excel { + r.HasExcel = true + } + if r.Fields[i].DictType != "" { + dict[r.Fields[i].DictType] = "" + } + if r.Fields[i].Sort { + r.NeedSort = true + } + switch r.Fields[i].FieldType { + case "file": + r.HasFile = true + r.NeedJSON = true + case "json": + r.NeedJSON = true + case "array": + r.NeedJSON = true + r.HasArray = true + case "video": + r.HasPic = true + case "richtext": + r.HasRichText = true + case "picture": + r.HasPic = true + case "pictures": + r.HasPic = true + r.NeedJSON = true + case "time.Time": + r.HasTimer = true + if r.Fields[i].FieldSearchType != "" { + r.HasSearchTimer = true + } + } + if r.Fields[i].DataSource != nil { + if r.Fields[i].DataSource.Table != "" && r.Fields[i].DataSource.Label != "" && r.Fields[i].DataSource.Value != "" { + r.HasDataSource = true + r.Fields[i].CheckDataSource = true + r.DataSourceMap[r.Fields[i].FieldJson] = r.Fields[i].DataSource + } + } + if !r.GvaModel && r.PrimaryField == nil && r.Fields[i].PrimaryKey { + r.PrimaryField = r.Fields[i] + } // 自定义主键 + } + { + for key := range dict { + r.DictTypes = append(r.DictTypes, key) + } + } // DictTypes => 字典 + { + if r.GvaModel { + r.PrimaryField = &AutoCodeField{ + FieldName: "ID", + FieldType: "uint", + FieldDesc: "ID", + FieldJson: "ID", + DataTypeLong: "20", + Comment: "主键ID", + ColumnName: "id", + } + } + } // GvaModel + if r.Package == "" { + return errors.New("Package为空!") + } // 增加判断:Package不为空 + packages := []rune(r.Package) + if len(packages) > 0 { + if packages[0] >= 97 && packages[0] <= 122 { + packages[0] = packages[0] - 32 + } + r.PackageT = string(packages) + } // PackageT 是 Package 的首字母大写 + return nil +} + +func (r *AutoCode) History() SysAutoHistoryCreate { + bytes, _ := json.Marshal(r) + return SysAutoHistoryCreate{ + Table: r.TableName, + Package: r.Package, + Request: string(bytes), + StructName: r.StructName, + BusinessDB: r.BusinessDB, + Description: r.Description, + } +} + +type AutoCodeField struct { + FieldName string `json:"fieldName"` // Field名 + FieldDesc string `json:"fieldDesc"` // 中文名 + FieldType string `json:"fieldType"` // Field数据类型 + FieldJson string `json:"fieldJson"` // FieldJson + DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度 + Comment string `json:"comment"` // 数据库字段描述 + ColumnName string `json:"columnName"` // 数据库字段 + FieldSearchType string `json:"fieldSearchType"` // 搜索条件 + FieldSearchHide bool `json:"fieldSearchHide"` // 是否隐藏查询条件 + DictType string `json:"dictType"` // 字典 + //Front bool `json:"front"` // 是否前端可见 + Form bool `json:"form"` // 是否前端新建/编辑 + Table bool `json:"table"` // 是否前端表格列 + Desc bool `json:"desc"` // 是否前端详情 + Excel bool `json:"excel"` // 是否导入/导出 + Require bool `json:"require"` // 是否必填 + DefaultValue string `json:"defaultValue"` // 是否必填 + ErrorText string `json:"errorText"` // 校验失败文字 + Clearable bool `json:"clearable"` // 是否可清空 + Sort bool `json:"sort"` // 是否增加排序 + PrimaryKey bool `json:"primaryKey"` // 是否主键 + DataSource *DataSource `json:"dataSource"` // 数据源 + CheckDataSource bool `json:"checkDataSource"` // 是否检查数据源 + FieldIndexType string `json:"fieldIndexType"` // 索引类型 +} + +type AutoFunc struct { + Package string `json:"package"` + FuncName string `json:"funcName"` // 方法名称 + Router string `json:"router"` // 路由名称 + FuncDesc string `json:"funcDesc"` // 方法介绍 + BusinessDB string `json:"businessDB"` // 业务库 + StructName string `json:"structName"` // Struct名称 + PackageName string `json:"packageName"` // 文件名称 + Description string `json:"description"` // Struct中文名称 + Abbreviation string `json:"abbreviation"` // Struct简称 + HumpPackageName string `json:"humpPackageName"` // go文件名称 + Method string `json:"method"` // 方法 + IsPlugin bool `json:"isPlugin"` // 是否插件 +} + +type InitMenu struct { + PlugName string `json:"plugName"` + ParentMenu string `json:"parentMenu"` + Menus []uint `json:"menus"` +} + +type InitApi struct { + PlugName string `json:"plugName"` + APIs []uint `json:"apis"` +} diff --git a/server/model/system/request/sys_auto_code_package.go b/server/model/system/request/sys_auto_code_package.go new file mode 100644 index 0000000000..8494cb1786 --- /dev/null +++ b/server/model/system/request/sys_auto_code_package.go @@ -0,0 +1,27 @@ +package request + +import ( + model "github.com/flipped-aurora/gin-vue-admin/server/model/system" +) + +type SysAutoCodePackageCreate struct { + Desc string `json:"desc" example:"描述"` + Label string `json:"label" example:"展示名"` + Template string `json:"template" example:"模版"` + PackageName string `json:"packageName" example:"包名"` +} + +func (r *SysAutoCodePackageCreate) AutoCode() AutoCode { + return AutoCode{ + Package: r.PackageName, + } +} + +func (r *SysAutoCodePackageCreate) Create() model.SysAutoCodePackage { + return model.SysAutoCodePackage{ + Desc: r.Desc, + Label: r.Label, + Template: r.Template, + PackageName: r.PackageName, + } +} diff --git a/server/model/system/request/sys_auto_history.go b/server/model/system/request/sys_auto_history.go index 48c95e607f..fb50a7944f 100644 --- a/server/model/system/request/sys_auto_history.go +++ b/server/model/system/request/sys_auto_history.go @@ -1,13 +1,56 @@ package request -import "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" +import ( + common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + model "github.com/flipped-aurora/gin-vue-admin/server/model/system" +) -type SysAutoHistory struct { - request.PageInfo +type SysAutoHistoryCreate struct { + Table string // 表名 + Package string // 模块名/插件名 + Request string // 前端传入的结构化信息 + StructName string // 结构体名称 + BusinessDB string // 业务库 + Description string // Struct中文名称 + Injections map[string]string // 注入路径 + Templates map[string]string // 模板信息 + ApiIDs []uint // api表注册内容 + MenuID uint // 菜单ID + ExportTemplateID uint // 导出模板ID } -// GetById Find by id structure -type RollBack struct { - ID int `json:"id" form:"id"` // 主键ID +func (r *SysAutoHistoryCreate) Create() model.SysAutoCodeHistory { + entity := model.SysAutoCodeHistory{ + Package: r.Package, + Request: r.Request, + Table: r.Table, + StructName: r.StructName, + BusinessDB: r.BusinessDB, + Description: r.Description, + Injections: r.Injections, + Templates: r.Templates, + ApiIDs: r.ApiIDs, + MenuID: r.MenuID, + ExportTemplateID: r.ExportTemplateID, + } + if entity.Table == "" { + entity.Table = r.StructName + } + return entity +} + +type SysAutoHistoryRollBack struct { + common.GetById + DeleteApi bool `json:"deleteApi" form:"deleteApi"` // 是否删除接口 + DeleteMenu bool `json:"deleteMenu" form:"deleteMenu"` // 是否删除菜单 DeleteTable bool `json:"deleteTable" form:"deleteTable"` // 是否删除表 } + +func (r *SysAutoHistoryRollBack) ApiIds(entity model.SysAutoCodeHistory) common.IdsReq { + length := len(entity.ApiIDs) + ids := make([]int, 0) + for i := 0; i < length; i++ { + ids = append(ids, int(entity.ApiIDs[i])) + } + return common.IdsReq{Ids: ids} +} diff --git a/server/model/system/request/sys_casbin.go b/server/model/system/request/sys_casbin.go index 0c07ae604b..ef8c823cbe 100644 --- a/server/model/system/request/sys_casbin.go +++ b/server/model/system/request/sys_casbin.go @@ -17,10 +17,11 @@ func DefaultCasbin() []CasbinInfo { {Path: "/menu/getMenu", Method: "POST"}, {Path: "/jwt/jsonInBlacklist", Method: "POST"}, {Path: "/base/login", Method: "POST"}, - {Path: "/user/admin_register", Method: "POST"}, {Path: "/user/changePassword", Method: "POST"}, {Path: "/user/setUserAuthority", Method: "POST"}, - {Path: "/user/setUserInfo", Method: "PUT"}, {Path: "/user/getUserInfo", Method: "GET"}, + {Path: "/user/setSelfInfo", Method: "PUT"}, + {Path: "/fileUploadAndDownload/upload", Method: "POST"}, + {Path: "/sysDictionary/findSysDictionary", Method: "GET"}, } } diff --git a/server/model/system/request/sys_init.go b/server/model/system/request/sys_init.go index 91b690ce2f..6882895d24 100644 --- a/server/model/system/request/sys_init.go +++ b/server/model/system/request/sys_init.go @@ -7,13 +7,14 @@ import ( ) type InitDB struct { - DBType string `json:"dbType"` // 数据库类型 - Host string `json:"host"` // 服务器地址 - Port string `json:"port"` // 数据库连接端口 - UserName string `json:"userName"` // 数据库用户名 - Password string `json:"password"` // 数据库密码 - DBName string `json:"dbName" binding:"required"` // 数据库名 - DBPath string `json:"dbPath"` // sqlite数据库文件路径 + AdminPassword string `json:"adminPassword" binding:"required"` + DBType string `json:"dbType"` // 数据库类型 + Host string `json:"host"` // 服务器地址 + Port string `json:"port"` // 数据库连接端口 + UserName string `json:"userName"` // 数据库用户名 + Password string `json:"password"` // 数据库密码 + DBName string `json:"dbName" binding:"required"` // 数据库名 + DBPath string `json:"dbPath"` // sqlite数据库文件路径 } // MysqlEmptyDsn msyql 空数据库 建库链接 diff --git a/server/model/system/response/sys_api.go b/server/model/system/response/sys_api.go index 09dc72f8bf..20e382b9aa 100644 --- a/server/model/system/response/sys_api.go +++ b/server/model/system/response/sys_api.go @@ -1,6 +1,8 @@ package response -import "github.com/flipped-aurora/gin-vue-admin/server/model/system" +import ( + "github.com/flipped-aurora/gin-vue-admin/server/model/system" +) type SysAPIResponse struct { Api system.SysApi `json:"api"` @@ -9,3 +11,8 @@ type SysAPIResponse struct { type SysAPIListResponse struct { Apis []system.SysApi `json:"apis"` } + +type SysSyncApis struct { + NewApis []system.SysApi `json:"newApis"` + DeleteApis []system.SysApi `json:"deleteApis"` +} diff --git a/server/model/system/response/sys_auto_code_history.go b/server/model/system/response/sys_auto_code_history.go deleted file mode 100644 index 071844c34f..0000000000 --- a/server/model/system/response/sys_auto_code_history.go +++ /dev/null @@ -1,14 +0,0 @@ -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"` - BusinessDB string `json:"businessDB" gorm:"column:business_db"` - 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/sys_api.go b/server/model/system/sys_api.go index 2b6ab36ce8..853ddb0873 100644 --- a/server/model/system/sys_api.go +++ b/server/model/system/sys_api.go @@ -15,3 +15,14 @@ type SysApi struct { func (SysApi) TableName() string { return "sys_apis" } + +type SysIgnoreApi struct { + global.GVA_MODEL + Path string `json:"path" gorm:"comment:api路径"` // api路径 + Method string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE + Flag bool `json:"flag" gorm:"-"` // 是否忽略 +} + +func (SysIgnoreApi) TableName() string { + return "sys_ignore_apis" +} diff --git a/server/model/system/sys_auto_code.go b/server/model/system/sys_auto_code.go deleted file mode 100644 index 003781ca31..0000000000 --- a/server/model/system/sys_auto_code.go +++ /dev/null @@ -1,124 +0,0 @@ -package system - -import ( - "errors" - "go/token" - "strings" - - "github.com/flipped-aurora/gin-vue-admin/server/global" -) - -// AutoCodeStruct 初始版本自动化代码工具 -type AutoCodeStruct struct { - StructName string `json:"structName"` // Struct名称 - TableName string `json:"tableName"` // 表名 - PackageName string `json:"packageName"` // 文件名称 - HumpPackageName string `json:"humpPackageName"` // go文件名称 - Abbreviation string `json:"abbreviation"` // Struct简称 - Description string `json:"description"` // Struct中文名称 - AutoCreateApiToSql bool `json:"autoCreateApiToSql"` // 是否自动创建api - AutoCreateMenuToSql bool `json:"autoCreateMenuToSql"` // 是否自动创建menu - AutoCreateResource bool `json:"autoCreateResource"` // 是否自动创建资源标识 - AutoMoveFile bool `json:"autoMoveFile"` // 是否自动移动文件 - BusinessDB string `json:"businessDB"` // 业务数据库 - GvaModel bool `json:"gvaModel"` // 是否使用gva默认Model - Fields []*Field `json:"fields"` - PrimaryField *Field `json:"primaryField"` - HasTimer bool `json:"-"` - HasSearchTimer bool `json:"-"` - DictTypes []string `json:"-"` - Package string `json:"package"` - PackageT string `json:"-"` - NeedSort bool `json:"-"` - HasPic bool `json:"-"` - HasRichText bool `json:"-"` - HasFile bool `json:"-"` - NeedJSON bool `json:"-"` -} - -func (a *AutoCodeStruct) Pretreatment() { - a.KeyWord() - a.SuffixTest() -} - -// KeyWord 是go关键字的处理加上 _ ,防止编译报错 -// Author [SliverHorn](https://github.com/SliverHorn) -func (a *AutoCodeStruct) KeyWord() { - if token.IsKeyword(a.Abbreviation) { - a.Abbreviation = a.Abbreviation + "_" - } -} - -// SuffixTest 处理_test 后缀 -// Author [SliverHorn](https://github.com/SliverHorn) -func (a *AutoCodeStruct) SuffixTest() { - if strings.HasSuffix(a.HumpPackageName, "test") { - a.HumpPackageName = a.HumpPackageName + "_" - } -} - -type Field struct { - FieldName string `json:"fieldName"` // Field名 - FieldDesc string `json:"fieldDesc"` // 中文名 - FieldType string `json:"fieldType"` // Field数据类型 - FieldJson string `json:"fieldJson"` // FieldJson - DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度 - Comment string `json:"comment"` // 数据库字段描述 - ColumnName string `json:"columnName"` // 数据库字段 - FieldSearchType string `json:"fieldSearchType"` // 搜索条件 - DictType string `json:"dictType"` // 字典 - Require bool `json:"require"` // 是否必填 - DefaultValue string `json:"defaultValue"` // 是否必填 - ErrorText string `json:"errorText"` // 校验失败文字 - Clearable bool `json:"clearable"` // 是否可清空 - Sort bool `json:"sort"` // 是否增加排序 - PrimaryKey bool `json:"primaryKey"` // 是否主键 -} - -var ErrAutoMove error = errors.New("创建代码成功并移动文件成功") - -type SysAutoCode struct { - global.GVA_MODEL - PackageName string `json:"packageName" gorm:"comment:包名"` - Label string `json:"label" gorm:"comment:展示名"` - Desc string `json:"desc" gorm:"comment:描述"` -} - -type AutoPlugReq struct { - PlugName string `json:"plugName"` // 必然大写开头 - Snake string `json:"snake"` // 后端自动转为 snake - RouterGroup string `json:"routerGroup"` - HasGlobal bool `json:"hasGlobal"` - HasRequest bool `json:"hasRequest"` - HasResponse bool `json:"hasResponse"` - NeedModel bool `json:"needModel"` - Global []AutoPlugInfo `json:"global,omitempty"` - Request []AutoPlugInfo `json:"request,omitempty"` - Response []AutoPlugInfo `json:"response,omitempty"` -} - -func (a *AutoPlugReq) CheckList() { - a.Global = bind(a.Global) - a.Request = bind(a.Request) - a.Response = bind(a.Response) - -} -func bind(req []AutoPlugInfo) []AutoPlugInfo { - var r []AutoPlugInfo - for _, info := range req { - if info.Effective() { - r = append(r, info) - } - } - return r -} - -type AutoPlugInfo struct { - Key string `json:"key"` - Type string `json:"type"` - Desc string `json:"desc"` -} - -func (a AutoPlugInfo) Effective() bool { - return a.Key != "" && a.Type != "" && a.Desc != "" -} diff --git a/server/model/system/sys_auto_code_history.go b/server/model/system/sys_auto_code_history.go new file mode 100644 index 0000000000..c36787ddb3 --- /dev/null +++ b/server/model/system/sys_auto_code_history.go @@ -0,0 +1,67 @@ +package system + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + "gorm.io/gorm" + "os" + "path" + "path/filepath" + "strings" +) + +// SysAutoCodeHistory 自动迁移代码记录,用于回滚,重放使用 +type SysAutoCodeHistory struct { + global.GVA_MODEL + Table string `json:"tableName" gorm:"column:table_name;comment:表名"` + Package string `json:"package" gorm:"column:package;comment:模块名/插件名"` + Request string `json:"request" gorm:"type:text;column:request;comment:前端传入的结构化信息"` + StructName string `json:"structName" gorm:"column:struct_name;comment:结构体名称"` + BusinessDB string `json:"businessDb" gorm:"column:business_db;comment:业务库"` + Description string `json:"description" gorm:"column:description;comment:Struct中文名称"` + Templates map[string]string `json:"template" gorm:"serializer:json;type:text;column:templates;comment:模板信息"` + Injections map[string]string `json:"injections" gorm:"serializer:json;type:text;column:Injections;comment:注入路径"` + Flag int `json:"flag" gorm:"column:flag;comment:[0:创建,1:回滚]"` + ApiIDs []uint `json:"apiIDs" gorm:"serializer:json;column:api_ids;comment:api表注册内容"` + MenuID uint `json:"menuId" gorm:"column:menu_id;comment:菜单ID"` + ExportTemplateID uint `json:"exportTemplateID" gorm:"column:export_template_id;comment:导出模板ID"` + AutoCodePackage SysAutoCodePackage `json:"autoCodePackage" gorm:"foreignKey:ID;references:PackageID"` + PackageID uint `json:"packageID" gorm:"column:package_id;comment:包ID"` +} + +func (s *SysAutoCodeHistory) BeforeCreate(db *gorm.DB) error { + templates := make(map[string]string, len(s.Templates)) + for key, value := range s.Templates { + server := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server) + { + hasServer := strings.Index(key, server) + if hasServer != -1 { + key = strings.TrimPrefix(key, server) + keys := strings.Split(key, string(os.PathSeparator)) + key = path.Join(keys...) + } + } // key + web := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot()) + hasWeb := strings.Index(value, web) + if hasWeb != -1 { + value = strings.TrimPrefix(value, web) + values := strings.Split(value, string(os.PathSeparator)) + value = path.Join(values...) + templates[key] = value + continue + } + hasServer := strings.Index(value, server) + if hasServer != -1 { + value = strings.TrimPrefix(value, server) + values := strings.Split(value, string(os.PathSeparator)) + value = path.Join(values...) + templates[key] = value + continue + } + } + s.Templates = templates + return nil +} + +func (s *SysAutoCodeHistory) TableName() string { + return "sys_auto_code_histories" +} diff --git a/server/model/system/sys_auto_code_package.go b/server/model/system/sys_auto_code_package.go new file mode 100644 index 0000000000..e87e88538f --- /dev/null +++ b/server/model/system/sys_auto_code_package.go @@ -0,0 +1,17 @@ +package system + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" +) + +type SysAutoCodePackage struct { + global.GVA_MODEL + Desc string `json:"desc" gorm:"comment:描述"` + Label string `json:"label" gorm:"comment:展示名"` + Template string `json:"template" gorm:"comment:模版"` + PackageName string `json:"packageName" gorm:"comment:包名"` +} + +func (s *SysAutoCodePackage) TableName() string { + return "sys_auto_code_packages" +} diff --git a/server/model/system/sys_autocode_history.go b/server/model/system/sys_autocode_history.go deleted file mode 100644 index 60607938b8..0000000000 --- a/server/model/system/sys_autocode_history.go +++ /dev/null @@ -1,41 +0,0 @@ -package system - -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 - Package string `json:"package"` - BusinessDB string `json:"businessDB"` - TableName string `json:"tableName"` - MenuID uint `json:"menuID"` - RequestMeta string `gorm:"type:text" json:"requestMeta,omitempty"` // 前端传入的结构化信息 - AutoCodePath string `gorm:"type:text" json:"autoCodePath,omitempty"` // 其他meta信息 path;path - InjectionMeta string `gorm:"type:text" json:"injectionMeta,omitempty"` // 注入的内容 RouterPath@functionName@RouterString; - StructName string `json:"structName"` - 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_export_template.go b/server/model/system/sys_export_template.go index d5919280f8..aef24617d1 100644 --- a/server/model/system/sys_export_template.go +++ b/server/model/system/sys_export_template.go @@ -13,7 +13,7 @@ type SysExportTemplate struct { TableName string `json:"tableName" form:"tableName" gorm:"column:table_name;comment:表名称;"` //表名称 TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识;"` //模板标识 TemplateInfo string `json:"templateInfo" form:"templateInfo" gorm:"column:template_info;type:text;"` //模板信息 - Limit int `json:"limit" form:"limit" gorm:"column:limit;comment:导出限制"` + Limit *int `json:"limit" form:"limit" gorm:"column:limit;comment:导出限制"` Order string `json:"order" form:"order" gorm:"column:order;comment:排序"` Conditions []Condition `json:"conditions" form:"conditions" gorm:"foreignKey:TemplateID;references:TemplateID;comment:条件"` JoinTemplate []JoinTemplate `json:"joinTemplate" form:"joinTemplate" gorm:"foreignKey:TemplateID;references:TemplateID;comment:关联"` diff --git a/server/model/system/sys_user.go b/server/model/system/sys_user.go index e9857203b1..916c6b6e0d 100644 --- a/server/model/system/sys_user.go +++ b/server/model/system/sys_user.go @@ -2,27 +2,61 @@ package system import ( "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/model/common" "github.com/gofrs/uuid/v5" ) +type Login interface { + GetUsername() string + GetNickname() string + GetUUID() uuid.UUID + GetUserId() uint + GetAuthorityId() uint + GetUserInfo() any +} + +var _ Login = new(SysUser) + type SysUser struct { global.GVA_MODEL - UUID uuid.UUID `json:"uuid" gorm:"index;comment:用户UUID"` // 用户UUID - Username string `json:"userName" gorm:"index;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 uint `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID - Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"` - Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"` - Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号 - Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱 - Enable int `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结 + UUID uuid.UUID `json:"uuid" gorm:"index;comment:用户UUID"` // 用户UUID + Username string `json:"userName" gorm:"index;comment:用户登录名"` // 用户登录名 + Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码 + NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称 + HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像 + AuthorityId uint `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID + Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"` // 用户角色 + Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"` // 多用户角色 + Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号 + Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱 + Enable int `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结 + OriginSetting common.JSONMap `json:"originSetting" form:"originSetting" gorm:"type:text;default:null;column:origin_setting;comment:配置;"` //配置 } func (SysUser) TableName() string { return "sys_users" } + +func (s *SysUser) GetUsername() string { + return s.Username +} + +func (s *SysUser) GetNickname() string { + return s.NickName +} + +func (s *SysUser) GetUUID() uuid.UUID { + return s.UUID +} + +func (s *SysUser) GetUserId() uint { + return s.ID +} + +func (s *SysUser) GetAuthorityId() uint { + return s.AuthorityId +} + +func (s *SysUser) GetUserInfo() any { + return *s +} diff --git a/server/packfile/notUsePackFile.go b/server/packfile/notUsePackFile.go deleted file mode 100644 index 53871d6a7b..0000000000 --- a/server/packfile/notUsePackFile.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build !packfile -// +build !packfile - -package packfile diff --git a/server/packfile/usePackFile.go b/server/packfile/usePackFile.go deleted file mode 100644 index 7820af9994..0000000000 --- a/server/packfile/usePackFile.go +++ /dev/null @@ -1,45 +0,0 @@ -//go:build packfile -// +build packfile - -package packfile - -import ( - "fmt" - "os" - "path/filepath" - "strings" -) - -//go:generate go-bindata -o=staticFile.go -pkg=packfile -tags=packfile ../resource/... ../config.yaml - -func writeFile(path string, data []byte) { - // 如果文件夹不存在,预先创建文件夹 - if lastSeparator := strings.LastIndex(path, "/"); lastSeparator != -1 { - dirPath := path[:lastSeparator] - if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) { - os.MkdirAll(dirPath, os.ModePerm) - } - } - - // 已存在的文件,不应该覆盖重写,可能在前端更改了配置文件等 - if _, err := os.Stat(path); os.IsNotExist(err) { - if err2 := os.WriteFile(path, data, os.ModePerm); err2 != nil { - fmt.Printf("Write file failed: %s\n", path) - } - } else { - fmt.Printf("File exist, skip: %s\n", path) - } -} - -func init() { - for key := range _bindata { - filePath, _ := filepath.Abs(strings.TrimPrefix(key, ".")) - data, err := Asset(key) - if err != nil { - // Asset was not found. - fmt.Printf("Fail to find: %s\n", filePath) - } else { - writeFile(filePath, data) - } - } -} diff --git a/server/plugin/announcement/api/enter.go b/server/plugin/announcement/api/enter.go new file mode 100644 index 0000000000..7fee6fc2b6 --- /dev/null +++ b/server/plugin/announcement/api/enter.go @@ -0,0 +1,10 @@ +package api + +import "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/service" + +var ( + Api = new(api) + serviceInfo = service.Service.Info +) + +type api struct{ Info info } diff --git a/server/plugin/announcement/api/info.go b/server/plugin/announcement/api/info.go new file mode 100644 index 0000000000..dd0faa350f --- /dev/null +++ b/server/plugin/announcement/api/info.go @@ -0,0 +1,183 @@ +package api + +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/plugin/announcement/model" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/model/request" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +var Info = new(info) + +type info struct{} + +// CreateInfo 创建公告 +// @Tags Info +// @Summary 创建公告 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.Info true "创建公告" +// @Success 200 {object} response.Response{msg=string} "创建成功" +// @Router /info/createInfo [post] +func (a *info) CreateInfo(c *gin.Context) { + var info model.Info + err := c.ShouldBindJSON(&info) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = serviceInfo.CreateInfo(&info) + if err != nil { + global.GVA_LOG.Error("创建失败!", zap.Error(err)) + response.FailWithMessage("创建失败", c) + return + } + response.OkWithMessage("创建成功", c) +} + +// DeleteInfo 删除公告 +// @Tags Info +// @Summary 删除公告 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.Info true "删除公告" +// @Success 200 {object} response.Response{msg=string} "删除成功" +// @Router /info/deleteInfo [delete] +func (a *info) DeleteInfo(c *gin.Context) { + ID := c.Query("ID") + err := serviceInfo.DeleteInfo(ID) + if err != nil { + global.GVA_LOG.Error("删除失败!", zap.Error(err)) + response.FailWithMessage("删除失败", c) + return + } + response.OkWithMessage("删除成功", c) +} + +// DeleteInfoByIds 批量删除公告 +// @Tags Info +// @Summary 批量删除公告 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "批量删除成功" +// @Router /info/deleteInfoByIds [delete] +func (a *info) DeleteInfoByIds(c *gin.Context) { + IDs := c.QueryArray("IDs[]") + if err := serviceInfo.DeleteInfoByIds(IDs); err != nil { + global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) + response.FailWithMessage("批量删除失败", c) + return + } + response.OkWithMessage("批量删除成功", c) +} + +// UpdateInfo 更新公告 +// @Tags Info +// @Summary 更新公告 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.Info true "更新公告" +// @Success 200 {object} response.Response{msg=string} "更新成功" +// @Router /info/updateInfo [put] +func (a *info) UpdateInfo(c *gin.Context) { + var info model.Info + err := c.ShouldBindJSON(&info) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = serviceInfo.UpdateInfo(info) + if err != nil { + global.GVA_LOG.Error("更新失败!", zap.Error(err)) + response.FailWithMessage("更新失败", c) + return + } + response.OkWithMessage("更新成功", c) +} + +// FindInfo 用id查询公告 +// @Tags Info +// @Summary 用id查询公告 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data query model.Info true "用id查询公告" +// @Success 200 {object} response.Response{data=model.Info,msg=string} "查询成功" +// @Router /info/findInfo [get] +func (a *info) FindInfo(c *gin.Context) { + ID := c.Query("ID") + reinfo, err := serviceInfo.GetInfo(ID) + if err != nil { + global.GVA_LOG.Error("查询失败!", zap.Error(err)) + response.FailWithMessage("查询失败", c) + return + } + response.OkWithData(reinfo, c) +} + +// GetInfoList 分页获取公告列表 +// @Tags Info +// @Summary 分页获取公告列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data query request.InfoSearch true "分页获取公告列表" +// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功" +// @Router /info/getInfoList [get] +func (a *info) GetInfoList(c *gin.Context) { + var pageInfo request.InfoSearch + err := c.ShouldBindQuery(&pageInfo) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + list, total, err := serviceInfo.GetInfoInfoList(pageInfo) + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败", c) + return + } + response.OkWithDetailed(response.PageResult{ + List: list, + Total: total, + Page: pageInfo.Page, + PageSize: pageInfo.PageSize, + }, "获取成功", c) +} + +// GetInfoDataSource 获取Info的数据源 +// @Tags Info +// @Summary 获取Info的数据源 +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=object,msg=string} "查询成功" +// @Router /info/getInfoDataSource [get] +func (a *info) GetInfoDataSource(c *gin.Context) { + // 此接口为获取数据源定义的数据 + dataSource, err := serviceInfo.GetInfoDataSource() + if err != nil { + global.GVA_LOG.Error("查询失败!", zap.Error(err)) + response.FailWithMessage("查询失败", c) + return + } + response.OkWithData(dataSource, c) +} + +// GetInfoPublic 不需要鉴权的公告接口 +// @Tags Info +// @Summary 不需要鉴权的公告接口 +// @accept application/json +// @Produce application/json +// @Param data query request.InfoSearch true "分页获取公告列表" +// @Success 200 {object} response.Response{data=object,msg=string} "获取成功" +// @Router /info/getInfoPublic [get] +func (a *info) GetInfoPublic(c *gin.Context) { + // 此接口不需要鉴权 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑 + response.OkWithDetailed(gin.H{"info": "不需要鉴权的公告接口信息"}, "获取成功", c) +} diff --git a/server/plugin/announcement/config/config.go b/server/plugin/announcement/config/config.go new file mode 100644 index 0000000000..809bc990fc --- /dev/null +++ b/server/plugin/announcement/config/config.go @@ -0,0 +1,4 @@ +package config + +type Config struct { +} diff --git a/server/plugin/announcement/gen/gen.go b/server/plugin/announcement/gen/gen.go new file mode 100644 index 0000000000..240749ff1a --- /dev/null +++ b/server/plugin/announcement/gen/gen.go @@ -0,0 +1,17 @@ +package main + +import ( + "gorm.io/gen" + "path/filepath" //go:generate go mod tidy + //go:generate go mod download + //go:generate go run gen.go + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/model" +) + +func main() { + g := gen.NewGenerator(gen.Config{OutPath: filepath.Join("..", "..", "..", "announcement", "blender", "model", "dao"), Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface}) + g.ApplyBasic( + new(model.Info), + ) + g.Execute() +} diff --git a/server/plugin/announcement/initialize/api.go b/server/plugin/announcement/initialize/api.go new file mode 100644 index 0000000000..6d0fed1d02 --- /dev/null +++ b/server/plugin/announcement/initialize/api.go @@ -0,0 +1,49 @@ +package initialize + +import ( + "context" + model "github.com/flipped-aurora/gin-vue-admin/server/model/system" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/plugin-tool/utils" +) + +func Api(ctx context.Context) { + entities := []model.SysApi{ + { + Path: "/info/createInfo", + Description: "新建公告", + ApiGroup: "公告", + Method: "POST", + }, + { + Path: "/info/deleteInfo", + Description: "删除公告", + ApiGroup: "公告", + Method: "DELETE", + }, + { + Path: "/info/deleteInfoByIds", + Description: "批量删除公告", + ApiGroup: "公告", + Method: "DELETE", + }, + { + Path: "/info/updateInfo", + Description: "更新公告", + ApiGroup: "公告", + Method: "PUT", + }, + { + Path: "/info/findInfo", + Description: "根据ID获取公告", + ApiGroup: "公告", + Method: "GET", + }, + { + Path: "/info/getInfoList", + Description: "获取公告列表", + ApiGroup: "公告", + Method: "GET", + }, + } + utils.RegisterApis(entities...) +} diff --git a/server/plugin/announcement/initialize/gorm.go b/server/plugin/announcement/initialize/gorm.go new file mode 100644 index 0000000000..3a88ff25a9 --- /dev/null +++ b/server/plugin/announcement/initialize/gorm.go @@ -0,0 +1,20 @@ +package initialize + +import ( + "context" + "fmt" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/model" + "github.com/pkg/errors" + "go.uber.org/zap" +) + +func Gorm(ctx context.Context) { + err := global.GVA_DB.WithContext(ctx).AutoMigrate( + new(model.Info), + ) + if err != nil { + err = errors.Wrap(err, "注册表失败!") + zap.L().Error(fmt.Sprintf("%+v", err)) + } +} diff --git a/server/plugin/announcement/initialize/menu.go b/server/plugin/announcement/initialize/menu.go new file mode 100644 index 0000000000..40aff2b508 --- /dev/null +++ b/server/plugin/announcement/initialize/menu.go @@ -0,0 +1,22 @@ +package initialize + +import ( + "context" + model "github.com/flipped-aurora/gin-vue-admin/server/model/system" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/plugin-tool/utils" +) + +func Menu(ctx context.Context) { + entities := []model.SysBaseMenu{ + { + ParentId: 24, + Path: "anInfo", + Name: "anInfo", + Hidden: false, + Component: "plugin/announcement/view/info.vue", + Sort: 5, + Meta: model.Meta{Title: "公告管理", Icon: "box"}, + }, + } + utils.RegisterMenus(entities...) +} diff --git a/server/plugin/announcement/initialize/router.go b/server/plugin/announcement/initialize/router.go new file mode 100644 index 0000000000..e2c4f17878 --- /dev/null +++ b/server/plugin/announcement/initialize/router.go @@ -0,0 +1,15 @@ +package initialize + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/middleware" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/router" + "github.com/gin-gonic/gin" +) + +func Router(engine *gin.Engine) { + public := engine.Group(global.GVA_CONFIG.System.RouterPrefix).Group("") + private := engine.Group(global.GVA_CONFIG.System.RouterPrefix).Group("") + private.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + router.Router.Info.Init(public, private) +} diff --git a/server/plugin/announcement/initialize/viper.go b/server/plugin/announcement/initialize/viper.go new file mode 100644 index 0000000000..68cfff6855 --- /dev/null +++ b/server/plugin/announcement/initialize/viper.go @@ -0,0 +1,17 @@ +package initialize + +import ( + "fmt" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/plugin" + "github.com/pkg/errors" + "go.uber.org/zap" +) + +func Viper() { + err := global.GVA_VP.UnmarshalKey("announcement", &plugin.Config) + if err != nil { + err = errors.Wrap(err, "初始化配置文件失败!") + zap.L().Error(fmt.Sprintf("%+v", err)) + } +} diff --git a/server/plugin/announcement/model/info.go b/server/plugin/announcement/model/info.go new file mode 100644 index 0000000000..fcaa11f59d --- /dev/null +++ b/server/plugin/announcement/model/info.go @@ -0,0 +1,20 @@ +package model + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + "gorm.io/datatypes" +) + +// Info 公告 结构体 +type Info struct { + global.GVA_MODEL + Title string `json:"title" form:"title" gorm:"column:title;comment:公告标题;"` //标题 + Content string `json:"content" form:"content" gorm:"column:content;comment:公告内容;type:text;"` //内容 + UserID *int `json:"userID" form:"userID" gorm:"column:user_id;comment:发布者;"` //作者 + Attachments datatypes.JSON `json:"attachments" form:"attachments" gorm:"column:attachments;comment:相关附件;"swaggertype:"array,object"` //附件 +} + +// TableName 公告 Info自定义表名 gva_announcements_info +func (Info) TableName() string { + return "gva_announcements_info" +} diff --git a/server/plugin/announcement/model/request/info.go b/server/plugin/announcement/model/request/info.go new file mode 100644 index 0000000000..35be3e0322 --- /dev/null +++ b/server/plugin/announcement/model/request/info.go @@ -0,0 +1,12 @@ +package request + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + "time" +) + +type InfoSearch struct { + StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"` + EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"` + request.PageInfo +} diff --git a/server/plugin/announcement/plugin.go b/server/plugin/announcement/plugin.go new file mode 100644 index 0000000000..a20edb8945 --- /dev/null +++ b/server/plugin/announcement/plugin.go @@ -0,0 +1,26 @@ +package announcement + +import ( + "context" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/initialize" + interfaces "github.com/flipped-aurora/gin-vue-admin/server/utils/plugin/v2" + "github.com/gin-gonic/gin" +) + +var _ interfaces.Plugin = (*plugin)(nil) + +var Plugin = new(plugin) + +type plugin struct{} + +func (p *plugin) Register(group *gin.Engine) { + ctx := context.Background() + // 如果需要配置文件,请到config.Config中填充配置结构,且到下方发放中填入其在config.yaml中的key + // initialize.Viper() + // 安装插件时候自动注册的api数据请到下方法.Api方法中实现 + initialize.Api(ctx) + // 安装插件时候自动注册的api数据请到下方法.Menu方法中实现 + initialize.Menu(ctx) + initialize.Gorm(ctx) + initialize.Router(group) +} diff --git a/server/plugin/announcement/plugin/plugin.go b/server/plugin/announcement/plugin/plugin.go new file mode 100644 index 0000000000..4058239807 --- /dev/null +++ b/server/plugin/announcement/plugin/plugin.go @@ -0,0 +1,5 @@ +package plugin + +import "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/config" + +var Config config.Config diff --git a/server/plugin/announcement/router/enter.go b/server/plugin/announcement/router/enter.go new file mode 100644 index 0000000000..543e0ffb22 --- /dev/null +++ b/server/plugin/announcement/router/enter.go @@ -0,0 +1,10 @@ +package router + +import "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/api" + +var ( + Router = new(router) + apiInfo = api.Api.Info +) + +type router struct{ Info info } diff --git a/server/plugin/announcement/router/info.go b/server/plugin/announcement/router/info.go new file mode 100644 index 0000000000..8de316b35d --- /dev/null +++ b/server/plugin/announcement/router/info.go @@ -0,0 +1,31 @@ +package router + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/middleware" + "github.com/gin-gonic/gin" +) + +var Info = new(info) + +type info struct{} + +// Init 初始化 公告 路由信息 +func (r *info) Init(public *gin.RouterGroup, private *gin.RouterGroup) { + { + group := private.Group("info").Use(middleware.OperationRecord()) + group.POST("createInfo", apiInfo.CreateInfo) // 新建公告 + group.DELETE("deleteInfo", apiInfo.DeleteInfo) // 删除公告 + group.DELETE("deleteInfoByIds", apiInfo.DeleteInfoByIds) // 批量删除公告 + group.PUT("updateInfo", apiInfo.UpdateInfo) // 更新公告 + } + { + group := private.Group("info") + group.GET("findInfo", apiInfo.FindInfo) // 根据ID获取公告 + group.GET("getInfoList", apiInfo.GetInfoList) // 获取公告列表 + } + { + group := public.Group("info") + group.GET("getInfoDataSource", apiInfo.GetInfoDataSource) // 获取公告数据源 + group.GET("getInfoPublic", apiInfo.GetInfoPublic) // 获取公告列表 + } +} diff --git a/server/plugin/announcement/service/enter.go b/server/plugin/announcement/service/enter.go new file mode 100644 index 0000000000..988fbcd765 --- /dev/null +++ b/server/plugin/announcement/service/enter.go @@ -0,0 +1,5 @@ +package service + +var Service = new(service) + +type service struct{ Info info } diff --git a/server/plugin/announcement/service/info.go b/server/plugin/announcement/service/info.go new file mode 100644 index 0000000000..b52155393f --- /dev/null +++ b/server/plugin/announcement/service/info.go @@ -0,0 +1,78 @@ +package service + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/model" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/model/request" +) + +var Info = new(info) + +type info struct{} + +// CreateInfo 创建公告记录 +// Author [piexlmax](https://github.com/piexlmax) +func (s *info) CreateInfo(info *model.Info) (err error) { + err = global.GVA_DB.Create(info).Error + return err +} + +// DeleteInfo 删除公告记录 +// Author [piexlmax](https://github.com/piexlmax) +func (s *info) DeleteInfo(ID string) (err error) { + err = global.GVA_DB.Delete(&model.Info{}, "id = ?", ID).Error + return err +} + +// DeleteInfoByIds 批量删除公告记录 +// Author [piexlmax](https://github.com/piexlmax) +func (s *info) DeleteInfoByIds(IDs []string) (err error) { + err = global.GVA_DB.Delete(&[]model.Info{}, "id in ?", IDs).Error + return err +} + +// UpdateInfo 更新公告记录 +// Author [piexlmax](https://github.com/piexlmax) +func (s *info) UpdateInfo(info model.Info) (err error) { + err = global.GVA_DB.Model(&model.Info{}).Where("id = ?", info.ID).Updates(&info).Error + return err +} + +// GetInfo 根据ID获取公告记录 +// Author [piexlmax](https://github.com/piexlmax) +func (s *info) GetInfo(ID string) (info model.Info, err error) { + err = global.GVA_DB.Where("id = ?", ID).First(&info).Error + return +} + +// GetInfoInfoList 分页获取公告记录 +// Author [piexlmax](https://github.com/piexlmax) +func (s *info) GetInfoInfoList(info request.InfoSearch) (list []model.Info, total int64, err error) { + limit := info.PageSize + offset := info.PageSize * (info.Page - 1) + // 创建db + db := global.GVA_DB.Model(&model.Info{}) + var infos []model.Info + // 如果有条件搜索 下方会自动创建搜索语句 + if info.StartCreatedAt != nil && info.EndCreatedAt != nil { + db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt) + } + err = db.Count(&total).Error + if err != nil { + return + } + + if limit != 0 { + db = db.Limit(limit).Offset(offset) + } + err = db.Find(&infos).Error + return infos, total, err +} +func (s *info) GetInfoDataSource() (res map[string][]map[string]any, err error) { + res = make(map[string][]map[string]any) + + userID := make([]map[string]any, 0) + global.GVA_DB.Table("sys_users").Select("nick_name as label,id as value").Scan(&userID) + res["userID"] = userID + return +} diff --git a/server/plugin/plugin-tool/utils/check.go b/server/plugin/plugin-tool/utils/check.go index 4e8c09940d..4ea21921ed 100644 --- a/server/plugin/plugin-tool/utils/check.go +++ b/server/plugin/plugin-tool/utils/check.go @@ -15,7 +15,6 @@ func RegisterApis(apis ...system.SysApi) { } global.GVA_DB.Find(&[]system.SysApi{}, "path in (?)", apiPaths).Count(&count) if count > 0 { - fmt.Println("插件已安装或存在同名路由") return } err := global.GVA_DB.Create(&apis).Error @@ -34,10 +33,8 @@ func RegisterMenus(menus ...system.SysBaseMenu) { } global.GVA_DB.Find(&[]system.SysBaseMenu{}, "name in (?)", menuNames).Count(&count) if count > 0 { - fmt.Println("插件已安装或存在同名菜单") return } - parentMenu.ParentId = 0 err := global.GVA_DB.Create(&parentMenu).Error if err != nil { fmt.Println(err) diff --git a/server/resource/autocode_template/server/model.go.tpl b/server/resource/autocode_template/server/model.go.tpl deleted file mode 100644 index c1f467f318..0000000000 --- a/server/resource/autocode_template/server/model.go.tpl +++ /dev/null @@ -1,45 +0,0 @@ -// 自动生成模板{{.StructName}} -package {{.Package}} - -import ( - {{ if .GvaModel }}"github.com/flipped-aurora/gin-vue-admin/server/global"{{ end }} - {{ if or .HasTimer }}"time"{{ end }} - {{ if .NeedJSON }}"gorm.io/datatypes"{{ end }} -) - -// {{.Description}} 结构体 {{.StructName}} -type {{.StructName}} struct { -{{ if .GvaModel }} global.GVA_MODEL {{ end }} - {{- range .Fields}} - {{- if eq .FieldType "enum" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if eq .FieldType "picture" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if eq .FieldType "video" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if eq .FieldType "file" }} - {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if eq .FieldType "pictures" }} - {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if eq .FieldType "richtext" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if eq .FieldType "json" }} - {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` - {{- else if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` - {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` - {{- end }} {{ if .FieldDesc }}//{{.FieldDesc}} {{ end }} {{- end }} - {{- if .AutoCreateResource }} - CreatedBy uint `gorm:"column:created_by;comment:创建者"` - UpdatedBy uint `gorm:"column:updated_by;comment:更新者"` - DeletedBy uint `gorm:"column:deleted_by;comment:删除者"` - {{- end}} -} - -{{ if .TableName }} -// TableName {{.Description}} {{.StructName}}自定义表名 {{.TableName}} -func ({{.StructName}}) TableName() string { - return "{{.TableName}}" -} -{{ end }} diff --git a/server/resource/autocode_template/server/request.go.tpl b/server/resource/autocode_template/server/request.go.tpl deleted file mode 100644 index 7acd20ff10..0000000000 --- a/server/resource/autocode_template/server/request.go.tpl +++ /dev/null @@ -1,45 +0,0 @@ -package request - -import ( - "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" - {{ if or .HasSearchTimer .GvaModel}}"time"{{ end }} - {{ if .NeedJSON }}"gorm.io/datatypes"{{ end }} -) - -type {{.StructName}}Search struct{ - {{ if .GvaModel }} - StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"` - EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"` - {{ end }} - {{- range .Fields}} - {{- if ne .FieldSearchType ""}} - {{- if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} - Start{{.FieldName}} *{{.FieldType}} `json:"start{{.FieldName}}" form:"start{{.FieldName}}"` - End{{.FieldName}} *{{.FieldType}} `json:"end{{.FieldName}}" form:"end{{.FieldName}}"` - {{- else }} - {{- if eq .FieldType "enum" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}"` - {{- else if eq .FieldType "picture" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if eq .FieldType "video" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if eq .FieldType "file" }} - {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if eq .FieldType "pictures" }} - {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if eq .FieldType "richtext" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- end }} - {{- end }} - {{- end}} - {{- end }} - request.PageInfo - {{- if .NeedSort}} - Sort string `json:"sort" form:"sort"` - Order string `json:"order" form:"order"` - {{- end}} -} diff --git a/server/resource/autocode_template/subcontract/api_enter.go.tpl b/server/resource/autocode_template/subcontract/api_enter.go.tpl deleted file mode 100644 index d94193b8e3..0000000000 --- a/server/resource/autocode_template/subcontract/api_enter.go.tpl +++ /dev/null @@ -1,4 +0,0 @@ -package {{ .PackageName }} - -type ApiGroup struct { -} diff --git a/server/resource/autocode_template/subcontract/data.go b/server/resource/autocode_template/subcontract/data.go deleted file mode 100644 index cb445a5e1f..0000000000 --- a/server/resource/autocode_template/subcontract/data.go +++ /dev/null @@ -1,14 +0,0 @@ -package subcontract - -import ( - _ "embed" -) - -//go:embed api_enter.go.tpl -var API []byte - -//go:embed router_enter.go.tpl -var Router []byte - -//go:embed service_enter.go.tpl -var Server []byte diff --git a/server/resource/autocode_template/subcontract/router_enter.go.tpl b/server/resource/autocode_template/subcontract/router_enter.go.tpl deleted file mode 100644 index 24dec196ff..0000000000 --- a/server/resource/autocode_template/subcontract/router_enter.go.tpl +++ /dev/null @@ -1,4 +0,0 @@ -package {{ .PackageName }} - -type RouterGroup struct { -} diff --git a/server/resource/autocode_template/subcontract/service_enter.go.tpl b/server/resource/autocode_template/subcontract/service_enter.go.tpl deleted file mode 100644 index c8d82a4def..0000000000 --- a/server/resource/autocode_template/subcontract/service_enter.go.tpl +++ /dev/null @@ -1,6 +0,0 @@ -package {{ .PackageName }} - - -type ServiceGroup struct { -} - diff --git a/server/resource/function/api.go.tpl b/server/resource/function/api.go.tpl new file mode 100644 index 0000000000..1d276cff63 --- /dev/null +++ b/server/resource/function/api.go.tpl @@ -0,0 +1,40 @@ +{{if .IsPlugin}} +// {{.FuncName}} {{.FuncDesc}} +// @Tags {{.StructName}} +// @Summary {{.FuncDesc}} +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=object,msg=string} "获取成功" +// @Router /{{.Abbreviation}}/{{.Router}} [{{.Method}}] +func (a *{{.Abbreviation}}) {{.FuncName}}(c *gin.Context) { + // 请添加自己的业务逻辑 + err := service{{ .StructName }}.{{.FuncName}}() + if err != nil { + global.GVA_LOG.Error("失败!", zap.Error(err)) + response.FailWithMessage("失败", c) + return + } + response.OkWithData("返回数据",c) +} + +{{- else -}} + +// {{.FuncName}} {{.FuncDesc}} +// @Tags {{.StructName}} +// @Summary {{.FuncDesc}} +// @accept application/json +// @Produce application/json +// @Param data query {{.Package}}Req.{{.StructName}}Search true "成功" +// @Success 200 {object} response.Response{data=object,msg=string} "成功" +// @Router /{{.Abbreviation}}/{{.Router}} [{{.Method}}] +func ({{.Abbreviation}}Api *{{.StructName}}Api){{.FuncName}}(c *gin.Context) { + // 请添加自己的业务逻辑 + err := {{.Abbreviation}}Service.{{.FuncName}}() + if err != nil { + global.GVA_LOG.Error("失败!", zap.Error(err)) + response.FailWithMessage("失败", c) + return + } + response.OkWithData("返回数据",c) +} +{{end}} \ No newline at end of file diff --git a/server/resource/function/api.js.tpl b/server/resource/function/api.js.tpl new file mode 100644 index 0000000000..5cc491fe32 --- /dev/null +++ b/server/resource/function/api.js.tpl @@ -0,0 +1,32 @@ +{{if .IsPlugin}} +// {{.FuncName}} {{.FuncDesc}} +// @Tags {{.StructName}} +// @Summary {{.FuncDesc}} +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=object,msg=string} "获取成功" +// @Router /{{.Abbreviation}}/{{.Router}} [{{.Method}}] +export const {{.Router}} = () => { + return service({ + url: '/{{.Abbreviation}}/{{.Router}}', + method: '{{.Method}}' + }) +} + +{{- else -}} + +// {{.FuncName}} {{.FuncDesc}} +// @Tags {{.StructName}} +// @Summary {{.FuncDesc}} +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=object,msg=string} "成功" +// @Router /{{.Abbreviation}}/{{.Router}} [{{.Method}}] +export const {{.Router}} = () => { + return service({ + url: '/{{.Abbreviation}}/{{.Router}}', + method: '{{.Method}}' + }) +} + +{{- end -}} \ No newline at end of file diff --git a/server/resource/function/server.go.tpl b/server/resource/function/server.go.tpl new file mode 100644 index 0000000000..1c5191c4b4 --- /dev/null +++ b/server/resource/function/server.go.tpl @@ -0,0 +1,25 @@ +{{- $db := "" }} +{{- if eq .BusinessDB "" }} + {{- $db = "global.GVA_DB" }} +{{- else}} + {{- $db = printf "global.MustGetGlobalDBByDBName(\"%s\")" .BusinessDB }} +{{- end}} +{{if .IsPlugin}} + +// {{.FuncName}} {{.FuncDesc}} +// Author [yourname](https://github.com/yourname) +func (s *{{.Abbreviation}}) {{.FuncName}}() (err error) { + db := {{$db}}.Model(&model.{{.StructName}}{}) + return db.Error +} + +{{- else -}} + +// {{.FuncName}} {{.FuncDesc}} +// Author [yourname](https://github.com/yourname) +func ({{.Abbreviation}}Service *{{.StructName}}Service){{.FuncName}}() (err error) { + // 请在这里实现自己的业务逻辑 + db := {{$db}}.Model(&{{.Package}}.{{.StructName}}{}) + return db.Error +} +{{end}} \ No newline at end of file diff --git a/server/resource/autocode_template/readme.txt.tpl b/server/resource/package/readme.txt.tpl similarity index 100% rename from server/resource/autocode_template/readme.txt.tpl rename to server/resource/package/readme.txt.tpl diff --git a/server/resource/autocode_template/server/api.go.tpl b/server/resource/package/server/api/api.go.tpl similarity index 60% rename from server/resource/autocode_template/server/api.go.tpl rename to server/resource/package/server/api/api.go.tpl index 0fa88e9a44..43e727aa14 100644 --- a/server/resource/autocode_template/server/api.go.tpl +++ b/server/resource/package/server/api/api.go.tpl @@ -1,23 +1,25 @@ package {{.Package}} import ( + {{if not .OnlyTemplate}} "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/{{.Package}}" {{.Package}}Req "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}/request" - "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" - "github.com/flipped-aurora/gin-vue-admin/server/service" "github.com/gin-gonic/gin" "go.uber.org/zap" {{- if .AutoCreateResource}} "github.com/flipped-aurora/gin-vue-admin/server/utils" {{- end }} + {{- else}} + "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" + "github.com/gin-gonic/gin" + {{- end}} ) -type {{.StructName}}Api struct { -} - -var {{.Abbreviation}}Service = service.ServiceGroupApp.{{.PackageT}}ServiceGroup.{{.StructName}}Service +type {{.StructName}}Api struct {} +{{if not .OnlyTemplate}} // Create{{.StructName}} 创建{{.Description}} // @Tags {{.StructName}} @@ -26,7 +28,7 @@ var {{.Abbreviation}}Service = service.ServiceGroupApp.{{.PackageT}}ServiceGroup // @accept application/json // @Produce application/json // @Param data body {{.Package}}.{{.StructName}} true "创建{{.Description}}" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Success 200 {object} response.Response{msg=string} "创建成功" // @Router /{{.Abbreviation}}/create{{.StructName}} [post] func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Context) { var {{.Abbreviation}} {{.Package}}.{{.StructName}} @@ -38,13 +40,13 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con {{- if .AutoCreateResource }} {{.Abbreviation}}.CreatedBy = utils.GetUserID(c) {{- end }} - - if err := {{.Abbreviation}}Service.Create{{.StructName}}(&{{.Abbreviation}}); err != nil { + err = {{.Abbreviation}}Service.Create{{.StructName}}(&{{.Abbreviation}}) + if err != nil { global.GVA_LOG.Error("创建失败!", zap.Error(err)) - response.FailWithMessage("创建失败", c) - } else { - response.OkWithMessage("创建成功", c) + response.FailWithMessage("创建失败:" + err.Error(), c) + return } + response.OkWithMessage("创建成功", c) } // Delete{{.StructName}} 删除{{.Description}} @@ -54,19 +56,20 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con // @accept application/json // @Produce application/json // @Param data body {{.Package}}.{{.StructName}} true "删除{{.Description}}" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Success 200 {object} response.Response{msg=string} "删除成功" // @Router /{{.Abbreviation}}/delete{{.StructName}} [delete] func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Context) { {{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}") {{- if .AutoCreateResource }} - userID := utils.GetUserID(c) + userID := utils.GetUserID(c) {{- end }} - if err := {{.Abbreviation}}Service.Delete{{.StructName}}({{.PrimaryField.FieldJson}} {{- if .AutoCreateResource -}},userID{{- end -}}); err != nil { + err := {{.Abbreviation}}Service.Delete{{.StructName}}({{.PrimaryField.FieldJson}} {{- if .AutoCreateResource -}},userID{{- end -}}) + if err != nil { global.GVA_LOG.Error("删除失败!", zap.Error(err)) - response.FailWithMessage("删除失败", c) - } else { - response.OkWithMessage("删除成功", c) + response.FailWithMessage("删除失败:" + err.Error(), c) + return } + response.OkWithMessage("删除成功", c) } // Delete{{.StructName}}ByIds 批量删除{{.Description}} @@ -75,19 +78,20 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Con // @Security ApiKeyAuth // @accept application/json // @Produce application/json -// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}" +// @Success 200 {object} response.Response{msg=string} "批量删除成功" // @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete] func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gin.Context) { {{.PrimaryField.FieldJson}}s := c.QueryArray("{{.PrimaryField.FieldJson}}s[]") {{- if .AutoCreateResource }} userID := utils.GetUserID(c) {{- end }} - if err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }},userID{{- end }}); err != nil { + err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }},userID{{- end }}) + if err != nil { global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) - response.FailWithMessage("批量删除失败", c) - } else { - response.OkWithMessage("批量删除成功", c) + response.FailWithMessage("批量删除失败:" + err.Error(), c) + return } + response.OkWithMessage("批量删除成功", c) } // Update{{.StructName}} 更新{{.Description}} @@ -97,7 +101,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gi // @accept application/json // @Produce application/json // @Param data body {{.Package}}.{{.StructName}} true "更新{{.Description}}" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}" +// @Success 200 {object} response.Response{msg=string} "更新成功" // @Router /{{.Abbreviation}}/update{{.StructName}} [put] func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Context) { var {{.Abbreviation}} {{.Package}}.{{.StructName}} @@ -109,13 +113,13 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Con {{- if .AutoCreateResource }} {{.Abbreviation}}.UpdatedBy = utils.GetUserID(c) {{- end }} - - if err := {{.Abbreviation}}Service.Update{{.StructName}}({{.Abbreviation}}); err != nil { + err = {{.Abbreviation}}Service.Update{{.StructName}}({{.Abbreviation}}) + if err != nil { global.GVA_LOG.Error("更新失败!", zap.Error(err)) - response.FailWithMessage("更新失败", c) - } else { - response.OkWithMessage("更新成功", c) + response.FailWithMessage("更新失败:" + err.Error(), c) + return } + response.OkWithMessage("更新成功", c) } // Find{{.StructName}} 用id查询{{.Description}} @@ -125,16 +129,17 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Con // @accept application/json // @Produce application/json // @Param data query {{.Package}}.{{.StructName}} true "用id查询{{.Description}}" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}" +// @Success 200 {object} response.Response{data={{.Package}}.{{.StructName}},msg=string} "查询成功" // @Router /{{.Abbreviation}}/find{{.StructName}} [get] func ({{.Abbreviation}}Api *{{.StructName}}Api) Find{{.StructName}}(c *gin.Context) { {{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}") - if re{{.Abbreviation}}, err := {{.Abbreviation}}Service.Get{{.StructName}}({{.PrimaryField.FieldJson}}); err != nil { + re{{.Abbreviation}}, err := {{.Abbreviation}}Service.Get{{.StructName}}({{.PrimaryField.FieldJson}}) + if err != nil { global.GVA_LOG.Error("查询失败!", zap.Error(err)) - response.FailWithMessage("查询失败", c) - } else { - response.OkWithData(gin.H{"re{{.Abbreviation}}": re{{.Abbreviation}}}, c) + response.FailWithMessage("查询失败:" + err.Error(), c) + return } + response.OkWithData(re{{.Abbreviation}}, c) } // Get{{.StructName}}List 分页获取{{.Description}}列表 @@ -144,7 +149,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Find{{.StructName}}(c *gin.Conte // @accept application/json // @Produce application/json // @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功" // @Router /{{.Abbreviation}}/get{{.StructName}}List [get] func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Context) { var pageInfo {{.Package}}Req.{{.StructName}}Search @@ -153,30 +158,54 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Co response.FailWithMessage(err.Error(), c) return } - if list, total, err := {{.Abbreviation}}Service.Get{{.StructName}}InfoList(pageInfo); err != nil { + list, total, err := {{.Abbreviation}}Service.Get{{.StructName}}InfoList(pageInfo) + if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) - response.FailWithMessage("获取失败", c) - } else { - response.OkWithDetailed(response.PageResult{ - List: list, - Total: total, - Page: pageInfo.Page, - PageSize: pageInfo.PageSize, - }, "获取成功", c) + response.FailWithMessage("获取失败:" + err.Error(), c) + return } + response.OkWithDetailed(response.PageResult{ + List: list, + Total: total, + Page: pageInfo.Page, + PageSize: pageInfo.PageSize, + }, "获取成功", c) } +{{- if .HasDataSource }} +// Get{{.StructName}}DataSource 获取{{.StructName}}的数据源 +// @Tags {{.StructName}} +// @Summary 获取{{.StructName}}的数据源 +// @accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=object,msg=string} "查询成功" +// @Router /{{.Abbreviation}}/get{{.StructName}}DataSource [get] +func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}DataSource(c *gin.Context) { + // 此接口为获取数据源定义的数据 + dataSource, err := {{.Abbreviation}}Service.Get{{.StructName}}DataSource() + if err != nil { + global.GVA_LOG.Error("查询失败!", zap.Error(err)) + response.FailWithMessage("查询失败:" + err.Error(), c) + return + } + response.OkWithData(dataSource, c) +} +{{- end }} + +{{- end }} + // Get{{.StructName}}Public 不需要鉴权的{{.Description}}接口 // @Tags {{.StructName}} // @Summary 不需要鉴权的{{.Description}}接口 // @accept application/json // @Produce application/json // @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" -// @Router /{{.Abbreviation}}/get{{.StructName}}List [get] +// @Success 200 {object} response.Response{data=object,msg=string} "获取成功" +// @Router /{{.Abbreviation}}/get{{.StructName}}Public [get] func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}Public(c *gin.Context) { // 此接口不需要鉴权 // 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑 + {{.Abbreviation}}Service.Get{{.StructName}}Public() response.OkWithDetailed(gin.H{ "info": "不需要鉴权的{{.Description}}接口信息", }, "获取成功", c) diff --git a/server/resource/package/server/api/enter.go.tpl b/server/resource/package/server/api/enter.go.tpl new file mode 100644 index 0000000000..778b3146e1 --- /dev/null +++ b/server/resource/package/server/api/enter.go.tpl @@ -0,0 +1,4 @@ +package {{ .Package }} + +type ApiGroup struct { +} \ No newline at end of file diff --git a/server/resource/package/server/model/model.go.tpl b/server/resource/package/server/model/model.go.tpl new file mode 100644 index 0000000000..36d9037547 --- /dev/null +++ b/server/resource/package/server/model/model.go.tpl @@ -0,0 +1,60 @@ +// 自动生成模板{{.StructName}} +package {{.Package}} + +{{- if not .OnlyTemplate}} +import ( + {{- if .GvaModel }} + "github.com/flipped-aurora/gin-vue-admin/server/global" + {{- end }} + {{- if or .HasTimer }} + "time" + {{- end }} + {{- if .NeedJSON }} + "gorm.io/datatypes" + {{- end }} +) +{{- end }} + +// {{.Description}} 结构体 {{.StructName}} +type {{.StructName}} struct { +{{- if not .OnlyTemplate}} +{{- if .GvaModel }} + global.GVA_MODEL +{{- end }} +{{- range .Fields}} + {{- if eq .FieldType "enum" }} + {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};" {{- if .Require }} binding:"required"{{- end -}}` + {{- else if eq .FieldType "picture" }} + {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` + {{- else if eq .FieldType "video" }} + {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` + {{- else if eq .FieldType "file" }} + {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` + {{- else if eq .FieldType "pictures" }} + {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` + {{- else if eq .FieldType "richtext" }} + {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` + {{- else if eq .FieldType "json" }} + {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"object"` + {{- else if eq .FieldType "array" }} + {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` + {{- else if ne .FieldType "string" }} + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` + {{- else }} + {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` + {{- end }} {{ if .FieldDesc }}//{{.FieldDesc}} {{ end }} +{{- end }} + {{- if .AutoCreateResource }} + CreatedBy uint `gorm:"column:created_by;comment:创建者"` + UpdatedBy uint `gorm:"column:updated_by;comment:更新者"` + DeletedBy uint `gorm:"column:deleted_by;comment:删除者"` + {{- end }} +{{- end }} +} + +{{ if .TableName }} +// TableName {{.Description}} {{.StructName}}自定义表名 {{.TableName}} +func ({{.StructName}}) TableName() string { + return "{{.TableName}}" +} +{{ end }} diff --git a/server/resource/package/server/model/request/request.go.tpl b/server/resource/package/server/model/request/request.go.tpl new file mode 100644 index 0000000000..e97a0fd7ab --- /dev/null +++ b/server/resource/package/server/model/request/request.go.tpl @@ -0,0 +1,38 @@ +package request + +import ( +{{- if not .OnlyTemplate }} + "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + {{ if or .HasSearchTimer .GvaModel}}"time"{{ end }} +{{- end }} +) + +type {{.StructName}}Search struct{ +{{- if not .OnlyTemplate}} +{{- if .GvaModel }} + StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"` + EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"` +{{- end }} +{{- range .Fields}} + {{- if ne .FieldSearchType ""}} + {{- if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} + Start{{.FieldName}} *{{.FieldType}} `json:"start{{.FieldName}}" form:"start{{.FieldName}}"` + End{{.FieldName}} *{{.FieldType}} `json:"end{{.FieldName}}" form:"end{{.FieldName}}"` + {{- else }} + {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "richtext") (eq .FieldType "json") }} + {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- else if ne .FieldType "string" }} + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- else }} + {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- end }} + {{- end }} + {{- end}} +{{- end }} + request.PageInfo + {{- if .NeedSort}} + Sort string `json:"sort" form:"sort"` + Order string `json:"order" form:"order"` + {{- end}} +{{- end}} +} diff --git a/server/resource/package/server/router/enter.go.tpl b/server/resource/package/server/router/enter.go.tpl new file mode 100644 index 0000000000..178aecf3bd --- /dev/null +++ b/server/resource/package/server/router/enter.go.tpl @@ -0,0 +1,4 @@ +package {{ .Package }} + +type RouterGroup struct { +} \ No newline at end of file diff --git a/server/resource/autocode_template/server/router.go.tpl b/server/resource/package/server/router/router.go.tpl similarity index 62% rename from server/resource/autocode_template/server/router.go.tpl rename to server/resource/package/server/router/router.go.tpl index 4aef21c3f7..9a4ba9de02 100644 --- a/server/resource/autocode_template/server/router.go.tpl +++ b/server/resource/package/server/router/router.go.tpl @@ -1,21 +1,23 @@ package {{.Package}} import ( - "github.com/flipped-aurora/gin-vue-admin/server/api/v1" - "github.com/flipped-aurora/gin-vue-admin/server/middleware" + {{if .OnlyTemplate}}// {{ end}}"github.com/flipped-aurora/gin-vue-admin/server/middleware" "github.com/gin-gonic/gin" ) -type {{.StructName}}Router struct { -} +type {{.StructName}}Router struct {} // Init{{.StructName}}Router 初始化 {{.Description}} 路由信息 func (s *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGroup,PublicRouter *gin.RouterGroup) { + {{- if not .OnlyTemplate}} {{.Abbreviation}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord()) {{.Abbreviation}}RouterWithoutRecord := Router.Group("{{.Abbreviation}}") + {{- else }} + // {{.Abbreviation}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord()) + // {{.Abbreviation}}RouterWithoutRecord := Router.Group("{{.Abbreviation}}") + {{- end}} {{.Abbreviation}}RouterWithoutAuth := PublicRouter.Group("{{.Abbreviation}}") - - var {{.Abbreviation}}Api = v1.ApiGroupApp.{{.PackageT}}ApiGroup.{{.StructName}}Api + {{- if not .OnlyTemplate}} { {{.Abbreviation}}Router.POST("create{{.StructName}}", {{.Abbreviation}}Api.Create{{.StructName}}) // 新建{{.Description}} {{.Abbreviation}}Router.DELETE("delete{{.StructName}}", {{.Abbreviation}}Api.Delete{{.StructName}}) // 删除{{.Description}} @@ -27,6 +29,14 @@ func (s *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGrou {{.Abbreviation}}RouterWithoutRecord.GET("get{{.StructName}}List", {{.Abbreviation}}Api.Get{{.StructName}}List) // 获取{{.Description}}列表 } { - {{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}Public", {{.Abbreviation}}Api.Get{{.StructName}}Public) // 获取{{.Description}}列表 + {{- if .HasDataSource}} + {{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}DataSource", {{.Abbreviation}}Api.Get{{.StructName}}DataSource) // 获取{{.Description}}数据源 + {{- end}} + {{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}Public", {{.Abbreviation}}Api.Get{{.StructName}}Public) // {{.Description}}开放接口 + } + {{- else}} + { + {{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}Public", {{.Abbreviation}}Api.Get{{.StructName}}Public) // {{.Description}}开放接口 } + {{ end }} } diff --git a/server/resource/package/server/service/enter.go.tpl b/server/resource/package/server/service/enter.go.tpl new file mode 100644 index 0000000000..adf1db02ef --- /dev/null +++ b/server/resource/package/server/service/enter.go.tpl @@ -0,0 +1,4 @@ +package {{ .Package }} + +type ServiceGroup struct { +} \ No newline at end of file diff --git a/server/resource/autocode_template/server/service.go.tpl b/server/resource/package/server/service/service.go.tpl similarity index 80% rename from server/resource/autocode_template/server/service.go.tpl rename to server/resource/package/server/service/service.go.tpl index 1d521c0385..731a3b3248 100644 --- a/server/resource/autocode_template/server/service.go.tpl +++ b/server/resource/package/server/service/service.go.tpl @@ -1,16 +1,17 @@ package {{.Package}} import ( +{{- if not .OnlyTemplate }} "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}" {{.Package}}Req "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}/request" {{- if .AutoCreateResource }} "gorm.io/gorm" {{- end}} +{{- end }} ) -type {{.StructName}}Service struct { -} +type {{.StructName}}Service struct {} {{- $db := "" }} {{- if eq .BusinessDB "" }} @@ -19,15 +20,16 @@ type {{.StructName}}Service struct { {{- $db = printf "global.MustGetGlobalDBByDBName(\"%s\")" .BusinessDB }} {{- end}} +{{- if not .OnlyTemplate }} // Create{{.StructName}} 创建{{.Description}}记录 -// Author [piexlmax](https://github.com/piexlmax) +// Author [yourname](https://github.com/yourname) func ({{.Abbreviation}}Service *{{.StructName}}Service) Create{{.StructName}}({{.Abbreviation}} *{{.Package}}.{{.StructName}}) (err error) { err = {{$db}}.Create({{.Abbreviation}}).Error return err } // Delete{{.StructName}} 删除{{.Description}}记录 -// Author [piexlmax](https://github.com/piexlmax) +// Author [yourname](https://github.com/yourname) func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}({{.PrimaryField.FieldJson}} string{{- if .AutoCreateResource -}},userID uint{{- end -}}) (err error) { {{- if .AutoCreateResource }} err = {{$db}}.Transaction(func(tx *gorm.DB) error { @@ -46,7 +48,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}({{. } // Delete{{.StructName}}ByIds 批量删除{{.Description}}记录 -// Author [piexlmax](https://github.com/piexlmax) +// Author [yourname](https://github.com/yourname) func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson}}s []string {{- if .AutoCreateResource }},deleted_by uint{{- end}}) (err error) { {{- if .AutoCreateResource }} err = {{$db}}.Transaction(func(tx *gorm.DB) error { @@ -65,21 +67,21 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ById } // Update{{.StructName}} 更新{{.Description}}记录 -// Author [piexlmax](https://github.com/piexlmax) +// Author [yourname](https://github.com/yourname) func ({{.Abbreviation}}Service *{{.StructName}}Service)Update{{.StructName}}({{.Abbreviation}} {{.Package}}.{{.StructName}}) (err error) { err = {{$db}}.Model(&{{.Package}}.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} = ?",{{.Abbreviation}}.{{.PrimaryField.FieldName}}).Updates(&{{.Abbreviation}}).Error return err } // Get{{.StructName}} 根据{{.PrimaryField.FieldJson}}获取{{.Description}}记录 -// Author [piexlmax](https://github.com/piexlmax) +// Author [yourname](https://github.com/yourname) func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}({{.PrimaryField.FieldJson}} string) ({{.Abbreviation}} {{.Package}}.{{.StructName}}, err error) { err = {{$db}}.Where("{{.PrimaryField.ColumnName}} = ?", {{.PrimaryField.FieldJson}}).First(&{{.Abbreviation}}).Error return } // Get{{.StructName}}InfoList 分页获取{{.Description}}记录 -// Author [piexlmax](https://github.com/piexlmax) +// Author [yourname](https://github.com/yourname) func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoList(info {{.Package}}Req.{{.StructName}}Search) (list []{{.Package}}.{{.StructName}}, total int64, err error) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) @@ -94,9 +96,13 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis {{- end }} {{- range .Fields}} {{- if .FieldSearchType}} - {{- if or (eq .FieldType "string") (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "richtext") }} + {{- if or (eq .FieldType "string") (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "richtext") (eq .FieldType "json") }} if info.{{.FieldName}} != "" { + {{- if or (eq .FieldType "enum") (eq .FieldType "string") }} db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + {{- else}} + // 数据类型为复杂类型,请根据业务需求自行实现复杂类型的查询业务 + {{- end}} } {{- else if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} if info.Start{{.FieldName}} != nil && info.End{{.FieldName}} != nil { @@ -133,7 +139,24 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis if limit != 0 { db = db.Limit(limit).Offset(offset) } - + err = db.Find(&{{.Abbreviation}}s).Error return {{.Abbreviation}}s, total, err } + +{{- if .HasDataSource }} +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}DataSource() (res map[string][]map[string]any, err error) { + res = make(map[string][]map[string]any) + {{range $key, $value := .DataSourceMap}} + {{$key}} := make([]map[string]any, 0) + {{$db}}.Table("{{$value.Table}}").Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) + res["{{$key}}"] = {{$key}} + {{- end }} + return +} +{{- end }} +{{- end }} +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}Public() { + // 此方法为获取数据源定义的数据 + // 请自行实现 +} diff --git a/server/resource/package/web/api/api.js.tpl b/server/resource/package/web/api/api.js.tpl new file mode 100644 index 0000000000..94085baa11 --- /dev/null +++ b/server/resource/package/web/api/api.js.tpl @@ -0,0 +1,130 @@ +import service from '@/utils/request' + +{{- if not .OnlyTemplate}} +// @Tags {{.StructName}} +// @Summary 创建{{.Description}} +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.{{.StructName}} true "创建{{.Description}}" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Router /{{.Abbreviation}}/create{{.StructName}} [post] +export const create{{.StructName}} = (data) => { + return service({ + url: '/{{.Abbreviation}}/create{{.StructName}}', + method: 'post', + data + }) +} + +// @Tags {{.StructName}} +// @Summary 删除{{.Description}} +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.{{.StructName}} true "删除{{.Description}}" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /{{.Abbreviation}}/delete{{.StructName}} [delete] +export const delete{{.StructName}} = (params) => { + return service({ + url: '/{{.Abbreviation}}/delete{{.StructName}}', + method: 'delete', + params + }) +} + +// @Tags {{.StructName}} +// @Summary 批量删除{{.Description}} +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.IdsReq true "批量删除{{.Description}}" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /{{.Abbreviation}}/delete{{.StructName}} [delete] +export const delete{{.StructName}}ByIds = (params) => { + return service({ + url: '/{{.Abbreviation}}/delete{{.StructName}}ByIds', + method: 'delete', + params + }) +} + +// @Tags {{.StructName}} +// @Summary 更新{{.Description}} +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.{{.StructName}} true "更新{{.Description}}" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}" +// @Router /{{.Abbreviation}}/update{{.StructName}} [put] +export const update{{.StructName}} = (data) => { + return service({ + url: '/{{.Abbreviation}}/update{{.StructName}}', + method: 'put', + data + }) +} + +// @Tags {{.StructName}} +// @Summary 用id查询{{.Description}} +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data query model.{{.StructName}} true "用id查询{{.Description}}" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}" +// @Router /{{.Abbreviation}}/find{{.StructName}} [get] +export const find{{.StructName}} = (params) => { + return service({ + url: '/{{.Abbreviation}}/find{{.StructName}}', + method: 'get', + params + }) +} + +// @Tags {{.StructName}} +// @Summary 分页获取{{.Description}}列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data query request.PageInfo true "分页获取{{.Description}}列表" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /{{.Abbreviation}}/get{{.StructName}}List [get] +export const get{{.StructName}}List = (params) => { + return service({ + url: '/{{.Abbreviation}}/get{{.StructName}}List', + method: 'get', + params + }) +} + +{{- if .HasDataSource}} +// @Tags {{.StructName}} +// @Summary 获取数据源 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}" +// @Router /{{.Abbreviation}}/find{{.StructName}}DataSource [get] +export const get{{.StructName}}DataSource = () => { + return service({ + url: '/{{.Abbreviation}}/get{{.StructName}}DataSource', + method: 'get', + }) +} +{{- end}} + +{{- end}} + +// @Tags {{.StructName}} +// @Summary 不需要鉴权的{{.Description}}接口 +// @accept application/json +// @Produce application/json +// @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表" +// @Success 200 {object} response.Response{data=object,msg=string} "获取成功" +// @Router /{{.Abbreviation}}/get{{.StructName}}Public [get] +export const get{{.StructName}}Public = () => { + return service({ + url: '/{{.Abbreviation}}/get{{.StructName}}Public', + method: 'get', + }) +} diff --git a/server/resource/autocode_template/web/form.vue.tpl b/server/resource/package/web/view/form.vue.tpl similarity index 82% rename from server/resource/autocode_template/web/form.vue.tpl rename to server/resource/package/web/view/form.vue.tpl index d49bb9e1dc..6ad1a4369b 100644 --- a/server/resource/autocode_template/web/form.vue.tpl +++ b/server/resource/package/web/view/form.vue.tpl @@ -1,9 +1,16 @@ +{{- if not .OnlyTemplate }}