daShangDao_kfz_goods_pricing/internal/handler/kfz_handler.go
97694732@qq.com e26d7a027e first commit
2026-06-11 16:06:08 +08:00

205 lines
5.4 KiB
Go

package handler
import (
"encoding/json"
"fmt"
"github.com/parnurzeal/gorequest"
"net/http"
"strings"
"time"
)
// KfzHandler Kfz处理器
type KfzHandler struct {
}
// NewKfzHandler 创建Kfz处理器实例
func NewKfzHandler() *KfzHandler {
return &KfzHandler{}
}
// KfzLogin 登录孔网并返回用户信息
func (h *KfzHandler) KfzLogin(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(32 << 20)
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
if username == "" || password == "" {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"code":500,"message":"username和password不能为空"}`))
return
}
token, err := outKfzLogin(username, password)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error())))
return
}
userInfo, err := outKfzGetUserInfo(token)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error())))
return
}
userInfo.Token = token
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"code": 200,
"message": "success",
"data": userInfo,
})
}
/*
* 孔网登录
* param username[string] 孔网用户名
* param password[string] 孔网密码
* return token,错误信息
* Error 登录请求失败
* Error 登录失败(HTTP状态码: %d)
* Error 登录成功但未获取到Cookie
* Error 登录失败: 未找到 PHPSESSID
* Error 账号或密码错误
* Error 登录失败
* Error 登录失败,未知错误!
*/
func outKfzLogin(username, password string) (string, error) {
// 检查用户名和密码是否为空
if username == "" || password == "" {
return "", fmt.Errorf("请输入用户名和密码!")
}
// 准备POST请求的表单数据
formData := map[string]string{
"loginName": username,
"loginPass": password,
"returnUrl": "http://user.kongfz.com/",
}
// 孔网登录URL
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)
}
// 检查HTTP状态码
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("登录失败(HTTP状态码: %d)", resp.StatusCode)
}
// 提取Cookie
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"`
}
// 解析json
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("登录失败,未知错误!")
}
// UserInfo 孔网用户信息结构体
type UserInfo struct {
UserID int64 `json:"userId"` // 用户ID
Nickname string `json:"nickname"` // 用户昵称
Mobile string `json:"mobile"` // 手机号
Token string `json:"token"` // token
}
/*
* 获取孔网用户信息
* param token[string] 孔网token
* return 孔网用户信息结构体,错误信息
* Error 查询请求失败
* Error HTTP错误
* Error 解析JSON失败
* Error 获取用户失败
*/
func outKfzGetUserInfo(token string) (*UserInfo, error) {
// 用户信息URL
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)
}
//检查HTTP状态码
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"`
}
}
// 解析json
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
}