package api import ( "strconv" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model" "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/request" 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 MpConfigApi struct{} var mpConfigService = service.ServiceGroupApp.MpConfigService // GetWechatConfig 获取微信配置 // @Tags MpConfig // @Summary 获取微信配置 // @Description 获取微信配置信息 // @Accept json // @Produce json // @Param type query string false "配置类型 mp/mini" // @Success 200 {object} response.Response{data=model.MpConfig} "获取成功" // @Router /wechat/mp/config [get] func (m *MpConfigApi) GetWechatConfig(c *gin.Context) { configType := c.DefaultQuery("type", "mp") config, err := mpConfigService.GetWechatConfig(configType) if err != nil { global.GVA_LOG.Error("获取微信配置失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithData(config, c) } // SaveWechatConfig 保存微信配置 // @Tags MpConfig // @Summary 保存微信配置 // @Description 保存微信配置信息 // @Accept json // @Produce json // @Param data body request.SaveMpConfigRequest true "配置信息" // @Success 200 {object} response.Response "保存成功" // @Router /wechat/mp/config [post] func (m *MpConfigApi) SaveWechatConfig(c *gin.Context) { var req request.SaveMpConfigRequest err := c.ShouldBindJSON(&req) if err != nil { response.FailWithMessage(err.Error(), c) return } // 将DTO转换为数据库实体 config := &model.MpConfig{ ConfigType: req.ConfigType, AppID: req.AppID, AppSecret: req.AppSecret, Token: req.Token, EncodingAESKey: req.EncodingAESKey, ServerURL: req.ServerURL, WebhookURL: req.WebhookURL, MiniAppName: req.MiniAppName, MiniAppDesc: req.MiniAppDesc, Status: req.Status, ExtraConfig: req.ExtraConfig, Remark: req.Remark, } // 验证配置 err = mpConfigService.ValidateConfig(config) if err != nil { response.FailWithMessage(err.Error(), c) return } err = mpConfigService.SaveWechatConfig(config) if err != nil { global.GVA_LOG.Error("保存微信配置失败!", zap.Error(err)) response.FailWithMessage("保存失败: "+err.Error(), c) return } response.OkWithData(config, c) } // TestWechatConfig 测试微信配置 // @Tags MpConfig // @Summary 测试微信配置 // @Description 测试微信配置是否有效 // @Accept json // @Produce json // @Param data body request.TestMpConfigRequest true "配置信息" // @Success 200 {object} response.Response "测试成功" // @Router /wechat/mp/config/test [post] func (m *MpConfigApi) TestWechatConfig(c *gin.Context) { var req request.TestMpConfigRequest err := c.ShouldBindJSON(&req) if err != nil { response.FailWithMessage(err.Error(), c) return } // 将DTO转换为数据库实体 config := &model.MpConfig{ ConfigType: req.ConfigType, AppID: req.AppID, AppSecret: req.AppSecret, Token: req.Token, EncodingAESKey: req.EncodingAESKey, ServerURL: req.ServerURL, WebhookURL: req.WebhookURL, MiniAppName: req.MiniAppName, MiniAppDesc: req.MiniAppDesc, } err = mpConfigService.TestWechatConfig(config) if err != nil { global.GVA_LOG.Error("测试微信配置失败!", zap.Error(err)) response.FailWithMessage("测试失败: "+err.Error(), c) return } response.OkWithMessage("测试成功", c) } // GetConfigList 获取配置列表 // @Tags MpConfig // @Summary 获取配置列表 // @Description 获取所有微信配置列表 // @Accept json // @Produce json // @Success 200 {object} response.Response{data=[]model.MpConfig} "获取成功" // @Router /wechat/mp/config/list [get] func (m *MpConfigApi) GetConfigList(c *gin.Context) { configs, err := mpConfigService.GetConfigList() if err != nil { global.GVA_LOG.Error("获取配置列表失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithData(configs, c) } // DeleteConfig 删除配置 // @Tags MpConfig // @Summary 删除配置 // @Description 删除微信配置 // @Accept json // @Produce json // @Param id path int true "配置ID" // @Success 200 {object} response.Response "删除成功" // @Router /wechat/mp/config/{id} [delete] func (m *MpConfigApi) DeleteConfig(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.FailWithMessage("无效的配置ID", c) return } err = mpConfigService.DeleteConfig(uint(id)) if err != nil { global.GVA_LOG.Error("删除配置失败!", zap.Error(err)) response.FailWithMessage("删除失败: "+err.Error(), c) return } response.OkWithMessage("删除成功", c) } // GetWebhookLogs 获取Webhook日志 // @Tags MpConfig // @Summary 获取Webhook日志 // @Description 获取微信Webhook日志列表 // @Accept json // @Produce json // @Param page query int false "页码" // @Param pageSize query int false "每页数量" // @Param configId query int false "配置ID" // @Success 200 {object} response.Response{data=response.PageResult} "获取成功" // @Router /wechat/mp/webhook/logs [get] func (m *MpConfigApi) GetWebhookLogs(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10")) var configID *uint if configIDStr := c.Query("configId"); configIDStr != "" { if id, err := strconv.ParseUint(configIDStr, 10, 32); err == nil { configIDUint := uint(id) configID = &configIDUint } } if page <= 0 { page = 1 } if pageSize <= 0 || pageSize > 100 { pageSize = 10 } logs, total, err := mpConfigService.GetWebhookLogs(page, pageSize, configID) if err != nil { global.GVA_LOG.Error("获取Webhook日志失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithDetailed(wechatResponse.PageResult{ List: logs, Total: total, Page: page, PageSize: pageSize, }, "获取成功", c) } // GetWebhookLogDetail 获取Webhook日志详情 // @Tags MpConfig // @Summary 获取Webhook日志详情 // @Description 获取微信Webhook日志详情 // @Accept json // @Produce json // @Param id path int true "日志ID" // @Success 200 {object} response.Response{data=model.MpWebhookLog} "获取成功" // @Router /wechat/mp/webhook/logs/{id} [get] func (m *MpConfigApi) GetWebhookLogDetail(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.FailWithMessage("无效的日志ID", c) return } log, err := mpConfigService.GetWebhookLogByID(uint(id)) if err != nil { global.GVA_LOG.Error("获取Webhook日志详情失败!", zap.Error(err)) response.FailWithMessage("获取失败: "+err.Error(), c) return } response.OkWithData(log, c) } // ClearWebhookLogs 清空Webhook日志 // @Tags MpConfig // @Summary 清空Webhook日志 // @Description 清空微信Webhook日志 // @Accept json // @Produce json // @Param configId query int false "配置ID" // @Success 200 {object} response.Response "清空成功" // @Router /wechat/mp/webhook/logs/clear [post] func (m *MpConfigApi) ClearWebhookLogs(c *gin.Context) { var configID *uint if configIDStr := c.Query("configId"); configIDStr != "" { if id, err := strconv.ParseUint(configIDStr, 10, 32); err == nil { configIDUint := uint(id) configID = &configIDUint } } err := mpConfigService.ClearWebhookLogs(configID) if err != nil { global.GVA_LOG.Error("清空Webhook日志失败!", zap.Error(err)) response.FailWithMessage("清空失败: "+err.Error(), c) return } response.OkWithMessage("清空成功", c) } // ValidateConfig 验证微信配置 // @Tags MpConfig // @Summary 验证微信配置 // @Description 验证微信配置是否有效 // @Accept json // @Produce json // @Success 200 {object} response.Response "验证成功" // @Router /wechat/mp/config/validate [post] func (m *MpConfigApi) ValidateConfig(c *gin.Context) { // 获取当前配置 config, err := mpConfigService.GetWechatConfig("mp") if err != nil { global.GVA_LOG.Error("获取微信配置失败!", zap.Error(err)) response.FailWithMessage("获取配置失败: "+err.Error(), c) return } // 验证配置 err = mpConfigService.ValidateConfig(config) if err != nil { global.GVA_LOG.Error("验证微信配置失败!", zap.Error(err)) response.FailWithMessage("验证失败: "+err.Error(), c) return } // 使用微信公众号服务验证配置 wechatMpService := service.ServiceGroupApp.MpService err = wechatMpService.ValidateConfig(config) if err != nil { global.GVA_LOG.Error("配置连通性测试失败!", zap.Error(err)) response.FailWithMessage("配置连通性测试失败: "+err.Error(), c) return } response.OkWithMessage("验证成功", c) } // GenerateQrCode 生成公众号二维码 // @Tags MpConfig // @Summary 生成公众号二维码 // @Description 生成公众号二维码 // @Accept json // @Produce json // @Success 200 {object} response.Response{data=map[string]string} "生成成功" // @Router /wechat/mp/qrcode/generate [post] func (m *MpConfigApi) GenerateQrCode(c *gin.Context) { // 获取当前配置 config, err := mpConfigService.GetWechatConfig("mp") if err != nil { global.GVA_LOG.Error("获取微信配置失败!", zap.Error(err)) response.FailWithMessage("获取配置失败: "+err.Error(), c) return } // 生成二维码 qrCodeUrl, err := mpConfigService.GenerateQrCode(config) if err != nil { global.GVA_LOG.Error("生成二维码失败!", zap.Error(err)) response.FailWithMessage("生成失败: "+err.Error(), c) return } response.OkWithData(map[string]string{"qrCodeUrl": qrCodeUrl}, c) } // ClearQuota 清空API配额 // @Tags MpConfig // @Summary 清空API配额 // @Description 清空微信公众号API配额 // @Accept json // @Produce json // @Success 200 {object} response.Response "清空成功" // @Router /wechat/mp/quota/clear [post] func (m *MpConfigApi) ClearQuota(c *gin.Context) { // 获取当前配置 config, err := mpConfigService.GetWechatConfig("mp") if err != nil { global.GVA_LOG.Error("获取微信配置失败!", zap.Error(err)) response.FailWithMessage("获取配置失败: "+err.Error(), c) return } // 清空配额 err = mpConfigService.ClearQuota(config) if err != nil { global.GVA_LOG.Error("清空API配额失败!", zap.Error(err)) response.FailWithMessage("清空失败: "+err.Error(), c) return } response.OkWithMessage("清空成功", c) }