165 lines
4.5 KiB
Go
165 lines
4.5 KiB
Go
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 MpService struct{}
|
||
|
||
// GetWechatOfficialAccount 获取微信公众号实例
|
||
func (w *MpService) 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 *MpService) 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 *MpService) 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 *MpService) 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 *MpService) 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 *MpService) 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 *MpService) SendTextMessage(mpConfig *model.MpConfig, openID, content string) error {
|
||
// // TODO: 实现发送文本消息功能
|
||
// return errors.New("发送消息功能暂未实现")
|
||
// }
|