package cpdaily import ( "crypto/tls" "encoding/json" "fmt" "io" "strings" "time" "github.com/go-resty/resty/v2" ) // 创建 Resty 客户端 func newMobileClient() *resty.Client { return resty.New(). SetTimeout(15*time.Second). SetDoNotParseResponse(true). SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) } // FetchUserProfile 从 cpdaily 获取用户主页信息 // 使用 wecloud getCurrentUserId API 获取姓名+头像,不再尝试获取手机号 func FetchUserProfile(cookieMap map[string]string, wecloudUrl string) (*CpdailyUserProfile, error) { if wecloudUrl != "" { if p, err := fetchFromWecloud(wecloudUrl, cookieMap); err == nil && p.Name != "" { return p, nil } } return nil, fmt.Errorf("无法获取用户信息") } // fetchFromWecloud 通过 campusphere.net 获取用户基本信息 func fetchFromWecloud(wecloudUrl string, cookieMap map[string]string) (*CpdailyUserProfile, error) { host := strings.TrimSuffix(wecloudUrl, "/") cookieStr := cookiesToStr(cookieMap) client := newMobileClient() resp, err := client.R(). SetHeader("User-Agent", "Mozilla/5.0 (Linux; Android 15; Redmi Note 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.81 Mobile Safari/537.36 cpdaily/9.9.6 wisedu/9.9.6"). SetHeader("CpdailyClientType", "CPDAILY"). SetHeader("Cookie", cookieStr). Get(host + "/wec-im-group/group/groupMember/getCurrentUserId") if err != nil { return nil, fmt.Errorf("请求 wecloud 用户信息失败: %w", err) } defer resp.RawBody().Close() body, _ := io.ReadAll(resp.RawBody()) var result struct { ErrCode int `json:"errCode"` ErrMsg string `json:"errMsg"` Data *struct { UserName string `json:"userName"` AvatarUrl string `json:"avatarUrl"` MobilePhone string `json:"mobilePhone"` } `json:"data"` } if err := json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("解析 wecloud 用户信息失败: %w", err) } if result.ErrCode != 0 || result.Data == nil { return nil, fmt.Errorf("wecloud 用户信息接口错误(%d): %s", result.ErrCode, result.ErrMsg) } return &CpdailyUserProfile{ Name: result.Data.UserName, Img: result.Data.AvatarUrl, MobilePhone: result.Data.MobilePhone, }, nil } // cookiesToStr 将 cookie map 转为 cookie 字符串 func cookiesToStr(cookieMap map[string]string) string { var parts []string for k, v := range cookieMap { parts = append(parts, k+"="+v) } return strings.Join(parts, "; ") } // ParseCookieJSON 将 JSON cookie 字符串解析为 map func ParseCookieJSON(cookieJSON string) map[string]string { cookieMap := make(map[string]string) json.Unmarshal([]byte(cookieJSON), &cookieMap) return cookieMap }