123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- 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"
- "github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
- "github.com/flipped-aurora/gin-vue-admin/server/model/system"
- systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
- "github.com/flipped-aurora/gin-vue-admin/server/service"
- "github.com/flipped-aurora/gin-vue-admin/server/utils"
- "github.com/gin-gonic/gin"
- "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 {
- }
- var sysExportTemplateService = service.ServiceGroupApp.SystemServiceGroup.SysExportTemplateService
- // CreateSysExportTemplate 创建导出模板
- // @Tags SysExportTemplate
- // @Summary 创建导出模板
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Param data body system.SysExportTemplate true "创建导出模板"
- // @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
- // @Router /sysExportTemplate/createSysExportTemplate [post]
- func (sysExportTemplateApi *SysExportTemplateApi) CreateSysExportTemplate(c *gin.Context) {
- var sysExportTemplate system.SysExportTemplate
- err := c.ShouldBindJSON(&sysExportTemplate)
- if err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- verify := utils.Rules{
- "Name": {utils.NotEmpty()},
- }
- if err := utils.Verify(sysExportTemplate, verify); err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- if err := sysExportTemplateService.CreateSysExportTemplate(&sysExportTemplate); err != nil {
- global.GVA_LOG.Error("创建失败!", zap.Error(err))
- response.FailWithMessage("创建失败", c)
- } else {
- response.OkWithMessage("创建成功", c)
- }
- }
- // DeleteSysExportTemplate 删除导出模板
- // @Tags SysExportTemplate
- // @Summary 删除导出模板
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Param data body system.SysExportTemplate true "删除导出模板"
- // @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
- // @Router /sysExportTemplate/deleteSysExportTemplate [delete]
- func (sysExportTemplateApi *SysExportTemplateApi) DeleteSysExportTemplate(c *gin.Context) {
- var sysExportTemplate system.SysExportTemplate
- err := c.ShouldBindJSON(&sysExportTemplate)
- if err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- if err := sysExportTemplateService.DeleteSysExportTemplate(sysExportTemplate); err != nil {
- global.GVA_LOG.Error("删除失败!", zap.Error(err))
- response.FailWithMessage("删除失败", c)
- } else {
- response.OkWithMessage("删除成功", c)
- }
- }
- // DeleteSysExportTemplateByIds 批量删除导出模板
- // @Tags SysExportTemplate
- // @Summary 批量删除导出模板
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Param data body request.IdsReq true "批量删除导出模板"
- // @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
- // @Router /sysExportTemplate/deleteSysExportTemplateByIds [delete]
- func (sysExportTemplateApi *SysExportTemplateApi) DeleteSysExportTemplateByIds(c *gin.Context) {
- var IDS request.IdsReq
- err := c.ShouldBindJSON(&IDS)
- if err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- if err := sysExportTemplateService.DeleteSysExportTemplateByIds(IDS); err != nil {
- global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
- response.FailWithMessage("批量删除失败", c)
- } else {
- response.OkWithMessage("批量删除成功", c)
- }
- }
- // UpdateSysExportTemplate 更新导出模板
- // @Tags SysExportTemplate
- // @Summary 更新导出模板
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Param data body system.SysExportTemplate true "更新导出模板"
- // @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
- // @Router /sysExportTemplate/updateSysExportTemplate [put]
- func (sysExportTemplateApi *SysExportTemplateApi) UpdateSysExportTemplate(c *gin.Context) {
- var sysExportTemplate system.SysExportTemplate
- err := c.ShouldBindJSON(&sysExportTemplate)
- if err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- verify := utils.Rules{
- "Name": {utils.NotEmpty()},
- }
- if err := utils.Verify(sysExportTemplate, verify); err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- if err := sysExportTemplateService.UpdateSysExportTemplate(sysExportTemplate); err != nil {
- global.GVA_LOG.Error("更新失败!", zap.Error(err))
- response.FailWithMessage("更新失败", c)
- } else {
- response.OkWithMessage("更新成功", c)
- }
- }
- // FindSysExportTemplate 用id查询导出模板
- // @Tags SysExportTemplate
- // @Summary 用id查询导出模板
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Param data query system.SysExportTemplate true "用id查询导出模板"
- // @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
- // @Router /sysExportTemplate/findSysExportTemplate [get]
- func (sysExportTemplateApi *SysExportTemplateApi) FindSysExportTemplate(c *gin.Context) {
- var sysExportTemplate system.SysExportTemplate
- err := c.ShouldBindQuery(&sysExportTemplate)
- if err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- if resysExportTemplate, err := sysExportTemplateService.GetSysExportTemplate(sysExportTemplate.ID); err != nil {
- global.GVA_LOG.Error("查询失败!", zap.Error(err))
- response.FailWithMessage("查询失败", c)
- } else {
- response.OkWithData(gin.H{"resysExportTemplate": resysExportTemplate}, c)
- }
- }
- // GetSysExportTemplateList 分页获取导出模板列表
- // @Tags SysExportTemplate
- // @Summary 分页获取导出模板列表
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Param data query systemReq.SysExportTemplateSearch true "分页获取导出模板列表"
- // @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
- // @Router /sysExportTemplate/getSysExportTemplateList [get]
- func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gin.Context) {
- var pageInfo systemReq.SysExportTemplateSearch
- err := c.ShouldBindQuery(&pageInfo)
- if err != nil {
- response.FailWithMessage(err.Error(), c)
- return
- }
- if list, total, err := sysExportTemplateService.GetSysExportTemplateInfoList(pageInfo); 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)
- }
- }
- // ExportExcel 导出表格token
- // @Tags SysExportTemplate
- // @Summary 导出表格
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Router /sysExportTemplate/exportExcel [get]
- func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) {
- templateID := c.Query("templateID")
- 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("success", "true")
- c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes())
- }
- }
- // ExportTemplate 导出表格模板
- // @Tags SysExportTemplate
- // @Summary 导出表格模板
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @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("success", "true")
- c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes())
- }
- }
- // ImportExcel 导入表格
- // @Tags SysImportTemplate
- // @Summary 导入表格
- // @Security ApiKeyAuth
- // @accept application/json
- // @Produce application/json
- // @Router /sysExportTemplate/importExcel [post]
- func (sysExportTemplateApi *SysExportTemplateApi) ImportExcel(c *gin.Context) {
- templateID := c.Query("templateID")
- if templateID == "" {
- response.FailWithMessage("模板ID不能为空", c)
- return
- }
- file, err := c.FormFile("file")
- if err != nil {
- global.GVA_LOG.Error("文件获取失败!", zap.Error(err))
- response.FailWithMessage("文件获取失败", c)
- return
- }
- if err := sysExportTemplateService.ImportExcel(templateID, file); err != nil {
- global.GVA_LOG.Error(err.Error(), zap.Error(err))
- response.FailWithMessage(err.Error(), c)
- } else {
- response.OkWithMessage("导入成功", c)
- }
- }
|