mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-09-16 18:27:13 +00:00
d4fd38ab7e
- 同步 Plus v4.3.1 功能源并移除商业 License 闭环 - 更新开源镜像命名、Docker 部署版本和 geekai 数据库配置 - 补充前端 ESLint 检查配置并修复存量解析与模板问题 - 保留 JWT、管理员权限、API Key 和 OAuth 等正常鉴权机制
106 lines
2.6 KiB
Go
106 lines
2.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"geekai/core/types"
|
|
"geekai/store/model"
|
|
"geekai/utils"
|
|
"sync"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// WxGzhService 微信公众号服务
|
|
type WxGzhService struct {
|
|
config types.WxGzhConfig
|
|
DB *gorm.DB
|
|
|
|
ccMu sync.Mutex
|
|
ccToken string
|
|
ccExpire time.Time
|
|
ccForApp string
|
|
}
|
|
|
|
func (s *WxGzhService) UpdateConfig(config types.WxGzhConfig) {
|
|
s.config = config
|
|
s.ccMu.Lock()
|
|
s.ccToken = ""
|
|
s.ccExpire = time.Time{}
|
|
s.ccForApp = ""
|
|
s.ccMu.Unlock()
|
|
}
|
|
|
|
func (s *WxGzhService) GetConfig() types.WxGzhConfig {
|
|
return s.config
|
|
}
|
|
|
|
func (s *WxGzhService) SetConfig(config types.WxGzhConfig) {
|
|
s.config = config
|
|
}
|
|
|
|
func NewWxGzhService(config *types.SystemConfig, db *gorm.DB) *WxGzhService {
|
|
return &WxGzhService{config: config.WxGzh, DB: db}
|
|
}
|
|
|
|
// GetOpenIDByCode 根据 code 获取 openid 和 access_token
|
|
func (s *WxGzhService) GetOpenIDByCode(code string) (string, string, error) {
|
|
|
|
var config model.Config
|
|
s.DB.Where("name", types.ConfigKeyWxGzh).First(&config)
|
|
|
|
var value map[string]any
|
|
err := utils.JsonDecode(config.Value, &value)
|
|
|
|
url := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
|
|
value["app_id"], value["secret"], code)
|
|
|
|
body, status, err := utils.FetchURLBytes(context.Background(), url, "", 30*time.Second, 2, 2<<20)
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("wx get openid failed: status=%d: %w", status, err)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
err = json.Unmarshal(body, &result)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
if openID, ok := result["openid"].(string); ok {
|
|
if accessToken, ok := result["access_token"].(string); ok {
|
|
return openID, accessToken, nil
|
|
}
|
|
}
|
|
|
|
if errMsg, ok := result["errmsg"].(string); ok {
|
|
return "", "", fmt.Errorf("微信 API 错误: %s", errMsg)
|
|
}
|
|
|
|
return "", "", fmt.Errorf("获取 openid 和 access_token 失败: %s", string(body))
|
|
}
|
|
|
|
// GetUserInfo 获取微信用户昵称和头像
|
|
func (s *WxGzhService) GetUserInfo(accessToken string, openID string) (map[string]any, error) {
|
|
url := fmt.Sprintf("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
|
|
accessToken, openID)
|
|
|
|
body, status, err := utils.FetchURLBytes(context.Background(), url, "", 30*time.Second, 2, 2<<20)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("wx get userinfo failed: status=%d: %w", status, err)
|
|
}
|
|
|
|
var result map[string]any
|
|
err = json.Unmarshal(body, &result)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if errMsg, ok := result["errmsg"].(string); ok {
|
|
return nil, fmt.Errorf("微信 API 错误: %s", errMsg)
|
|
}
|
|
|
|
return result, nil
|
|
}
|