package service import ( "errors" "fmt" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model" "github.com/silenceper/wechat/v2" "github.com/silenceper/wechat/v2/cache" "github.com/silenceper/wechat/v2/officialaccount" "github.com/silenceper/wechat/v2/officialaccount/basic" "github.com/silenceper/wechat/v2/officialaccount/config" ) type WechatMpService struct{} // GetWechatOfficialAccount 获取微信公众号实例 func (w *WechatMpService) GetWechatOfficialAccount(mpConfig *model.MpConfig) (*officialaccount.OfficialAccount, error) { if mpConfig == nil { return nil, errors.New("微信公众号配置不能为空") } if mpConfig.AppID == "" || mpConfig.AppSecret == "" { return nil, errors.New("微信公众号配置不完整") } wc := wechat.NewWechat() memory := cache.NewMemory() cfg := &config.Config{ AppID: mpConfig.AppID, AppSecret: mpConfig.AppSecret, Cache: memory, } // 如果有Token和EncodingAESKey,设置服务器配置 if mpConfig.Token != nil && *mpConfig.Token != "" { cfg.Token = *mpConfig.Token } if mpConfig.EncodingAESKey != nil && *mpConfig.EncodingAESKey != "" { cfg.EncodingAESKey = *mpConfig.EncodingAESKey } return wc.GetOfficialAccount(cfg), nil } // GenerateQrCode 生成公众号二维码 func (w *WechatMpService) GenerateQrCode(mpConfig *model.MpConfig) (string, error) { oa, err := w.GetWechatOfficialAccount(mpConfig) if err != nil { return "", err } // 获取基础服务 basicService := oa.GetBasic() // 创建永久二维码请求 qrRequest := basic.NewLimitQrRequest("mp_config_qr") // 获取二维码ticket ticket, err := basicService.GetQRTicket(qrRequest) if err != nil { global.GVA_LOG.Error("获取二维码ticket失败: " + err.Error()) return "", fmt.Errorf("获取二维码ticket失败: %v", err) } // 生成二维码图片URL qrCodeURL := basic.ShowQRCode(ticket) global.GVA_LOG.Info("生成公众号二维码成功: " + qrCodeURL) return qrCodeURL, nil } // ClearQuota 清空API配额 func (w *WechatMpService) ClearQuota(mpConfig *model.MpConfig) error { oa, err := w.GetWechatOfficialAccount(mpConfig) if err != nil { return err } // 调用清空API配额接口 basic := oa.GetBasic() err = basic.ClearQuota() if err != nil { global.GVA_LOG.Error("清空API配额失败: " + err.Error()) return fmt.Errorf("清空API配额失败: %v", err) } global.GVA_LOG.Info("清空API配额成功") return nil } // ValidateConfig 验证公众号配置 func (w *WechatMpService) ValidateConfig(mpConfig *model.MpConfig) error { oa, err := w.GetWechatOfficialAccount(mpConfig) if err != nil { return err } // 通过获取access_token来验证配置是否正确 basic := oa.GetBasic() token, err := basic.GetAccessToken() if err != nil { global.GVA_LOG.Error("验证公众号配置失败: " + err.Error()) return fmt.Errorf("验证配置失败: %v", err) } if token == "" { return errors.New("获取access_token失败,请检查AppID和AppSecret") } global.GVA_LOG.Info("验证公众号配置成功") return nil } // GetServerIPs 获取微信服务器IP地址 func (w *WechatMpService) GetServerIPs(mpConfig *model.MpConfig) ([]string, error) { oa, err := w.GetWechatOfficialAccount(mpConfig) if err != nil { return nil, err } basic := oa.GetBasic() ips, err := basic.GetCallbackIP() if err != nil { global.GVA_LOG.Error("获取微信服务器IP失败: " + err.Error()) return nil, fmt.Errorf("获取微信服务器IP失败: %v", err) } return ips, nil } // GetUserInfo 获取用户基本信息 func (w *WechatMpService) GetUserInfo(mpConfig *model.MpConfig, openID string) (map[string]interface{}, error) { oa, err := w.GetWechatOfficialAccount(mpConfig) if err != nil { return nil, err } user := oa.GetUser() userInfo, err := user.GetUserInfo(openID) if err != nil { global.GVA_LOG.Error("获取用户信息失败: " + err.Error()) return nil, fmt.Errorf("获取用户信息失败: %v", err) } return map[string]interface{}{ "openid": userInfo.OpenID, "nickname": userInfo.Nickname, "sex": userInfo.Sex, "province": userInfo.Province, "city": userInfo.City, "country": userInfo.Country, "headimgurl": userInfo.Headimgurl, "unionid": userInfo.UnionID, }, nil } // SendTextMessage 发送文本消息 (暂时注释,需要正确的API调用方式) // func (w *WechatMpService) SendTextMessage(mpConfig *model.MpConfig, openID, content string) error { // // TODO: 实现发送文本消息功能 // return errors.New("发送消息功能暂未实现") // }