225 lines
6.8 KiB
Go
225 lines
6.8 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"kra/internal/biz"
|
|
"kra/internal/service"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type exportTemplateRequest struct {
|
|
ID uint `json:"ID"`
|
|
DBName string `json:"dbName"`
|
|
Name string `json:"name"`
|
|
TableName string `json:"tableName"`
|
|
TemplateID string `json:"templateID"`
|
|
TemplateInfo string `json:"templateInfo"`
|
|
SQL string `json:"sql"`
|
|
ImportSQL string `json:"importSql"`
|
|
Limit *int `json:"limit"`
|
|
Order string `json:"order"`
|
|
Conditions []struct {
|
|
From string `json:"from"`
|
|
Column string `json:"column"`
|
|
Operator string `json:"operator"`
|
|
} `json:"conditions"`
|
|
Joins []struct {
|
|
Join string `json:"joins"`
|
|
Table string `json:"table"`
|
|
On string `json:"on"`
|
|
} `json:"joinTemplate"`
|
|
}
|
|
|
|
func exportTemplateDomain(v exportTemplateRequest) *biz.ExportTemplate {
|
|
out := &biz.ExportTemplate{ID: v.ID, DBName: v.DBName, Name: v.Name, TableName: v.TableName, TemplateID: v.TemplateID, TemplateInfo: v.TemplateInfo, SQL: v.SQL, ImportSQL: v.ImportSQL, Limit: v.Limit, Order: v.Order}
|
|
for _, x := range v.Conditions {
|
|
out.Conditions = append(out.Conditions, biz.ExportCondition{From: x.From, Column: x.Column, Operator: x.Operator})
|
|
}
|
|
for _, x := range v.Joins {
|
|
out.Joins = append(out.Joins, biz.ExportJoin{Join: x.Join, Table: x.Table, On: x.On})
|
|
}
|
|
return out
|
|
}
|
|
func exportParams(values url.Values) map[string]string {
|
|
out := map[string]string{}
|
|
nested, _ := url.ParseQuery(values.Get("params"))
|
|
for key, items := range nested {
|
|
if len(items) > 0 {
|
|
out[key] = items[0]
|
|
}
|
|
}
|
|
for key, items := range values {
|
|
if key != "params" && len(items) > 0 {
|
|
out[key] = items[0]
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
type exportToken struct {
|
|
TemplateID string `json:"templateID"`
|
|
Params map[string]string `json:"params"`
|
|
Blank bool `json:"blank"`
|
|
}
|
|
|
|
func registerExportRoutes(group, public *gin.RouterGroup, system *service.SystemService, svc *service.ExportService) {
|
|
router := group.Group("/sysExportTemplate")
|
|
router.POST("/createSysExportTemplate", func(c *gin.Context) {
|
|
var req exportTemplateRequest
|
|
if c.ShouldBindJSON(&req) != nil || req.Name == "" || req.TemplateID == "" {
|
|
fail(c, "参数错误")
|
|
return
|
|
}
|
|
if err := svc.Create(c.Request.Context(), exportTemplateDomain(req)); err != nil {
|
|
fail(c, "创建失败:"+err.Error())
|
|
return
|
|
}
|
|
ok(c)
|
|
})
|
|
router.PUT("/updateSysExportTemplate", func(c *gin.Context) {
|
|
var req exportTemplateRequest
|
|
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
|
fail(c, "参数错误")
|
|
return
|
|
}
|
|
if err := svc.Update(c.Request.Context(), exportTemplateDomain(req)); err != nil {
|
|
fail(c, "更新失败:"+err.Error())
|
|
return
|
|
}
|
|
ok(c)
|
|
})
|
|
router.DELETE("/deleteSysExportTemplate", func(c *gin.Context) {
|
|
var req struct {
|
|
ID uint `json:"ID"`
|
|
}
|
|
if c.ShouldBindJSON(&req) != nil {
|
|
fail(c, "参数错误")
|
|
return
|
|
}
|
|
if err := svc.Delete(c.Request.Context(), []uint{req.ID}); err != nil {
|
|
fail(c, "删除失败")
|
|
return
|
|
}
|
|
ok(c)
|
|
})
|
|
router.DELETE("/deleteSysExportTemplateByIds", func(c *gin.Context) {
|
|
var req struct {
|
|
IDs []uint `json:"ids"`
|
|
}
|
|
if c.ShouldBindJSON(&req) != nil {
|
|
fail(c, "参数错误")
|
|
return
|
|
}
|
|
if err := svc.Delete(c.Request.Context(), req.IDs); err != nil {
|
|
fail(c, "删除失败")
|
|
return
|
|
}
|
|
ok(c)
|
|
})
|
|
router.GET("/findSysExportTemplate", func(c *gin.Context) {
|
|
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
|
item, err := svc.Template(c.Request.Context(), uint(id), "")
|
|
if err != nil {
|
|
fail(c, "查询失败")
|
|
return
|
|
}
|
|
writeResult(c, codeSuccess, gin.H{"resysExportTemplate": item}, "查询成功")
|
|
})
|
|
router.GET("/getSysExportTemplateList", func(c *gin.Context) {
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
size, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
|
items, total, err := svc.Templates(c.Request.Context(), page, size, &biz.ExportTemplate{Name: c.Query("name"), TableName: c.Query("tableName"), TemplateID: c.Query("templateID")})
|
|
if err != nil {
|
|
fail(c, "获取失败")
|
|
return
|
|
}
|
|
writeResult(c, codeSuccess, pageResult{List: items, Total: total, Page: page, PageSize: size}, "获取成功")
|
|
})
|
|
router.GET("/previewSQL", func(c *gin.Context) {
|
|
sql, err := svc.Preview(c.Request.Context(), c.Query("templateID"), exportParams(c.Request.URL.Query()))
|
|
if err != nil {
|
|
fail(c, "预览失败:"+err.Error())
|
|
return
|
|
}
|
|
writeResult(c, codeSuccess, gin.H{"sql": sql}, "获取成功")
|
|
})
|
|
issue := func(blank bool) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
tid := c.Query("templateID")
|
|
if tid == "" {
|
|
fail(c, "模板ID不能为空")
|
|
return
|
|
}
|
|
token := strings.ReplaceAll(uuid.NewString(), "-", "")
|
|
raw, _ := json.Marshal(exportToken{TemplateID: tid, Params: exportParams(c.Request.URL.Query()), Blank: blank})
|
|
if err := system.CacheSet(c.Request.Context(), "export:"+token, string(raw), 5*time.Minute); err != nil {
|
|
fail(c, "导出令牌创建失败")
|
|
return
|
|
}
|
|
writeResult(c, codeSuccess, gin.H{"token": token}, "获取成功")
|
|
}
|
|
}
|
|
router.GET("/exportExcel", issue(false))
|
|
router.GET("/exportTemplate", issue(true))
|
|
router.POST("/importExcel", func(c *gin.Context) {
|
|
file, err := c.FormFile("file")
|
|
if err != nil {
|
|
fail(c, "请选择导入文件")
|
|
return
|
|
}
|
|
opened, err := file.Open()
|
|
if err != nil {
|
|
fail(c, "读取文件失败")
|
|
return
|
|
}
|
|
defer opened.Close()
|
|
tid := c.PostForm("templateID")
|
|
if tid == "" {
|
|
tid = c.Query("templateID")
|
|
}
|
|
if err = svc.Import(c.Request.Context(), tid, opened); err != nil {
|
|
fail(c, err.Error())
|
|
return
|
|
}
|
|
ok(c)
|
|
})
|
|
pub := public.Group("/sysExportTemplate")
|
|
download := func(expectBlank bool) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
token := c.Query("token")
|
|
raw, okValue, err := system.CacheGet(c.Request.Context(), "export:"+token)
|
|
if err != nil || !okValue {
|
|
fail(c, "导出令牌无效或已过期")
|
|
return
|
|
}
|
|
_ = system.CacheDelete(c.Request.Context(), "export:"+token)
|
|
var value exportToken
|
|
if json.Unmarshal([]byte(raw), &value) != nil || value.Blank != expectBlank {
|
|
fail(c, "导出令牌无效")
|
|
return
|
|
}
|
|
var data []byte
|
|
var name string
|
|
if expectBlank {
|
|
data, name, err = svc.ExportBlankTemplate(c.Request.Context(), value.TemplateID)
|
|
} else {
|
|
data, name, err = svc.Export(c.Request.Context(), value.TemplateID, value.Params)
|
|
}
|
|
if err != nil {
|
|
fail(c, "导出失败:"+err.Error())
|
|
return
|
|
}
|
|
c.Header("Content-Disposition", "attachment; filename*=UTF-8''"+url.QueryEscape(name))
|
|
c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", data)
|
|
}
|
|
}
|
|
pub.GET("/exportExcelByToken", download(false))
|
|
pub.GET("/exportTemplateByToken", download(true))
|
|
}
|