153 lines
4.5 KiB
Go
153 lines
4.5 KiB
Go
package service
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"log"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/parnurzeal/gorequest"
|
||
)
|
||
|
||
// ErrPasswordWrong 账号或密码错误,不再重试
|
||
var ErrPasswordWrong = errors.New("孔网账号或密码错误")
|
||
|
||
// UserInfo 孔网用户信息结构体
|
||
type UserInfo struct {
|
||
UserID int64 `json:"userId"` // 用户ID
|
||
Nickname string `json:"nickname"` // 用户昵称
|
||
Mobile string `json:"mobile"` // 手机号
|
||
Token string `json:"token"` // token
|
||
}
|
||
|
||
/*
|
||
* 孔网登录
|
||
* param username[string] 孔网用户名
|
||
* param password[string] 孔网密码
|
||
* return token,错误信息
|
||
*/
|
||
func OutKfzLogin(username, password string) (string, error) {
|
||
if username == "" || password == "" {
|
||
return "", fmt.Errorf("请输入用户名和密码!")
|
||
}
|
||
|
||
formData := map[string]string{
|
||
"loginName": username,
|
||
"loginPass": password,
|
||
"returnUrl": "http://user.kongfz.com/",
|
||
}
|
||
loginUrl := "https://login.kongfz.com/Pc/Login/account"
|
||
|
||
resp, body, errs := gorequest.New().
|
||
Post(loginUrl).
|
||
Set("Content-Type", "application/x-www-form-urlencoded").
|
||
Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36").
|
||
Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8").
|
||
Send(formData).
|
||
Timeout(15 * time.Second).
|
||
End()
|
||
|
||
if len(errs) > 0 {
|
||
return "", fmt.Errorf("登录请求失败: %v", errs)
|
||
}
|
||
|
||
if resp.StatusCode != http.StatusOK {
|
||
return "", fmt.Errorf("登录失败(HTTP状态码: %d)", resp.StatusCode)
|
||
}
|
||
|
||
cookie := resp.Header.Get("Set-Cookie")
|
||
if strings.Contains(body, "window.location.href='https://login.kongfz.cn/Pc/Session/rsync") {
|
||
if cookie == "" {
|
||
return "", fmt.Errorf("登录成功但未获取到Cookie")
|
||
}
|
||
if strings.Contains(cookie, "PHPSESSID=") {
|
||
token := strings.Split(strings.Split(cookie, "PHPSESSID=")[1], ";")[0]
|
||
return token, nil
|
||
}
|
||
return "", fmt.Errorf("登录失败: 未找到PHPSESSID")
|
||
}
|
||
|
||
var res struct {
|
||
Status bool `json:"status"`
|
||
ErrCode int `json:"errCode"`
|
||
ErrInfo string `json:"errInfo"`
|
||
}
|
||
if err := json.Unmarshal([]byte(body), &res); err == nil {
|
||
if res.ErrCode == 1001 || res.ErrCode == 1005 {
|
||
return "", fmt.Errorf("账号或密码错误!")
|
||
}
|
||
if res.ErrInfo != "" {
|
||
return "", fmt.Errorf("登录失败: %s", res.ErrInfo)
|
||
}
|
||
}
|
||
|
||
return "", fmt.Errorf("登录失败,未知错误!")
|
||
}
|
||
|
||
/*
|
||
* 获取孔网用户信息
|
||
*/
|
||
func OutKfzGetUserInfo(token string) (*UserInfo, error) {
|
||
url := "https://user.kongfz.com/User/Index/getUserInfo/"
|
||
resp, body, errs := gorequest.New().
|
||
Get(url).
|
||
Set("Cookie", fmt.Sprintf("PHPSESSID=%s", token)).
|
||
Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").
|
||
Set("Accept", "application/json, text/plain, */*").
|
||
Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8").
|
||
Timeout(15 * time.Second).
|
||
End()
|
||
|
||
if len(errs) > 0 {
|
||
return nil, fmt.Errorf("查询用户信息请求失败: %v", errs)
|
||
}
|
||
if resp.StatusCode != http.StatusOK {
|
||
return nil, fmt.Errorf("HTTP错误: %s", resp.Status)
|
||
}
|
||
|
||
var userInfo struct {
|
||
Status bool `json:"status"`
|
||
Data struct {
|
||
UserID int64 `json:"userId"`
|
||
Nickname string `json:"nickname"`
|
||
Mobile string `json:"mobile"`
|
||
}
|
||
}
|
||
if err := json.Unmarshal([]byte(body), &userInfo); err != nil {
|
||
return nil, fmt.Errorf("解析JSON失败: %w", err)
|
||
}
|
||
|
||
user := &UserInfo{}
|
||
if !userInfo.Status {
|
||
return nil, fmt.Errorf("获取用户失败!")
|
||
}
|
||
user.UserID = userInfo.Data.UserID
|
||
user.Nickname = userInfo.Data.Nickname
|
||
user.Mobile = userInfo.Data.Mobile
|
||
return user, nil
|
||
}
|
||
|
||
// TryRefreshToken 尝试用保存的密码重新登录,更新token。成功返回新token
|
||
// 密码错误时返回 ErrPasswordWrong
|
||
func (s *GoodsService) TryRefreshToken(tokenID int64, username, password string) (string, error) {
|
||
log.Printf("[RefreshToken] 开始重新登录: username=%s, tokenID=%d", username, tokenID)
|
||
newToken, err := OutKfzLogin(username, password)
|
||
if err != nil {
|
||
log.Printf("[RefreshToken] 重新登录失败: username=%s, 错误=%v", username, err)
|
||
if strings.Contains(err.Error(), "账号或密码错误") {
|
||
return "", ErrPasswordWrong
|
||
}
|
||
return "", err
|
||
}
|
||
// 更新数据库中的token
|
||
if err := s.tokenRepository.UpdateToken(tokenID, newToken); err != nil {
|
||
log.Printf("[RefreshToken] 更新Token失败: id=%d, 错误=%v", tokenID, err)
|
||
return "", err
|
||
}
|
||
log.Printf("[RefreshToken] 重新登录并更新Token成功: username=%s, tokenID=%d", username, tokenID)
|
||
return newToken, nil
|
||
}
|