diff --git a/server/api/v1/exa_excel.go b/server/api/v1/exa_excel.go new file mode 100644 index 00000000..2aa70db5 --- /dev/null +++ b/server/api/v1/exa_excel.go @@ -0,0 +1,99 @@ +package v1 + +import ( + "gin-vue-admin/global" + "gin-vue-admin/model" + "gin-vue-admin/model/response" + "gin-vue-admin/service" + "gin-vue-admin/utils" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +// /excel/importExcel 接口,与upload接口作用类似,只是把文件存到resource/excel目录下,用于导入Excel时存放Excel文件(ExcelImport.xlsx) +// /excel/loadExcel接口,用于读取resource/excel目录下的文件((ExcelImport.xlsx)并加载为[]model.SysBaseMenu类型的示例数据 +// /excel/exportExcel 接口,用于读取前端传来的tableData,生成Excel文件并返回 +// /excel/downloadTemplate 接口,用于下载resource/excel目录下的 ExcelTemplate.xlsx 文件,作为导入的模板 + +// @Tags excel +// @Summary 导出Excel +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/octet-stream +// @Param data body model.ExcelInfo true "导出Excel文件信息" +// @Success 200 +// @Router /excel/exportExcel [post] +func ExportExcel(c *gin.Context) { + var excelInfo model.ExcelInfo + _ = c.ShouldBindJSON(&excelInfo) + filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName + err := service.ParseInfoList2Excel(excelInfo.InfoList, filePath) + if err != nil { + global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err)) + response.FailWithMessage("转换Excel失败", c) + return + } + c.Writer.Header().Add("success", "true") + c.File(filePath) +} + +// @Tags excel +// @Summary 导入Excel文件 +// @Security ApiKeyAuth +// @accept multipart/form-data +// @Produce application/json +// @Param file formData file true "导入Excel文件" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}" +// @Router /excel/importExcel [post] +func ImportExcel(c *gin.Context) { + _, header, err := c.Request.FormFile("file") + if err != nil { + global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err)) + response.FailWithMessage("接收文件失败", c) + return + } + _ = c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx") + response.OkWithMessage("导入成功", c) +} + +// @Tags excel +// @Summary 加载Excel数据 +// @Security ApiKeyAuth +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"加载数据成功"}" +// @Router /excel/loadExcel [get] +func LoadExcel(c *gin.Context) { + menus, err := service.ParseExcel2InfoList() + if err != nil { + global.GVA_LOG.Error("加载数据失败", zap.Any("err", err)) + response.FailWithMessage("加载数据失败", c) + return + } + response.OkWithDetailed(response.PageResult{ + List: menus, + Total: int64(len(menus)), + Page: 1, + PageSize: 999, + }, "加载数据成功", c) +} + +// @Tags excel +// @Summary 下载模板 +// @Security ApiKeyAuth +// @accept multipart/form-data +// @Produce application/json +// @Param fileName query fileName true "模板名称" +// @Success 200 +// @Router /excel/downloadTemplate [get] +func DownloadTemplate(c *gin.Context) { + fileName := c.Query("fileName") + filePath := global.GVA_CONFIG.Excel.Dir + fileName + ok, err := utils.PathExists(filePath) + if !ok || err != nil { + global.GVA_LOG.Error("文件不存在", zap.Any("err", err)) + response.FailWithMessage("文件不存在", c) + return + } + c.Writer.Header().Add("success", "true") + c.File(filePath) +} diff --git a/server/api/v1/exa_file_upload_download.go b/server/api/v1/exa_file_upload_download.go index b3e6427f..ab007488 100644 --- a/server/api/v1/exa_file_upload_download.go +++ b/server/api/v1/exa_file_upload_download.go @@ -6,7 +6,6 @@ import ( "gin-vue-admin/model/request" "gin-vue-admin/model/response" "gin-vue-admin/service" - "gin-vue-admin/utils" "github.com/gin-gonic/gin" "go.uber.org/zap" ) @@ -76,89 +75,6 @@ func GetFileList(c *gin.Context) { Total: total, Page: pageInfo.Page, PageSize: pageInfo.PageSize, - },"获取成功", c) + }, "获取成功", c) } } - -// @Tags ExaFileUploadAndDownload -// @Summary 导出Excel -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/octet-stream -// @Param data body request.ExcelInfo true "导出Excel文件信息" -// @Success 200 -// @Router /fileUploadAndDownload/exportExcel [post] -func ExportExcel(c *gin.Context) { - var excelInfo request.ExcelInfo - c.ShouldBindJSON(&excelInfo) - filePath := global.GVA_CONFIG.Excel.Dir+excelInfo.FileName - err := service.ParseInfoList2Excel(excelInfo.InfoList, filePath) - if err != nil { - global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err)) - response.FailWithMessage("转换Excel失败", c) - return - } - c.Writer.Header().Add("success", "true") - c.File(filePath) -} - -// @Tags ExaFileUploadAndDownload -// @Summary 导入Excel文件 -// @Security ApiKeyAuth -// @accept multipart/form-data -// @Produce application/json -// @Param file formData file true "导入Excel文件" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}" -// @Router /fileUploadAndDownload/importExcel [post] -func ImportExcel(c *gin.Context) { - _, header, err := c.Request.FormFile("file") - if err != nil { - global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err)) - response.FailWithMessage("接收文件失败", c) - return - } - c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx") - response.OkWithMessage("导入成功", c) -} - -// @Tags ExaFileUploadAndDownload -// @Summary 加载Excel数据 -// @Security ApiKeyAuth -// @Produce application/json -// @Success 200 {string} string "{"success":true,"data":{},"msg":"加载数据成功"}" -// @Router /fileUploadAndDownload/loadExcel [get] -func LoadExcel(c *gin.Context) { - menus, err := service.ParseExcel2InfoList() - if err != nil { - global.GVA_LOG.Error("加载数据失败", zap.Any("err", err)) - response.FailWithMessage("加载数据失败", c) - return - } - response.OkWithDetailed(response.PageResult{ - List: menus, - Total: int64(len(menus)), - Page: 1, - PageSize: 999, - },"加载数据成功", c) -} - -// @Tags ExaFileUploadAndDownload -// @Summary 下载模板 -// @Security ApiKeyAuth -// @accept multipart/form-data -// @Produce application/json -// @Param fileName query fileName true "模板名称" -// @Success 200 -// @Router /fileUploadAndDownload/downloadTemplate [get] -func DownloadTemplate(c *gin.Context) { - fileName := c.Query("fileName") - filePath := global.GVA_CONFIG.Excel.Dir+fileName - ok, err := utils.PathExists(filePath) - if !ok || err != nil { - global.GVA_LOG.Error("文件不存在", zap.Any("err", err)) - response.FailWithMessage("文件不存在", c) - return - } - c.Writer.Header().Add("success", "true") - c.File(filePath) -} \ No newline at end of file diff --git a/server/cmd/information/system/api.go b/server/cmd/information/system/api.go index 0461d6e8..27c430dc 100644 --- a/server/cmd/information/system/api.go +++ b/server/cmd/information/system/api.go @@ -93,6 +93,10 @@ var apis = []model.SysApi{ {global.GVA_MODEL{ID: 78, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/getWorkflowMoveByID", "根据id获取当前节点详情和历史", "workflowProcess", "GET"}, {global.GVA_MODEL{ID: 79, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/completeWorkflowMove", "提交工作流", "workflowProcess", "POST"}, {global.GVA_MODEL{ID: 80, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/autoCode/preview", "预览自动化代码", "autoCode", "POST"}, + {global.GVA_MODEL{ID: 81, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/importExcel", "预览自动化代码", "autoCode", "POST"}, + {global.GVA_MODEL{ID: 82, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/loadExcel", "预览自动化代码", "autoCode", "POST"}, + {global.GVA_MODEL{ID: 83, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/exportExcel", "预览自动化代码", "autoCode", "POST"}, + {global.GVA_MODEL{ID: 84, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/downloadTemplate", "预览自动化代码", "autoCode", "POST"}, } //@author: [SliverHorn](https://github.com/SliverHorn) diff --git a/server/cmd/information/system/casbin.go b/server/cmd/information/system/casbin.go index e71f3117..649b448f 100644 --- a/server/cmd/information/system/casbin.go +++ b/server/cmd/information/system/casbin.go @@ -92,6 +92,10 @@ var carbines = []gormadapter.CasbinRule{ {PType: "p", V0: "888", V1: "/workflowProcess/getMyStated", V2: "GET"}, {PType: "p", V0: "888", V1: "/workflowProcess/getMyNeed", V2: "GET"}, {PType: "p", V0: "888", V1: "/workflowProcess/getWorkflowMoveByID", V2: "GET"}, + {PType: "p", V0: "888", V1: "/excel/importExcel", V2: "POST"}, + {PType: "p", V0: "888", V1: "/excel/loadExcel", V2: "GET"}, + {PType: "p", V0: "888", V1: "/excel/exportExcel", V2: "POST"}, + {PType: "p", V0: "888", V1: "/excel/downloadTemplate", V2: "GET"}, {PType: "p", V0: "8881", V1: "/base/login", V2: "POST"}, {PType: "p", V0: "8881", V1: "/user/register", V2: "POST"}, {PType: "p", V0: "8881", V1: "/api/createApi", V2: "POST"}, diff --git a/server/initialize/router.go b/server/initialize/router.go index 32ce9896..de34b37e 100644 --- a/server/initialize/router.go +++ b/server/initialize/router.go @@ -47,6 +47,7 @@ func Routers() *gin.Engine { router.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 router.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 router.InitWorkflowProcessRouter(PrivateGroup) // 工作流相关接口 + router.InitExcelRouter(PrivateGroup) // 表格导入导出 } global.GVA_LOG.Info("router register success") return Router diff --git a/server/model/exa_excel.go b/server/model/exa_excel.go new file mode 100644 index 00000000..c1d7f769 --- /dev/null +++ b/server/model/exa_excel.go @@ -0,0 +1,6 @@ +package model + +type ExcelInfo struct { + FileName string `json:"fileName"` + InfoList []SysBaseMenu `json:"infoList"` +} diff --git a/server/model/request/exa_file_upload_and_download.go b/server/model/request/exa_file_upload_and_download.go deleted file mode 100644 index c95cd83a..00000000 --- a/server/model/request/exa_file_upload_and_download.go +++ /dev/null @@ -1,8 +0,0 @@ -package request - -import "gin-vue-admin/model" - -type ExcelInfo struct { - FileName string `json:"fileName"` - InfoList []model.SysBaseMenu `json:"infoList"` -} \ No newline at end of file diff --git a/server/resource/excel/ExcelExport.xlsx b/server/resource/excel/ExcelExport.xlsx index 5b2ba1ca..4f757819 100644 Binary files a/server/resource/excel/ExcelExport.xlsx and b/server/resource/excel/ExcelExport.xlsx differ diff --git a/server/router/exp_customer.go b/server/router/exa_customer.go similarity index 100% rename from server/router/exp_customer.go rename to server/router/exa_customer.go diff --git a/server/router/exa_excel.go b/server/router/exa_excel.go new file mode 100644 index 00000000..0bd3d19d --- /dev/null +++ b/server/router/exa_excel.go @@ -0,0 +1,16 @@ +package router + +import ( + "gin-vue-admin/api/v1" + "github.com/gin-gonic/gin" +) + +func InitExcelRouter(Router *gin.RouterGroup) { + FileUploadAndDownloadGroup := Router.Group("excel") + { + FileUploadAndDownloadGroup.POST("/importExcel", v1.ImportExcel) // 导入Excel + FileUploadAndDownloadGroup.GET("/loadExcel", v1.LoadExcel) // 加载Excel数据 + FileUploadAndDownloadGroup.POST("/exportExcel", v1.ExportExcel) // 导出Excel + FileUploadAndDownloadGroup.GET("/downloadTemplate", v1.DownloadTemplate) // 下载模板文件 + } +} diff --git a/server/router/exp_file_upload_and_download.go b/server/router/exa_file_upload_and_download.go similarity index 70% rename from server/router/exp_file_upload_and_download.go rename to server/router/exa_file_upload_and_download.go index c8ed1fb8..de141d8c 100644 --- a/server/router/exp_file_upload_and_download.go +++ b/server/router/exa_file_upload_and_download.go @@ -15,9 +15,5 @@ func InitFileUploadAndDownloadRouter(Router *gin.RouterGroup) { FileUploadAndDownloadGroup.GET("/findFile", v1.FindFile) // 查询当前文件成功的切片 FileUploadAndDownloadGroup.POST("/breakpointContinueFinish", v1.BreakpointContinueFinish) // 查询当前文件成功的切片 FileUploadAndDownloadGroup.POST("/removeChunk", v1.RemoveChunk) // 查询当前文件成功的切片 - FileUploadAndDownloadGroup.POST("/importExcel", v1.ImportExcel) // 导入Excel - FileUploadAndDownloadGroup.GET("/loadExcel", v1.LoadExcel) // 加载Excel数据 - FileUploadAndDownloadGroup.POST("/exportExcel", v1.ExportExcel) // 导出Excel - FileUploadAndDownloadGroup.GET("/downloadTemplate", v1.DownloadTemplate) // 下载模板文件 } } diff --git a/web/src/api/excel.js b/web/src/api/excel.js new file mode 100644 index 00000000..3315f6ab --- /dev/null +++ b/web/src/api/excel.js @@ -0,0 +1,85 @@ +import service from '@/utils/request'; +import { Message } from 'element-ui'; + +const handleFileError = (res, fileName) => { + if (typeof(res.data) !== "undefined") { + if (res.data.type == "application/json") { + const reader = new FileReader(); + reader.onload = function() { + let message = JSON.parse(reader.result).msg; + Message({ + showClose: true, + message: message, + type: 'error' + }) + }; + reader.readAsText(new Blob([res.data])); + } + } else { + var downloadUrl = window.URL.createObjectURL(new Blob([res])); + var a = document.createElement('a'); + a.style.display = 'none'; + a.href = downloadUrl; + a.download = fileName; + var event = new MouseEvent("click"); + a.dispatchEvent(event); + } +} + +// @Tags excel +// @Summary 导出Excel +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/octet-stream +// @Param data body model.ExcelInfo true "导出Excel文件信息" +// @Success 200 +// @Router /excel/exportExcel [post] +export const exportExcel = (tableData, fileName) => { + service({ + url: "/excel/exportExcel", + method: 'post', + data: { + fileName: fileName, + infoList: tableData + }, + responseType: 'blob' + }).then((res) => { + handleFileError(res, fileName) + }) +} + +// @Tags excel +// @Summary 导入Excel文件 +// @Security ApiKeyAuth +// @accept multipart/form-data +// @Produce application/json +// @Param file formData file true "导入Excel文件" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}" +// @Router /excel/importExcel [post] +export const loadExcelData = () => { + return service({ + url: "/excel/loadExcel", + method: 'get' + }) +} + +// @Tags excel +// @Summary 下载模板 +// @Security ApiKeyAuth +// @accept multipart/form-data +// @Produce application/json +// @Param fileName query fileName true "模板名称" +// @Success 200 +// @Router /excel/downloadTemplate [get] +export const downloadTemplate = (fileName) => { + return service({ + url: "/excel/downloadTemplate", + method: 'get', + params: { + fileName: fileName + }, + responseType: 'blob' + }).then((res) => { + handleFileError(res, fileName) + }) +} \ No newline at end of file diff --git a/web/src/api/fileUploadAndDownload.js b/web/src/api/fileUploadAndDownload.js index 62e70c7b..492be034 100644 --- a/web/src/api/fileUploadAndDownload.js +++ b/web/src/api/fileUploadAndDownload.js @@ -1,30 +1,4 @@ import service from '@/utils/request'; -import { Message } from 'element-ui'; - -const handleFileError = (res, fileName) => { - if (typeof(res.data) !== "undefined") { - if (res.data.type == "application/json") { - const reader = new FileReader(); - reader.onload = function() { - let message = JSON.parse(reader.result).msg; - Message({ - showClose: true, - message: message, - type: 'error' - }) - }; - reader.readAsText(new Blob([res.data])); - } - } else { - var downloadUrl = window.URL.createObjectURL(new Blob([res])); - var a = document.createElement('a'); - a.style.display = 'none'; - a.href = downloadUrl; - a.download = fileName; - var event = new MouseEvent("click"); - a.dispatchEvent(event); - } -} // @Tags FileUploadAndDownload // @Summary 分页文件列表 @@ -55,62 +29,4 @@ export const deleteFile = (data) => { method: "post", data }) -} - -// @Tags ExaFileUploadAndDownload -// @Summary 导出Excel -// @Security ApiKeyAuth -// @accept application/json -// @Produce application/octet-stream -// @Param data body request.ExcelInfo true "导出Excel文件信息" -// @Success 200 -// @Router /fileUploadAndDownload/exportExcel [post] -export const exportExcel = (tableData, fileName) => { - service({ - url: "/fileUploadAndDownload/exportExcel", - method: 'post', - data: { - fileName: fileName, - infoList: tableData - }, - responseType: 'blob' - }).then((res)=>{ - handleFileError(res, fileName) - }) -} - -// @Tags ExaFileUploadAndDownload -// @Summary 导入Excel文件 -// @Security ApiKeyAuth -// @accept multipart/form-data -// @Produce application/json -// @Param file formData file true "导入Excel文件" -// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}" -// @Router /fileUploadAndDownload/importExcel [post] -export const loadExcelData = () => { - return service({ - url: "/fileUploadAndDownload/loadExcel", - method: 'get' - }) -} - -// @Tags ExaFileUploadAndDownload -// @Summary 下载模板 -// @Security ApiKeyAuth -// @accept multipart/form-data -// @Produce application/json -// @Param fileName query fileName true "模板名称" -// @Success 200 -// @Router /fileUploadAndDownload/downloadTemplate [get] -export const downloadTemplate = (fileName) => { - return service({ - url: "/fileUploadAndDownload/downloadTemplate", - method: 'get', - params:{ - fileName: fileName - }, - responseType: 'blob' - }).then((res)=>{ - handleFileError(res, fileName) - }) } \ No newline at end of file diff --git a/web/src/view/example/excel/excel.vue b/web/src/view/example/excel/excel.vue index bb208cb7..c211eb89 100644 --- a/web/src/view/example/excel/excel.vue +++ b/web/src/view/example/excel/excel.vue @@ -3,7 +3,7 @@