diff --git a/server/api/v1/system/sys_export_template.go b/server/api/v1/system/sys_export_template.go index 9b83a17c43..0d61588ee3 100644 --- a/server/api/v1/system/sys_export_template.go +++ b/server/api/v1/system/sys_export_template.go @@ -3,6 +3,9 @@ package system import ( "fmt" "net/http" + "net/url" + "sync" + "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" @@ -15,6 +18,33 @@ import ( "go.uber.org/zap" ) +// 用于token一次性存储 +var ( + exportTokenCache = make(map[string]interface{}) + exportTokenExpiration = make(map[string]time.Time) + tokenMutex sync.RWMutex +) + +// 五分钟检测窗口过期 +func cleanupExpiredTokens() { + for { + time.Sleep(5 * time.Minute) + tokenMutex.Lock() + now := time.Now() + for token, expiry := range exportTokenExpiration { + if now.After(expiry) { + delete(exportTokenCache, token) + delete(exportTokenExpiration, token) + } + } + tokenMutex.Unlock() + } +} + +func init() { + go cleanupExpiredTokens() +} + type SysExportTemplateApi struct { } @@ -183,7 +213,7 @@ func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gi } } -// ExportExcel 导出表格 +// ExportExcel 导出表格token // @Tags SysExportTemplate // @Summary 导出表格 // @Security ApiKeyAuth @@ -192,16 +222,83 @@ func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gi // @Router /sysExportTemplate/exportExcel [get] func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) { templateID := c.Query("templateID") - queryParams := c.Request.URL.Query() if templateID == "" { response.FailWithMessage("模板ID不能为空", c) return } + + queryParams := c.Request.URL.Query() + + //创造一次性token + token := utils.RandomString(32) // 随机32位 + + // 记录本次请求参数 + exportParams := map[string]interface{}{ + "templateID": templateID, + "queryParams": queryParams, + } + + // 参数保留记录完成鉴权 + tokenMutex.Lock() + exportTokenCache[token] = exportParams + exportTokenExpiration[token] = time.Now().Add(30 * time.Minute) + tokenMutex.Unlock() + + // 生成一次性链接 + exportUrl := fmt.Sprintf("/sysExportTemplate/exportExcelByToken?token=%s", token) + response.OkWithData(exportUrl, c) +} + +// ExportExcelByToken 导出表格 +// @Tags ExportExcelByToken +// @Summary 导出表格 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Router /sysExportTemplate/exportExcelByToken [get] +func (sysExportTemplateApi *SysExportTemplateApi) ExportExcelByToken(c *gin.Context) { + token := c.Query("token") + if token == "" { + response.FailWithMessage("导出token不能为空", c) + return + } + + // 获取token并且从缓存中剔除 + tokenMutex.RLock() + exportParamsRaw, exists := exportTokenCache[token] + expiry, _ := exportTokenExpiration[token] + tokenMutex.RUnlock() + + if !exists || time.Now().After(expiry) { + global.GVA_LOG.Error("导出token无效或已过期!") + response.FailWithMessage("导出token无效或已过期", c) + return + } + + // 从token获取参数 + exportParams, ok := exportParamsRaw.(map[string]interface{}) + if !ok { + global.GVA_LOG.Error("解析导出参数失败!") + response.FailWithMessage("解析导出参数失败", c) + return + } + + // 获取导出参数 + templateID := exportParams["templateID"].(string) + queryParams := exportParams["queryParams"].(url.Values) + + // 清理一次性token + tokenMutex.Lock() + delete(exportTokenCache, token) + delete(exportTokenExpiration, token) + tokenMutex.Unlock() + + // 导出 if file, name, err := sysExportTemplateService.ExportExcel(templateID, queryParams); err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { - c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+utils.RandomString(6)+".xlsx")) // 对下载的文件重命名 + c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+utils.RandomString(6)+".xlsx")) c.Header("success", "true") c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes()) } @@ -213,18 +310,91 @@ func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) { // @Security ApiKeyAuth // @accept application/json // @Produce application/json -// @Router /sysExportTemplate/ExportTemplate [get] +// @Router /sysExportTemplate/exportTemplate [get] func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplate(c *gin.Context) { templateID := c.Query("templateID") if templateID == "" { response.FailWithMessage("模板ID不能为空", c) return } + + // 创造一次性token + token := utils.RandomString(32) // 随机32位 + + // 记录本次请求参数 + exportParams := map[string]interface{}{ + "templateID": templateID, + "isTemplate": true, + } + + // 参数保留记录完成鉴权 + tokenMutex.Lock() + exportTokenCache[token] = exportParams + exportTokenExpiration[token] = time.Now().Add(30 * time.Minute) + tokenMutex.Unlock() + + // 生成一次性链接 + exportUrl := fmt.Sprintf("/sysExportTemplate/exportTemplateByToken?token=%s", token) + response.OkWithData(exportUrl, c) +} + +// ExportTemplateByToken 通过token导出表格模板 +// @Tags ExportTemplateByToken +// @Summary 通过token导出表格模板 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Router /sysExportTemplate/exportTemplateByToken [get] +func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplateByToken(c *gin.Context) { + token := c.Query("token") + if token == "" { + response.FailWithMessage("导出token不能为空", c) + return + } + + // 获取token并且从缓存中剔除 + tokenMutex.RLock() + exportParamsRaw, exists := exportTokenCache[token] + expiry, _ := exportTokenExpiration[token] + tokenMutex.RUnlock() + + if !exists || time.Now().After(expiry) { + global.GVA_LOG.Error("导出token无效或已过期!") + response.FailWithMessage("导出token无效或已过期", c) + return + } + + // 从token获取参数 + exportParams, ok := exportParamsRaw.(map[string]interface{}) + if !ok { + global.GVA_LOG.Error("解析导出参数失败!") + response.FailWithMessage("解析导出参数失败", c) + return + } + + // 检查是否为模板导出 + isTemplate, _ := exportParams["isTemplate"].(bool) + if !isTemplate { + global.GVA_LOG.Error("token类型错误!") + response.FailWithMessage("token类型错误", c) + return + } + + // 获取导出参数 + templateID := exportParams["templateID"].(string) + + // 清理一次性token + tokenMutex.Lock() + delete(exportTokenCache, token) + delete(exportTokenExpiration, token) + tokenMutex.Unlock() + + // 导出模板 if file, name, err := sysExportTemplateService.ExportTemplate(templateID); err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败", c) } else { - c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+"模板.xlsx")) // 对下载的文件重命名 + c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+"模板.xlsx")) c.Header("success", "true") c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes()) } diff --git a/server/core/server.go b/server/core/server.go index a14649db8f..a257187466 100644 --- a/server/core/server.go +++ b/server/core/server.go @@ -39,7 +39,7 @@ func RunWindowsServer() { fmt.Printf(` 欢迎使用 gin-vue-admin - 当前版本:v2.7.9 + 当前版本:v2.8.0 加群方式:微信号:shouzi_1994 QQ群:470239250 项目地址:https://github.com/flipped-aurora/gin-vue-admin 插件市场:https://plugin.gin-vue-admin.com diff --git a/server/docs/docs.go b/server/docs/docs.go index f81a8275f7..9edb572639 100644 --- a/server/docs/docs.go +++ b/server/docs/docs.go @@ -9296,7 +9296,7 @@ const docTemplate = `{ // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ - Version: "v2.7.9", + Version: "v2.8.0", Host: "", BasePath: "", Schemes: []string{}, diff --git a/server/initialize/router.go b/server/initialize/router.go index b3f1786d78..c9a6102055 100644 --- a/server/initialize/router.go +++ b/server/initialize/router.go @@ -77,24 +77,24 @@ func Routers() *gin.Engine { } { - systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由 - systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由 - systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由 - systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由 - systemRouter.InitSystemRouter(PrivateGroup) // system相关路由 - systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由 - systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码 - systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由 - systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理 - systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史 - systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 - systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 - systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理 - systemRouter.InitSysExportTemplateRouter(PrivateGroup) // 导出模板 - systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理 - exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由 - exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 - exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类 + systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由 + systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由 + systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由 + systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由 + systemRouter.InitSystemRouter(PrivateGroup) // system相关路由 + systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由 + systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码 + systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由 + systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理 + systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史 + systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 + systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 + systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理 + systemRouter.InitSysExportTemplateRouter(PrivateGroup, PublicGroup) // 导出模板 + systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理 + exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由 + exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 + exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类 } diff --git a/server/main.go b/server/main.go index 5b071ec875..1f75bbe991 100644 --- a/server/main.go +++ b/server/main.go @@ -21,7 +21,7 @@ import ( // @Tag.Description 用户 // @title Gin-Vue-Admin Swagger API接口文档 -// @version v2.7.9 +// @version v2.8.0 // @description 使用gin+vue进行极速开发的全栈开发基础平台 // @securityDefinitions.apikey ApiKeyAuth // @in header diff --git a/server/resource/function/api.go.tpl b/server/resource/function/api.go.tpl index 4b5bd666ae..35a1cd5a66 100644 --- a/server/resource/function/api.go.tpl +++ b/server/resource/function/api.go.tpl @@ -7,8 +7,10 @@ // @Success 200 {object} response.Response{data=object,msg=string} "获取成功" // @Router /{{.Abbreviation}}/{{.Router}} [{{.Method}}] func (a *{{.Abbreviation}}) {{.FuncName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() // 请添加自己的业务逻辑 - err := service{{ .StructName }}.{{.FuncName}}() + err := service{{ .StructName }}.{{.FuncName}}(ctx) if err != nil { global.GVA_LOG.Error("失败!", zap.Error(err)) response.FailWithMessage("失败", c) @@ -28,8 +30,10 @@ func (a *{{.Abbreviation}}) {{.FuncName}}(c *gin.Context) { // @Success 200 {object} response.Response{data=object,msg=string} "成功" // @Router /{{.Abbreviation}}/{{.Router}} [{{.Method}}] func ({{.Abbreviation}}Api *{{.StructName}}Api){{.FuncName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() // 请添加自己的业务逻辑 - err := {{.Abbreviation}}Service.{{.FuncName}}() + err := {{.Abbreviation}}Service.{{.FuncName}}(ctx) if err != nil { global.GVA_LOG.Error("失败!", zap.Error(err)) response.FailWithMessage("失败", c) diff --git a/server/resource/function/server.go.tpl b/server/resource/function/server.go.tpl index 1c5191c4b4..7327604861 100644 --- a/server/resource/function/server.go.tpl +++ b/server/resource/function/server.go.tpl @@ -8,7 +8,7 @@ // {{.FuncName}} {{.FuncDesc}} // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) {{.FuncName}}() (err error) { +func (s *{{.Abbreviation}}) {{.FuncName}}(ctx context.Context) (err error) { db := {{$db}}.Model(&model.{{.StructName}}{}) return db.Error } @@ -17,9 +17,9 @@ func (s *{{.Abbreviation}}) {{.FuncName}}() (err error) { // {{.FuncName}} {{.FuncDesc}} // Author [yourname](https://github.com/yourname) -func ({{.Abbreviation}}Service *{{.StructName}}Service){{.FuncName}}() (err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service){{.FuncName}}(ctx context.Context) (err error) { // 请在这里实现自己的业务逻辑 db := {{$db}}.Model(&{{.Package}}.{{.StructName}}{}) return db.Error } -{{end}} \ No newline at end of file +{{end}} diff --git a/server/resource/package/server/api/api.go.tpl b/server/resource/package/server/api/api.go.tpl index 9495e88e92..528487fd67 100644 --- a/server/resource/package/server/api/api.go.tpl +++ b/server/resource/package/server/api/api.go.tpl @@ -33,6 +33,9 @@ type {{.StructName}}Api struct {} // @Success 200 {object} response.Response{msg=string} "创建成功" // @Router /{{.Abbreviation}}/create{{.StructName}} [post] func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + var {{.Abbreviation}} {{.Package}}.{{.StructName}} err := c.ShouldBindJSON(&{{.Abbreviation}}) if err != nil { @@ -42,7 +45,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con {{- if .AutoCreateResource }} {{.Abbreviation}}.CreatedBy = utils.GetUserID(c) {{- end }} - err = {{.Abbreviation}}Service.Create{{.StructName}}(&{{.Abbreviation}}) + err = {{.Abbreviation}}Service.Create{{.StructName}}(ctx,&{{.Abbreviation}}) if err != nil { global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败:" + err.Error(), c) @@ -61,11 +64,14 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con // @Success 200 {object} response.Response{msg=string} "删除成功" // @Router /{{.Abbreviation}}/delete{{.StructName}} [delete] func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + {{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}") {{- if .AutoCreateResource }} userID := utils.GetUserID(c) {{- end }} - err := {{.Abbreviation}}Service.Delete{{.StructName}}({{.PrimaryField.FieldJson}} {{- if .AutoCreateResource -}},userID{{- end -}}) + err := {{.Abbreviation}}Service.Delete{{.StructName}}(ctx,{{.PrimaryField.FieldJson}} {{- if .AutoCreateResource -}},userID{{- end -}}) if err != nil { global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败:" + err.Error(), c) @@ -83,11 +89,14 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}(c *gin.Con // @Success 200 {object} response.Response{msg=string} "批量删除成功" // @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete] func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + {{.PrimaryField.FieldJson}}s := c.QueryArray("{{.PrimaryField.FieldJson}}s[]") {{- if .AutoCreateResource }} userID := utils.GetUserID(c) {{- end }} - err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }},userID{{- end }}) + err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds(ctx,{{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }},userID{{- end }}) if err != nil { global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) response.FailWithMessage("批量删除失败:" + err.Error(), c) @@ -106,6 +115,9 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gi // @Success 200 {object} response.Response{msg=string} "更新成功" // @Router /{{.Abbreviation}}/update{{.StructName}} [put] func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Context) { + // 从ctx获取标准context进行业务行为 + ctx := c.Request.Context() + var {{.Abbreviation}} {{.Package}}.{{.StructName}} err := c.ShouldBindJSON(&{{.Abbreviation}}) if err != nil { @@ -115,7 +127,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Con {{- if .AutoCreateResource }} {{.Abbreviation}}.UpdatedBy = utils.GetUserID(c) {{- end }} - err = {{.Abbreviation}}Service.Update{{.StructName}}({{.Abbreviation}}) + err = {{.Abbreviation}}Service.Update{{.StructName}}(ctx,{{.Abbreviation}}) if err != nil { global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败:" + err.Error(), c) @@ -134,8 +146,11 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Update{{.StructName}}(c *gin.Con // @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) { + // 创建业务用Context + ctx := c.Request.Context() + {{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}") - re{{.Abbreviation}}, err := {{.Abbreviation}}Service.Get{{.StructName}}({{.PrimaryField.FieldJson}}) + re{{.Abbreviation}}, err := {{.Abbreviation}}Service.Get{{.StructName}}(ctx,{{.PrimaryField.FieldJson}}) if err != nil { global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败:" + err.Error(), c) @@ -154,7 +169,10 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Find{{.StructName}}(c *gin.Conte // @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) { - list, err := {{.Abbreviation}}Service.Get{{.StructName}}InfoList() + // 创建业务用Context + ctx := c.Request.Context() + + list, err := {{.Abbreviation}}Service.Get{{.StructName}}InfoList(ctx) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败:" + err.Error(), c) @@ -173,13 +191,16 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Co // @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) { + // 创建业务用Context + ctx := c.Request.Context() + var pageInfo {{.Package}}Req.{{.StructName}}Search err := c.ShouldBindQuery(&pageInfo) if err != nil { response.FailWithMessage(err.Error(), c) return } - list, total, err := {{.Abbreviation}}Service.Get{{.StructName}}InfoList(pageInfo) + list, total, err := {{.Abbreviation}}Service.Get{{.StructName}}InfoList(ctx,pageInfo) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败:" + err.Error(), c) @@ -203,8 +224,11 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}List(c *gin.Co // @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) { + // 创建业务用Context + ctx := c.Request.Context() + // 此接口为获取数据源定义的数据 - dataSource, err := {{.Abbreviation}}Service.Get{{.StructName}}DataSource() + dataSource, err := {{.Abbreviation}}Service.Get{{.StructName}}DataSource(ctx) if err != nil { global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败:" + err.Error(), c) @@ -224,9 +248,12 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Get{{.StructName}}DataSource(c * // @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) { + // 创建业务用Context + ctx := c.Request.Context() + // 此接口不需要鉴权 // 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑 - {{.Abbreviation}}Service.Get{{.StructName}}Public() + {{.Abbreviation}}Service.Get{{.StructName}}Public(ctx) response.OkWithDetailed(gin.H{ "info": "不需要鉴权的{{.Description}}接口信息", }, "获取成功", c) diff --git a/server/resource/package/server/service/service.go.tpl b/server/resource/package/server/service/service.go.tpl index 0d6e6a83c9..d0cbb4f816 100644 --- a/server/resource/package/server/service/service.go.tpl +++ b/server/resource/package/server/service/service.go.tpl @@ -58,6 +58,7 @@ package {{.Package}} import ( {{- if not .OnlyTemplate }} + "context" "{{.Module}}/global" "{{.Module}}/model/{{.Package}}" {{- if not .IsTree}} @@ -77,14 +78,14 @@ type {{.StructName}}Service struct {} {{- if not .OnlyTemplate }} // Create{{.StructName}} 创建{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func ({{.Abbreviation}}Service *{{.StructName}}Service) Create{{.StructName}}({{.Abbreviation}} *{{.Package}}.{{.StructName}}) (err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service) Create{{.StructName}}(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) (err error) { err = {{$db}}.Create({{.Abbreviation}}).Error return err } // Delete{{.StructName}} 删除{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}({{.PrimaryField.FieldJson}} string{{- if .AutoCreateResource -}},userID uint{{- end -}}) (err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}(ctx context.Context, {{.PrimaryField.FieldJson}} string{{- if .AutoCreateResource -}},userID uint{{- end -}}) (err error) { {{- if .IsTree }} var count int64 err = {{$db}}.Find(&{{.Package}}.{{.StructName}}{},"parent_id = ?",{{.PrimaryField.FieldJson}}).Count(&count).Error @@ -114,7 +115,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}({{. // Delete{{.StructName}}ByIds 批量删除{{.Description}}记录 // 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) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ByIds(ctx context.Context, {{.PrimaryField.FieldJson}}s []string {{- if .AutoCreateResource }},deleted_by uint{{- end}}) (err error) { {{- if .AutoCreateResource }} err = {{$db}}.Transaction(func(tx *gorm.DB) error { if err := tx.Model(&{{.Package}}.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} in ?", {{.PrimaryField.FieldJson}}s).Update("deleted_by", deleted_by).Error; err != nil { @@ -133,14 +134,14 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ById // Update{{.StructName}} 更新{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func ({{.Abbreviation}}Service *{{.StructName}}Service)Update{{.StructName}}({{.Abbreviation}} {{.Package}}.{{.StructName}}) (err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Update{{.StructName}}(ctx context.Context, {{.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 [yourname](https://github.com/yourname) -func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}({{.PrimaryField.FieldJson}} string) ({{.Abbreviation}} {{.Package}}.{{.StructName}}, err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}(ctx context.Context, {{.PrimaryField.FieldJson}} string) ({{.Abbreviation}} {{.Package}}.{{.StructName}}, err error) { err = {{$db}}.Where("{{.PrimaryField.ColumnName}} = ?", {{.PrimaryField.FieldJson}}).First(&{{.Abbreviation}}).Error return } @@ -149,7 +150,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}({{.Pri {{- if .IsTree }} // Get{{.StructName}}InfoList 分页获取{{.Description}}记录,Tree模式下不添加分页和搜索 // Author [yourname](https://github.com/yourname) -func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoList() (list []*{{.Package}}.{{.StructName}},err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoList(ctx context.Context) (list []*{{.Package}}.{{.StructName}},err error) { // 创建db db := {{$db}}.Model(&{{.Package}}.{{.StructName}}{}) var {{.Abbreviation}}s []*{{.Package}}.{{.StructName}} @@ -161,7 +162,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis {{- else }} // Get{{.StructName}}InfoList 分页获取{{.Description}}记录 // 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) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoList(ctx context.Context, info {{.Package}}Req.{{.StructName}}Search) (list []{{.Package}}.{{.StructName}}, total int64, err error) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) // 创建db @@ -226,7 +227,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis {{- end }} {{- if .HasDataSource }} -func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}DataSource() (res map[string][]map[string]any, err error) { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}DataSource(ctx context.Context) (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) @@ -243,7 +244,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}DataSou } {{- end }} {{- end }} -func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}Public() { +func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}Public(ctx context.Context) { // 此方法为获取数据源定义的数据 // 请自行实现 } diff --git a/server/resource/package/web/view/table.vue.tpl b/server/resource/package/web/view/table.vue.tpl index 2d7b29949b..c6d5f55b15 100644 --- a/server/resource/package/web/view/table.vue.tpl +++ b/server/resource/package/web/view/table.vue.tpl @@ -131,7 +131,7 @@ @@ -607,7 +607,7 @@ getDataSourceFunc() @@ -1297,11 +1297,6 @@ const enterDialog = async () => { } }) } -{{if .HasFile }} -const downloadFile = (url) => { - window.open(getUrl(url), '_blank') -} -{{end}} const detailFrom = ref({}) diff --git a/server/resource/plugin/server/api/api.go.template b/server/resource/plugin/server/api/api.go.template index 683824081c..e69ae8246c 100644 --- a/server/resource/plugin/server/api/api.go.template +++ b/server/resource/plugin/server/api/api.go.template @@ -33,6 +33,9 @@ type {{.Abbreviation}} struct {} // @Success 200 {object} response.Response{msg=string} "创建成功" // @Router /{{.Abbreviation}}/create{{.StructName}} [post] func (a *{{.Abbreviation}}) Create{{.StructName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + var info model.{{.StructName}} err := c.ShouldBindJSON(&info) if err != nil { @@ -42,7 +45,7 @@ func (a *{{.Abbreviation}}) Create{{.StructName}}(c *gin.Context) { {{- if .AutoCreateResource }} info.CreatedBy = utils.GetUserID(c) {{- end }} - err = service{{ .StructName }}.Create{{.StructName}}(&info) + err = service{{ .StructName }}.Create{{.StructName}}(ctx,&info) if err != nil { global.GVA_LOG.Error("创建失败!", zap.Error(err)) response.FailWithMessage("创建失败:" + err.Error(), c) @@ -61,11 +64,14 @@ func (a *{{.Abbreviation}}) Create{{.StructName}}(c *gin.Context) { // @Success 200 {object} response.Response{msg=string} "删除成功" // @Router /{{.Abbreviation}}/delete{{.StructName}} [delete] func (a *{{.Abbreviation}}) Delete{{.StructName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + {{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}") {{- if .AutoCreateResource }} userID := utils.GetUserID(c) {{- end }} - err := service{{ .StructName }}.Delete{{.StructName}}({{.PrimaryField.FieldJson}} {{- if .AutoCreateResource -}},userID{{- end -}}) + err := service{{ .StructName }}.Delete{{.StructName}}(ctx,{{.PrimaryField.FieldJson}} {{- if .AutoCreateResource -}},userID{{- end -}}) if err != nil { global.GVA_LOG.Error("删除失败!", zap.Error(err)) response.FailWithMessage("删除失败:" + err.Error(), c) @@ -83,11 +89,14 @@ func (a *{{.Abbreviation}}) Delete{{.StructName}}(c *gin.Context) { // @Success 200 {object} response.Response{msg=string} "批量删除成功" // @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete] func (a *{{.Abbreviation}}) Delete{{.StructName}}ByIds(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + {{.PrimaryField.FieldJson}}s := c.QueryArray("{{.PrimaryField.FieldJson}}s[]") {{- if .AutoCreateResource }} userID := utils.GetUserID(c) {{- end }} - err := service{{ .StructName }}.Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }},userID{{- end }}) + err := service{{ .StructName }}.Delete{{.StructName}}ByIds(ctx,{{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }},userID{{- end }}) if err != nil { global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) response.FailWithMessage("批量删除失败:" + err.Error(), c) @@ -106,6 +115,9 @@ func (a *{{.Abbreviation}}) Delete{{.StructName}}ByIds(c *gin.Context) { // @Success 200 {object} response.Response{msg=string} "更新成功" // @Router /{{.Abbreviation}}/update{{.StructName}} [put] func (a *{{.Abbreviation}}) Update{{.StructName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + var info model.{{.StructName}} err := c.ShouldBindJSON(&info) if err != nil { @@ -115,7 +127,7 @@ func (a *{{.Abbreviation}}) Update{{.StructName}}(c *gin.Context) { {{- if .AutoCreateResource }} info.UpdatedBy = utils.GetUserID(c) {{- end }} - err = service{{ .StructName }}.Update{{.StructName}}(info) + err = service{{ .StructName }}.Update{{.StructName}}(ctx,info) if err != nil { global.GVA_LOG.Error("更新失败!", zap.Error(err)) response.FailWithMessage("更新失败:" + err.Error(), c) @@ -134,8 +146,11 @@ func (a *{{.Abbreviation}}) Update{{.StructName}}(c *gin.Context) { // @Success 200 {object} response.Response{data=model.{{.StructName}},msg=string} "查询成功" // @Router /{{.Abbreviation}}/find{{.StructName}} [get] func (a *{{.Abbreviation}}) Find{{.StructName}}(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + {{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}") - re{{.Abbreviation}}, err := service{{ .StructName }}.Get{{.StructName}}({{.PrimaryField.FieldJson}}) + re{{.Abbreviation}}, err := service{{ .StructName }}.Get{{.StructName}}(ctx,{{.PrimaryField.FieldJson}}) if err != nil { global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败:" + err.Error(), c) @@ -154,7 +169,10 @@ func (a *{{.Abbreviation}}) Find{{.StructName}}(c *gin.Context) { // @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功" // @Router /{{.Abbreviation}}/get{{.StructName}}List [get] func (a *{{.Abbreviation}}) Get{{.StructName}}List(c *gin.Context) { - list, err := service{{ .StructName }}.Get{{.StructName}}InfoList() + // 创建业务用Context + ctx := c.Request.Context() + + list, err := service{{ .StructName }}.Get{{.StructName}}InfoList(ctx) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败:" + err.Error(), c) @@ -173,13 +191,16 @@ func (a *{{.Abbreviation}}) Get{{.StructName}}List(c *gin.Context) { // @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功" // @Router /{{.Abbreviation}}/get{{.StructName}}List [get] func (a *{{.Abbreviation}}) Get{{.StructName}}List(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + var pageInfo request.{{.StructName}}Search err := c.ShouldBindQuery(&pageInfo) if err != nil { response.FailWithMessage(err.Error(), c) return } - list, total, err := service{{ .StructName }}.Get{{.StructName}}InfoList(pageInfo) + list, total, err := service{{ .StructName }}.Get{{.StructName}}InfoList(ctx,pageInfo) if err != nil { global.GVA_LOG.Error("获取失败!", zap.Error(err)) response.FailWithMessage("获取失败:" + err.Error(), c) @@ -203,8 +224,11 @@ func (a *{{.Abbreviation}}) Get{{.StructName}}List(c *gin.Context) { // @Success 200 {object} response.Response{data=object,msg=string} "查询成功" // @Router /{{.Abbreviation}}/get{{.StructName}}DataSource [get] func (a *{{.Abbreviation}}) Get{{.StructName}}DataSource(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + // 此接口为获取数据源定义的数据 - dataSource, err := service{{ .StructName }}.Get{{.StructName}}DataSource() + dataSource, err := service{{ .StructName }}.Get{{.StructName}}DataSource(ctx) if err != nil { global.GVA_LOG.Error("查询失败!", zap.Error(err)) response.FailWithMessage("查询失败:" + err.Error(), c) @@ -222,7 +246,10 @@ func (a *{{.Abbreviation}}) Get{{.StructName}}DataSource(c *gin.Context) { // @Success 200 {object} response.Response{data=object,msg=string} "获取成功" // @Router /{{.Abbreviation}}/get{{.StructName}}Public [get] func (a *{{.Abbreviation}}) Get{{.StructName}}Public(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + // 此接口不需要鉴权 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑 - service{{ .StructName }}.Get{{.StructName}}Public() + service{{ .StructName }}.Get{{.StructName}}Public(ctx) response.OkWithDetailed(gin.H{"info": "不需要鉴权的{{.Description}}接口信息"}, "获取成功", c) } diff --git a/server/resource/plugin/server/service/service.go.template b/server/resource/plugin/server/service/service.go.template index b0da0fa0b8..6d11da1d0a 100644 --- a/server/resource/plugin/server/service/service.go.template +++ b/server/resource/plugin/server/service/service.go.template @@ -58,6 +58,7 @@ package service import ( {{- if not .OnlyTemplate }} + "context" "{{.Module}}/global" "{{.Module}}/plugin/{{.Package}}/model" {{- if not .IsTree }} @@ -87,14 +88,14 @@ type {{.Abbreviation}} struct {} {{- if not .OnlyTemplate }} // Create{{.StructName}} 创建{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Create{{.StructName}}({{.Abbreviation}} *model.{{.StructName}}) (err error) { +func (s *{{.Abbreviation}}) Create{{.StructName}}(ctx context.Context, {{.Abbreviation}} *model.{{.StructName}}) (err error) { err = {{$db}}.Create({{.Abbreviation}}).Error return err } // Delete{{.StructName}} 删除{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Delete{{.StructName}}({{.PrimaryField.FieldJson}} string{{- if .AutoCreateResource -}},userID uint{{- end -}}) (err error) { +func (s *{{.Abbreviation}}) Delete{{.StructName}}(ctx context.Context, {{.PrimaryField.FieldJson}} string{{- if .AutoCreateResource -}},userID uint{{- end -}}) (err error) { {{- if .IsTree }} var count int64 @@ -125,7 +126,7 @@ func (s *{{.Abbreviation}}) Delete{{.StructName}}({{.PrimaryField.FieldJson}} st // Delete{{.StructName}}ByIds 批量删除{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson}}s []string {{- if .AutoCreateResource }},deleted_by uint{{- end}}) (err error) { +func (s *{{.Abbreviation}}) Delete{{.StructName}}ByIds(ctx context.Context, {{.PrimaryField.FieldJson}}s []string {{- if .AutoCreateResource }},deleted_by uint{{- end}}) (err error) { {{- if .AutoCreateResource }} err = {{$db}}.Transaction(func(tx *gorm.DB) error { if err := tx.Model(&model.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} in ?", {{.PrimaryField.FieldJson}}s).Update("deleted_by", deleted_by).Error; err != nil { @@ -144,14 +145,14 @@ func (s *{{.Abbreviation}}) Delete{{.StructName}}ByIds({{.PrimaryField.FieldJson // Update{{.StructName}} 更新{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Update{{.StructName}}({{.Abbreviation}} model.{{.StructName}}) (err error) { +func (s *{{.Abbreviation}}) Update{{.StructName}}(ctx context.Context, {{.Abbreviation}} model.{{.StructName}}) (err error) { err = {{$db}}.Model(&model.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} = ?",{{.Abbreviation}}.{{.PrimaryField.FieldName}}).Updates(&{{.Abbreviation}}).Error return err } // Get{{.StructName}} 根据{{.PrimaryField.FieldJson}}获取{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Get{{.StructName}}({{.PrimaryField.FieldJson}} string) ({{.Abbreviation}} model.{{.StructName}}, err error) { +func (s *{{.Abbreviation}}) Get{{.StructName}}(ctx context.Context, {{.PrimaryField.FieldJson}} string) ({{.Abbreviation}} model.{{.StructName}}, err error) { err = {{$db}}.Where("{{.PrimaryField.ColumnName}} = ?", {{.PrimaryField.FieldJson}}).First(&{{.Abbreviation}}).Error return } @@ -160,7 +161,7 @@ func (s *{{.Abbreviation}}) Get{{.StructName}}({{.PrimaryField.FieldJson}} strin {{- if .IsTree }} // Get{{.StructName}}InfoList 分页获取{{.Description}}记录,Tree模式下不添加分页和搜索 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList() (list []*model.{{.StructName}},err error) { +func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList(ctx context.Context) (list []*model.{{.StructName}},err error) { // 创建db db := {{$db}}.Model(&model.{{.StructName}}{}) var {{.Abbreviation}}s []*model.{{.StructName}} @@ -172,7 +173,7 @@ func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList() (list []*model.{{.Struc {{- else }} // Get{{.StructName}}InfoList 分页获取{{.Description}}记录 // Author [yourname](https://github.com/yourname) -func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList(info request.{{.StructName}}Search) (list []model.{{.StructName}}, total int64, err error) { +func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList(ctx context.Context, info request.{{.StructName}}Search) (list []model.{{.StructName}}, total int64, err error) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) // 创建db @@ -234,7 +235,7 @@ func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList(info request.{{.StructNam } {{- end }} {{- if .HasDataSource }} -func (s *{{.Abbreviation}})Get{{.StructName}}DataSource() (res map[string][]map[string]any, err error) { +func (s *{{.Abbreviation}})Get{{.StructName}}DataSource(ctx context.Context) (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) @@ -252,7 +253,7 @@ func (s *{{.Abbreviation}})Get{{.StructName}}DataSource() (res map[string][]map[ {{- end }} {{- end }} -func (s *{{.Abbreviation}})Get{{.StructName}}Public() { +func (s *{{.Abbreviation}})Get{{.StructName}}Public(ctx context.Context) { } {{- end }} diff --git a/server/resource/plugin/web/view/view.vue.template b/server/resource/plugin/web/view/view.vue.template index 88785002c1..aa13244264 100644 --- a/server/resource/plugin/web/view/view.vue.template +++ b/server/resource/plugin/web/view/view.vue.template @@ -131,7 +131,7 @@ @@ -607,7 +607,7 @@ getDataSourceFunc() @@ -1295,11 +1295,6 @@ const enterDialog = async () => { } }) } -{{if .HasFile }} -const downloadFile = (url) => { - window.open(getUrl(url), '_blank') -} -{{end}} const detailFrom = ref({}) diff --git a/server/router/system/sys_export_template.go b/server/router/system/sys_export_template.go index de4e1fa66b..e7fd5beef0 100644 --- a/server/router/system/sys_export_template.go +++ b/server/router/system/sys_export_template.go @@ -9,9 +9,11 @@ type SysExportTemplateRouter struct { } // InitSysExportTemplateRouter 初始化 导出模板 路由信息 -func (s *SysExportTemplateRouter) InitSysExportTemplateRouter(Router *gin.RouterGroup) { +func (s *SysExportTemplateRouter) InitSysExportTemplateRouter(Router *gin.RouterGroup, pubRouter *gin.RouterGroup) { sysExportTemplateRouter := Router.Group("sysExportTemplate").Use(middleware.OperationRecord()) sysExportTemplateRouterWithoutRecord := Router.Group("sysExportTemplate") + sysExportTemplateRouterWithoutAuth := pubRouter.Group("sysExportTemplate") + { sysExportTemplateRouter.POST("createSysExportTemplate", exportTemplateApi.CreateSysExportTemplate) // 新建导出模板 sysExportTemplateRouter.DELETE("deleteSysExportTemplate", exportTemplateApi.DeleteSysExportTemplate) // 删除导出模板 @@ -22,7 +24,11 @@ func (s *SysExportTemplateRouter) InitSysExportTemplateRouter(Router *gin.Router { sysExportTemplateRouterWithoutRecord.GET("findSysExportTemplate", exportTemplateApi.FindSysExportTemplate) // 根据ID获取导出模板 sysExportTemplateRouterWithoutRecord.GET("getSysExportTemplateList", exportTemplateApi.GetSysExportTemplateList) // 获取导出模板列表 - sysExportTemplateRouterWithoutRecord.GET("exportExcel", exportTemplateApi.ExportExcel) // 导出表格 + sysExportTemplateRouterWithoutRecord.GET("exportExcel", exportTemplateApi.ExportExcel) // 获取导出token sysExportTemplateRouterWithoutRecord.GET("exportTemplate", exportTemplateApi.ExportTemplate) // 导出表格模板 } + { + sysExportTemplateRouterWithoutAuth.GET("exportExcelByToken", exportTemplateApi.ExportExcelByToken) // 通过token导出表格 + sysExportTemplateRouterWithoutAuth.GET("exportTemplateByToken", exportTemplateApi.ExportTemplateByToken) // 通过token导出模板 + } } diff --git a/server/utils/claims.go b/server/utils/claims.go index 8c3fd4b462..2a6308e8a1 100644 --- a/server/utils/claims.go +++ b/server/utils/claims.go @@ -40,10 +40,10 @@ func SetToken(c *gin.Context, token string, maxAge int) { } func GetToken(c *gin.Context) string { - token, _ := c.Cookie("x-token") + token := c.Request.Header.Get("x-token") if token == "" { j := NewJWT() - token = c.Request.Header.Get("x-token") + token, _ = c.Cookie("x-token") claims, err := j.ParseToken(token) if err != nil { global.GVA_LOG.Error("重新写入cookie token失败,未能成功解析token,请检查请求头是否存在x-token且claims是否为规定结构") diff --git a/web/package.json b/web/package.json index 9c26581ec6..82bf3619d9 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "gin-vue-admin", - "version": "2.7.9", + "version": "2.8.0", "private": true, "scripts": { "serve": "node openDocument.js && vite --host --mode development", diff --git a/web/src/api/exportTemplate.js b/web/src/api/exportTemplate.js index 5b7b278275..9f8729b018 100644 --- a/web/src/api/exportTemplate.js +++ b/web/src/api/exportTemplate.js @@ -95,3 +95,34 @@ export const getSysExportTemplateList = (params) => { params }) } + + +// ExportExcel 导出表格token +// @Tags SysExportTemplate +// @Summary 导出表格 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Router /sysExportTemplate/exportExcel [get] +export const exportExcel = (params) => { + return service({ + url: '/sysExportTemplate/exportExcel', + method: 'get', + params + }) +} + +// ExportTemplate 导出表格模板 +// @Tags SysExportTemplate +// @Summary 导出表格模板 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Router /sysExportTemplate/exportTemplate [get] +export const exportTemplate = (params) => { + return service({ + url: '/sysExportTemplate/exportTemplate', + method: 'get', + params + }) +} diff --git a/web/src/components/exportExcel/exportExcel.vue b/web/src/components/exportExcel/exportExcel.vue index 23f380605f..6c1189e12a 100644 --- a/web/src/components/exportExcel/exportExcel.vue +++ b/web/src/components/exportExcel/exportExcel.vue @@ -5,7 +5,8 @@ diff --git a/web/src/components/exportExcel/exportTemplate.vue b/web/src/components/exportExcel/exportTemplate.vue index 0a69fddad0..dd77f95eff 100644 --- a/web/src/components/exportExcel/exportTemplate.vue +++ b/web/src/components/exportExcel/exportTemplate.vue @@ -1,10 +1,13 @@ diff --git a/web/src/components/exportExcel/importExcel.vue b/web/src/components/exportExcel/importExcel.vue index ebf886efd1..cd3a7d9469 100644 --- a/web/src/components/exportExcel/importExcel.vue +++ b/web/src/components/exportExcel/importExcel.vue @@ -4,6 +4,7 @@ :show-file-list="false" :on-success="handleSuccess" :multiple="false" + :headers="{'x-token': token}" > 导入 @@ -11,6 +12,7 @@