package api import ( "io" "strconv" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" wechatResponse "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/response" "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/service" "github.com/gin-gonic/gin" "go.uber.org/zap" ) type MpMaterialApi struct{} var mpMaterialService = service.ServiceGroupApp.MpMaterialService // GetMaterialList 获取素材列表 // @Tags MpMaterial // @Summary 获取素材列表 // @Description 获取公众号素材列表 // @Accept json // @Produce json // @Param page query int false "页码" // @Param pageSize query int false "每页数量" // @Param materialType query string false "素材类型" // @Param permanent query bool false "是否永久素材" // @Success 200 {object} response.Response{data=response.PageResult} "获取成功" // @Router /wechat/mp/material [get] func (m *MpMaterialApi) GetMaterialList(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10")) materialType := c.Query("materialType") var permanent *bool if p := c.Query("permanent"); p != "" { if perm, err := strconv.ParseBool(p); err == nil { permanent = &perm } } if page <= 0 { page = 1 } if pageSize <= 0 || pageSize > 100 { pageSize = 10 } materials, total, err := mpMaterialService.GetMaterialList(page, pageSize, materialType, permanent) if err != nil { global.GVA_LOG.Error("获取素材列表失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithDetailed(wechatResponse.PageResult{ List: materials, Total: total, Page: page, PageSize: pageSize, }, "获取成功", c) } // GetMaterialByID 获取素材详情 // @Tags MpMaterial // @Summary 获取素材详情 // @Description 根据ID获取素材详细信息 // @Accept json // @Produce json // @Param id path int true "素材ID" // @Success 200 {object} response.Response{data=model.MpMaterial} "获取成功" // @Router /wechat/mp/material/{id} [get] func (m *MpMaterialApi) GetMaterialByID(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.FailWithMessage("无效的素材ID", c) return } material, err := mpMaterialService.GetMaterialByID(uint(id)) if err != nil { global.GVA_LOG.Error("获取素材详情失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithData(material, c) } // UploadTempMaterial 上传临时素材 // @Tags MpMaterial // @Summary 上传临时素材 // @Description 上传临时素材到微信服务器 // @Accept multipart/form-data // @Produce json // @Param file formData file true "素材文件" // @Param type formData string true "素材类型:image、voice、video、thumb" // @Success 200 {object} response.Response{data=model.MpMaterial} "上传成功" // @Router /wechat/mp/material/temp [post] func (m *MpMaterialApi) UploadTempMaterial(c *gin.Context) { // 获取上传的文件 file, header, err := c.Request.FormFile("file") if err != nil { response.FailWithMessage("获取文件失败: "+err.Error(), c) return } defer file.Close() materialType := c.PostForm("type") if materialType == "" { response.FailWithMessage("素材类型不能为空", c) return } // 验证素材类型 validTypes := map[string]bool{ "image": true, "voice": true, "video": true, "thumb": true, } if !validTypes[materialType] { response.FailWithMessage("无效的素材类型", c) return } material, err := mpMaterialService.UploadTempMaterial(file, header.Filename, materialType) if err != nil { global.GVA_LOG.Error("上传临时素材失败!", zap.Error(err)) response.FailWithMessage("上传失败: "+err.Error(), c) return } response.OkWithDetailed(material, "上传成功", c) } // UploadPermanentMaterial 上传永久素材 // @Tags MpMaterial // @Summary 上传永久素材 // @Description 上传永久素材到微信服务器 // @Accept multipart/form-data // @Produce json // @Param file formData file true "素材文件" // @Param type formData string true "素材类型:image、voice、video、thumb" // @Success 200 {object} response.Response{data=model.MpMaterial} "上传成功" // @Router /wechat/mp/material/permanent [post] func (m *MpMaterialApi) UploadPermanentMaterial(c *gin.Context) { // 获取上传的文件 file, header, err := c.Request.FormFile("file") if err != nil { response.FailWithMessage("获取文件失败: "+err.Error(), c) return } defer file.Close() materialType := c.PostForm("type") if materialType == "" { response.FailWithMessage("素材类型不能为空", c) return } // 验证素材类型 validTypes := map[string]bool{ "image": true, "voice": true, "video": true, "thumb": true, } if !validTypes[materialType] { response.FailWithMessage("无效的素材类型", c) return } material, err := mpMaterialService.UploadPermanentMaterial(file, header.Filename, materialType) if err != nil { global.GVA_LOG.Error("上传永久素材失败!", zap.Error(err)) response.FailWithMessage("上传失败: "+err.Error(), c) return } response.OkWithDetailed(material, "上传成功", c) } // DeleteMaterial 删除素材 // @Tags MpMaterial // @Summary 删除素材 // @Description 删除指定的素材 // @Accept json // @Produce json // @Param id path int true "素材ID" // @Success 200 {object} response.Response "删除成功" // @Router /wechat/mp/material/{id} [delete] func (m *MpMaterialApi) DeleteMaterial(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.FailWithMessage("无效的素材ID", c) return } err = mpMaterialService.DeleteMaterial(uint(id)) if err != nil { global.GVA_LOG.Error("删除素材失败!", zap.Error(err)) response.FailWithMessage("删除失败: "+err.Error(), c) return } response.OkWithMessage("删除成功", c) } // GetMaterialByMediaID 根据MediaID获取素材 // @Tags MpMaterial // @Summary 根据MediaID获取素材 // @Description 根据微信MediaID获取素材信息 // @Accept json // @Produce json // @Param mediaId query string true "微信MediaID" // @Success 200 {object} response.Response{data=model.MpMaterial} "获取成功" // @Router /wechat/mp/material/media [get] func (m *MpMaterialApi) GetMaterialByMediaID(c *gin.Context) { mediaID := c.Query("mediaId") if mediaID == "" { response.FailWithMessage("MediaID不能为空", c) return } material, err := mpMaterialService.GetMaterialByMediaID(mediaID) if err != nil { global.GVA_LOG.Error("获取素材失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithData(material, c) } // DownloadMaterial 下载素材 // @Tags MpMaterial // @Summary 下载素材 // @Description 从微信服务器下载素材 // @Accept json // @Produce json // @Param mediaId query string true "素材MediaID" // @Success 200 {object} response.Response "下载成功" // @Router /wechat/mp/material/download [get] func (m *MpMaterialApi) DownloadMaterial(c *gin.Context) { mediaID := c.Query("mediaId") if mediaID == "" { response.FailWithMessage("MediaID不能为空", c) return } reader, filename, err := mpMaterialService.DownloadMaterial(mediaID) if err != nil { global.GVA_LOG.Error("下载素材失败!", zap.Error(err)) response.FailWithMessage("下载失败: "+err.Error(), c) return } defer reader.Close() // 设置响应头 c.Header("Content-Disposition", "attachment; filename="+filename) c.Header("Content-Type", "application/octet-stream") // 将文件内容写入响应 _, err = io.Copy(c.Writer, reader) if err != nil { global.GVA_LOG.Error("写入响应失败!", zap.Error(err)) response.FailWithMessage("下载失败", c) return } } // SyncMaterials 同步素材 // @Tags MpMaterial // @Summary 同步素材 // @Description 从微信服务器同步素材列表 // @Accept json // @Produce json // @Success 200 {object} response.Response "同步成功" // @Router /wechat/mp/material/sync [post] func (m *MpMaterialApi) SyncMaterials(c *gin.Context) { err := mpMaterialService.SyncMaterialsFromWechat() if err != nil { global.GVA_LOG.Error("同步素材失败!", zap.Error(err)) response.FailWithMessage("同步失败: "+err.Error(), c) return } response.OkWithMessage("同步成功", c) }