400 lines
12 KiB
Go
400 lines
12 KiB
Go
package system
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"kra/internal/biz/system"
|
|
"kra/pkg/response"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type VersionApi struct{}
|
|
|
|
// VersionSearchRequest 版本搜索请求
|
|
type VersionSearchRequest struct {
|
|
Page int `json:"page" form:"page"`
|
|
PageSize int `json:"pageSize" form:"pageSize"`
|
|
VersionName *string `json:"versionName" form:"versionName"`
|
|
VersionCode *string `json:"versionCode" form:"versionCode"`
|
|
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
|
|
}
|
|
|
|
// ExportVersionRequest 导出版本请求
|
|
type ExportVersionRequest struct {
|
|
VersionName string `json:"versionName" binding:"required"`
|
|
VersionCode string `json:"versionCode" binding:"required"`
|
|
Description string `json:"description"`
|
|
MenuIds []uint `json:"menuIds"`
|
|
ApiIds []uint `json:"apiIds"`
|
|
DictIds []uint `json:"dictIds"`
|
|
}
|
|
|
|
// VersionInfo 版本信息
|
|
type VersionInfo struct {
|
|
Name string `json:"name"`
|
|
Code string `json:"code"`
|
|
Description string `json:"description"`
|
|
ExportTime string `json:"exportTime"`
|
|
}
|
|
|
|
// ExportVersionResponse 导出版本响应
|
|
type ExportVersionResponse struct {
|
|
Version VersionInfo `json:"version"`
|
|
Menus []map[string]interface{} `json:"menus"`
|
|
Apis []map[string]interface{} `json:"apis"`
|
|
Dictionaries []map[string]interface{} `json:"dictionaries"`
|
|
}
|
|
|
|
// DeleteSysVersion
|
|
// @Tags SysVersion
|
|
// @Summary 删除版本
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param ID query string true "版本ID"
|
|
// @Success 200 {object} response.Response{msg=string} "删除版本"
|
|
// @Router /sysVersion/deleteSysVersion [delete]
|
|
func (v *VersionApi) DeleteSysVersion(c *gin.Context) {
|
|
id := c.Query("ID")
|
|
if id == "" {
|
|
response.FailWithMessage("缺少参数: ID", c)
|
|
return
|
|
}
|
|
|
|
if err := versionUsecase.DeleteSysVersion(c.Request.Context(), id); err != nil {
|
|
response.FailWithMessage("删除失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
response.OkWithMessage("删除成功", c)
|
|
}
|
|
|
|
// DeleteSysVersionByIds
|
|
// @Tags SysVersion
|
|
// @Summary 批量删除版本
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param IDs[] query []string true "版本ID列表"
|
|
// @Success 200 {object} response.Response{msg=string} "批量删除版本"
|
|
// @Router /sysVersion/deleteSysVersionByIds [delete]
|
|
func (v *VersionApi) DeleteSysVersionByIds(c *gin.Context) {
|
|
ids := c.QueryArray("IDs[]")
|
|
if len(ids) == 0 {
|
|
response.FailWithMessage("缺少参数: IDs", c)
|
|
return
|
|
}
|
|
|
|
if err := versionUsecase.DeleteSysVersionByIds(c.Request.Context(), ids); err != nil {
|
|
response.FailWithMessage("批量删除失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
response.OkWithMessage("批量删除成功", c)
|
|
}
|
|
|
|
// FindSysVersion
|
|
// @Tags SysVersion
|
|
// @Summary 根据ID获取版本
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param ID query string true "版本ID"
|
|
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取版本"
|
|
// @Router /sysVersion/findSysVersion [get]
|
|
func (v *VersionApi) FindSysVersion(c *gin.Context) {
|
|
id := c.Query("ID")
|
|
if id == "" {
|
|
response.FailWithMessage("缺少参数: ID", c)
|
|
return
|
|
}
|
|
|
|
version, err := versionUsecase.GetSysVersion(c.Request.Context(), id)
|
|
if err != nil {
|
|
response.FailWithMessage("查询失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
response.OkWithData(toVersionResponse(version), c)
|
|
}
|
|
|
|
// GetSysVersionList
|
|
// @Tags SysVersion
|
|
// @Summary 分页获取版本列表
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data query VersionSearchRequest true "页码, 每页大小, 搜索条件"
|
|
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取版本列表,返回包括列表,总数,页码,每页数量"
|
|
// @Router /sysVersion/getSysVersionList [get]
|
|
func (v *VersionApi) GetSysVersionList(c *gin.Context) {
|
|
var req VersionSearchRequest
|
|
if err := c.ShouldBindQuery(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
if req.Page == 0 {
|
|
req.Page = 1
|
|
}
|
|
if req.PageSize == 0 {
|
|
req.PageSize = 10
|
|
}
|
|
|
|
searchReq := &system.VersionSearchReq{
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
VersionName: req.VersionName,
|
|
VersionCode: req.VersionCode,
|
|
CreatedAtRange: req.CreatedAtRange,
|
|
}
|
|
|
|
list, total, err := versionUsecase.GetSysVersionInfoList(c.Request.Context(), searchReq)
|
|
if err != nil {
|
|
response.FailWithMessage("获取失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
result := make([]map[string]interface{}, len(list))
|
|
for i, item := range list {
|
|
result[i] = toVersionResponse(item)
|
|
}
|
|
|
|
response.OkWithDetailed(response.PageResult{
|
|
List: result,
|
|
Total: total,
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
}, "获取成功", c)
|
|
}
|
|
|
|
// GetSysVersionPublic
|
|
// @Tags SysVersion
|
|
// @Summary 公开版本接口
|
|
// @Produce application/json
|
|
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取公开版本信息"
|
|
// @Router /sysVersion/getSysVersionPublic [get]
|
|
func (v *VersionApi) GetSysVersionPublic(c *gin.Context) {
|
|
response.OkWithDetailed(gin.H{
|
|
"info": "不需要鉴权的版本管理接口信息",
|
|
}, "获取成功", c)
|
|
}
|
|
|
|
// ExportVersion
|
|
// @Tags SysVersion
|
|
// @Summary 创建发版数据
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body ExportVersionRequest true "发版数据"
|
|
// @Success 200 {object} response.Response{msg=string} "创建发版成功"
|
|
// @Router /sysVersion/exportVersion [post]
|
|
func (v *VersionApi) ExportVersion(c *gin.Context) {
|
|
var req ExportVersionRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
ctx := c.Request.Context()
|
|
|
|
// 获取选中的菜单数据
|
|
var menuData []map[string]interface{}
|
|
if len(req.MenuIds) > 0 {
|
|
menus, err := versionUsecase.GetMenusByIds(ctx, req.MenuIds)
|
|
if err != nil {
|
|
response.FailWithMessage("获取菜单数据失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
for _, m := range menus {
|
|
menuData = append(menuData, map[string]interface{}{
|
|
"path": m.Path,
|
|
"name": m.Name,
|
|
"hidden": m.Hidden,
|
|
"component": m.Component,
|
|
"sort": m.Sort,
|
|
})
|
|
}
|
|
}
|
|
|
|
// 获取选中的API数据
|
|
var apiData []map[string]interface{}
|
|
if len(req.ApiIds) > 0 {
|
|
apis, err := versionUsecase.GetApisByIds(ctx, req.ApiIds)
|
|
if err != nil {
|
|
response.FailWithMessage("获取API数据失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
for _, a := range apis {
|
|
apiData = append(apiData, map[string]interface{}{
|
|
"path": a.Path,
|
|
"description": a.Description,
|
|
"apiGroup": a.ApiGroup,
|
|
"method": a.Method,
|
|
})
|
|
}
|
|
}
|
|
|
|
// 获取选中的字典数据
|
|
var dictData []map[string]interface{}
|
|
if len(req.DictIds) > 0 {
|
|
dicts, err := versionUsecase.GetDictionariesByIds(ctx, req.DictIds)
|
|
if err != nil {
|
|
response.FailWithMessage("获取字典数据失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
for _, d := range dicts {
|
|
dictData = append(dictData, map[string]interface{}{
|
|
"name": d.Name,
|
|
"type": d.Type,
|
|
"status": d.Status,
|
|
"desc": d.Desc,
|
|
})
|
|
}
|
|
}
|
|
|
|
// 构建导出数据
|
|
exportData := ExportVersionResponse{
|
|
Version: VersionInfo{
|
|
Name: req.VersionName,
|
|
Code: req.VersionCode,
|
|
Description: req.Description,
|
|
ExportTime: time.Now().Format("2006-01-02 15:04:05"),
|
|
},
|
|
Menus: menuData,
|
|
Apis: apiData,
|
|
Dictionaries: dictData,
|
|
}
|
|
|
|
// 转换为JSON
|
|
jsonData, err := json.MarshalIndent(exportData, "", " ")
|
|
if err != nil {
|
|
response.FailWithMessage("JSON序列化失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
// 保存版本记录
|
|
version := &system.SysVersion{
|
|
VersionName: req.VersionName,
|
|
VersionCode: req.VersionCode,
|
|
Description: req.Description,
|
|
VersionData: string(jsonData),
|
|
}
|
|
|
|
if err := versionUsecase.CreateSysVersion(ctx, version); err != nil {
|
|
response.FailWithMessage("保存版本记录失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithMessage("创建发版成功", c)
|
|
}
|
|
|
|
// DownloadVersionJson
|
|
// @Tags SysVersion
|
|
// @Summary 下载版本JSON数据
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param ID query string true "版本ID"
|
|
// @Success 200 {file} json "版本JSON文件"
|
|
// @Router /sysVersion/downloadVersionJson [get]
|
|
func (v *VersionApi) DownloadVersionJson(c *gin.Context) {
|
|
id := c.Query("ID")
|
|
if id == "" {
|
|
response.FailWithMessage("版本ID不能为空", c)
|
|
return
|
|
}
|
|
|
|
version, err := versionUsecase.GetSysVersion(c.Request.Context(), id)
|
|
if err != nil {
|
|
response.FailWithMessage("获取版本记录失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
var jsonData []byte
|
|
if version.VersionData != "" {
|
|
jsonData = []byte(version.VersionData)
|
|
} else {
|
|
basicData := ExportVersionResponse{
|
|
Version: VersionInfo{
|
|
Name: version.VersionName,
|
|
Code: version.VersionCode,
|
|
Description: version.Description,
|
|
ExportTime: version.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
},
|
|
}
|
|
jsonData, _ = json.MarshalIndent(basicData, "", " ")
|
|
}
|
|
|
|
filename := fmt.Sprintf("version_%s_%s.json", version.VersionCode, time.Now().Format("20060102150405"))
|
|
c.Header("Content-Type", "application/json")
|
|
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
|
|
c.Header("Content-Length", strconv.Itoa(len(jsonData)))
|
|
|
|
c.Data(http.StatusOK, "application/json", jsonData)
|
|
}
|
|
|
|
// ImportVersion
|
|
// @Tags SysVersion
|
|
// @Summary 导入版本数据
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body map[string]interface{} true "版本JSON数据"
|
|
// @Success 200 {object} response.Response{msg=string} "导入成功"
|
|
// @Router /sysVersion/importVersion [post]
|
|
func (v *VersionApi) ImportVersion(c *gin.Context) {
|
|
var importData map[string]interface{}
|
|
if err := c.ShouldBindJSON(&importData); err != nil {
|
|
response.FailWithMessage("解析JSON数据失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
// 验证数据格式
|
|
versionInfo, ok := importData["version"].(map[string]interface{})
|
|
if !ok {
|
|
response.FailWithMessage("版本信息格式错误", c)
|
|
return
|
|
}
|
|
|
|
name, _ := versionInfo["name"].(string)
|
|
code, _ := versionInfo["code"].(string)
|
|
desc, _ := versionInfo["description"].(string)
|
|
|
|
if name == "" || code == "" {
|
|
response.FailWithMessage("版本名称和版本号不能为空", c)
|
|
return
|
|
}
|
|
|
|
// 创建导入记录
|
|
jsonData, _ := json.Marshal(importData)
|
|
version := &system.SysVersion{
|
|
VersionName: name,
|
|
VersionCode: fmt.Sprintf("%s_imported_%s", code, time.Now().Format("20060102150405")),
|
|
Description: fmt.Sprintf("导入版本: %s", desc),
|
|
VersionData: string(jsonData),
|
|
}
|
|
|
|
if err := versionUsecase.CreateSysVersion(c.Request.Context(), version); err != nil {
|
|
response.FailWithMessage("保存导入记录失败:"+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithMessage("导入成功", c)
|
|
}
|
|
|
|
// toVersionResponse 转换版本响应
|
|
func toVersionResponse(v *system.SysVersion) map[string]interface{} {
|
|
return map[string]interface{}{
|
|
"id": v.ID,
|
|
"versionName": v.VersionName,
|
|
"versionCode": v.VersionCode,
|
|
"description": v.Description,
|
|
"versionData": v.VersionData,
|
|
"createdAt": v.CreatedAt,
|
|
"updatedAt": v.UpdatedAt,
|
|
}
|
|
}
|