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, } }