Files
RockYang d4fd38ab7e feat: 迁移 geekai-plus v4.3.1 到开源版
- 同步 Plus v4.3.1 功能源并移除商业 License 闭环
- 更新开源镜像命名、Docker 部署版本和 geekai 数据库配置
- 补充前端 ESLint 检查配置并修复存量解析与模板问题
- 保留 JWT、管理员权限、API Key 和 OAuth 等正常鉴权机制
2026-09-13 14:37:12 +08:00

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
}