commit
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ai_xhs/config"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type XHSService struct{}
|
||||
@@ -38,128 +40,93 @@ type LoginResponse struct {
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// SendVerificationCode 调用Python脚本发送验证码
|
||||
// SendVerificationCode 调用Python HTTP API发送验证码
|
||||
func (s *XHSService) SendVerificationCode(phone, countryCode string) (*SendCodeResponse, error) {
|
||||
// 如果没有传国家码,默认使用+86
|
||||
if countryCode == "" {
|
||||
countryCode = "+86"
|
||||
}
|
||||
|
||||
// 获取Python脚本路径和venv中的Python解释器
|
||||
backendDir := filepath.Join("..", "backend")
|
||||
pythonScript := filepath.Join(backendDir, "xhs_cli.py")
|
||||
// 获取Python服务地址
|
||||
pythonURL := config.GetPythonServiceURL()
|
||||
apiURL := fmt.Sprintf("%s/api/xhs/send-code", pythonURL)
|
||||
|
||||
// 使用venv中的Python解释器 (跨平台)
|
||||
pythonCmd := getPythonPath(backendDir)
|
||||
|
||||
// 执行Python脚本
|
||||
cmd := exec.Command(pythonCmd, pythonScript, "send_code", phone, countryCode)
|
||||
|
||||
// 设置工作目录为Python脚本所在目录
|
||||
cmd.Dir = backendDir
|
||||
|
||||
// 捕获输出
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
// 执行命令
|
||||
err := cmd.Run()
|
||||
|
||||
// 打印Python脚本的日志输出(stderr)
|
||||
if stderr.Len() > 0 {
|
||||
log.Printf("[Python日志-发送验证码] %s", stderr.String())
|
||||
// 构造请求体
|
||||
reqData := map[string]interface{}{
|
||||
"phone": phone,
|
||||
"country_code": countryCode,
|
||||
}
|
||||
|
||||
reqBody, _ := json.Marshal(reqData)
|
||||
|
||||
// 发送HTTP POST请求
|
||||
client := &http.Client{
|
||||
Timeout: 60 * time.Second, // 60秒超时
|
||||
}
|
||||
resp, err := client.Post(apiURL, "application/json", bytes.NewBuffer(reqBody))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("执行Python脚本失败: %w, stderr: %s", err, stderr.String())
|
||||
return nil, fmt.Errorf("调用Python服务失败: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 读取响应
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取响应失败: %w", err)
|
||||
}
|
||||
|
||||
// 获取UTF-8编码的输出
|
||||
outputStr := stdout.String()
|
||||
|
||||
// 解析JSON输出
|
||||
log.Printf("[Python API-发送验证码] 响应: %s", string(body))
|
||||
|
||||
// 解析JSON响应
|
||||
var result SendCodeResponse
|
||||
if err := json.Unmarshal([]byte(outputStr), &result); err != nil {
|
||||
return nil, fmt.Errorf("解析Python输出失败: %w, output: %s", err, outputStr)
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %w, body: %s", err, string(body))
|
||||
}
|
||||
|
||||
// 检查Python脚本返回的success字段
|
||||
if !result.Data["success"].(bool) {
|
||||
return &SendCodeResponse{
|
||||
Code: 1,
|
||||
Message: result.Data["error"].(string),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &SendCodeResponse{
|
||||
Code: 0,
|
||||
Message: "验证码已发送",
|
||||
Data: result.Data,
|
||||
}, nil
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// VerifyLogin 调用Python脚本验证登录
|
||||
// VerifyLogin 调用Python HTTP API验证登录
|
||||
func (s *XHSService) VerifyLogin(phone, code, countryCode string) (*LoginResponse, error) {
|
||||
// 如果没有传国家码,默认使用+86
|
||||
if countryCode == "" {
|
||||
countryCode = "+86"
|
||||
}
|
||||
|
||||
// 获取Python脚本路径和venv中的Python解释器
|
||||
backendDir := filepath.Join("..", "backend")
|
||||
pythonScript := filepath.Join(backendDir, "xhs_cli.py")
|
||||
// 获取Python服务地址
|
||||
pythonURL := config.GetPythonServiceURL()
|
||||
apiURL := fmt.Sprintf("%s/api/xhs/login", pythonURL)
|
||||
|
||||
// 使用venv中的Python解释器 (跨平台)
|
||||
pythonCmd := getPythonPath(backendDir)
|
||||
|
||||
// 执行Python脚本
|
||||
cmd := exec.Command(pythonCmd, pythonScript, "login", phone, code, countryCode)
|
||||
|
||||
// 设置工作目录
|
||||
cmd.Dir = backendDir
|
||||
|
||||
// 捕获输出
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
// 执行命令
|
||||
err := cmd.Run()
|
||||
|
||||
// 打印Python脚本的日志输出(stderr)
|
||||
if stderr.Len() > 0 {
|
||||
log.Printf("[Python日志-登录] %s", stderr.String())
|
||||
// 构造请求体
|
||||
reqData := map[string]interface{}{
|
||||
"phone": phone,
|
||||
"code": code,
|
||||
"country_code": countryCode,
|
||||
}
|
||||
|
||||
reqBody, _ := json.Marshal(reqData)
|
||||
|
||||
// 发送HTTP POST请求
|
||||
client := &http.Client{
|
||||
Timeout: 120 * time.Second, // 120秒超时(登录可能较慢)
|
||||
}
|
||||
resp, err := client.Post(apiURL, "application/json", bytes.NewBuffer(reqBody))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("执行Python脚本失败: %w, stderr: %s", err, stderr.String())
|
||||
return nil, fmt.Errorf("调用Python服务失败: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 读取响应
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取响应失败: %w", err)
|
||||
}
|
||||
|
||||
// 获取UTF-8编码的输出
|
||||
outputStr := stdout.String()
|
||||
|
||||
// 解析JSON输出
|
||||
log.Printf("[Python API-验证登录] 响应: %s", string(body))
|
||||
|
||||
// 解析JSON响应
|
||||
var result LoginResponse
|
||||
if err := json.Unmarshal([]byte(outputStr), &result); err != nil {
|
||||
return nil, fmt.Errorf("解析Python输出失败: %w, output: %s", err, outputStr)
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %w, body: %s", err, string(body))
|
||||
}
|
||||
|
||||
// 检查Python脚本返回的success字段
|
||||
if !result.Data["success"].(bool) {
|
||||
errorMsg := "登录失败"
|
||||
if errStr, ok := result.Data["error"].(string); ok {
|
||||
errorMsg = errStr
|
||||
}
|
||||
return &LoginResponse{
|
||||
Code: 1,
|
||||
Message: errorMsg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &LoginResponse{
|
||||
Code: 0,
|
||||
Message: "登录成功",
|
||||
Data: result.Data,
|
||||
}, nil
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user