339 lines
7.2 KiB
Go
339 lines
7.2 KiB
Go
|
package gpt
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"encoding/json"
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
"io"
|
|||
|
"net/http"
|
|||
|
"regexp"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
var (
|
|||
|
host string
|
|||
|
telNum string
|
|||
|
password string
|
|||
|
)
|
|||
|
|
|||
|
type auth struct {
|
|||
|
expiredAt time.Time
|
|||
|
auth string
|
|||
|
}
|
|||
|
|
|||
|
type LoginData struct {
|
|||
|
Status int `json:"status"`
|
|||
|
Data User `json:"data"`
|
|||
|
Msg string `json:"msg"`
|
|||
|
Code int `json:"code"`
|
|||
|
Error interface{} `json:"error"`
|
|||
|
Err string `json:"err"`
|
|||
|
Keys []string `json:"keys"`
|
|||
|
}
|
|||
|
type User struct {
|
|||
|
Token string `json:"Token"`
|
|||
|
}
|
|||
|
|
|||
|
type GptRes struct {
|
|||
|
Status int `json:"status"`
|
|||
|
Data Data `json:"data"`
|
|||
|
Msg string `json:"msg"`
|
|||
|
Code int `json:"code"`
|
|||
|
Error interface{} `json:"error"`
|
|||
|
Err string `json:"err"`
|
|||
|
Keys interface{} `json:"keys"`
|
|||
|
}
|
|||
|
|
|||
|
type Data struct {
|
|||
|
Answer string `json:"answer"`
|
|||
|
}
|
|||
|
|
|||
|
var authObj = auth{}
|
|||
|
|
|||
|
func InitSet(tempHost, tel, paw string) {
|
|||
|
host = tempHost
|
|||
|
telNum = tel
|
|||
|
password = paw
|
|||
|
}
|
|||
|
|
|||
|
// 登陆url
|
|||
|
func getGetLoginUrl() string {
|
|||
|
return host + "/user/login"
|
|||
|
}
|
|||
|
|
|||
|
func getGptTextUrl() string {
|
|||
|
return host + "/chat/completion-text"
|
|||
|
}
|
|||
|
|
|||
|
// getLoginAuth 冲登陆中获取 登陆标志
|
|||
|
func getLoginAuth() (string, error) {
|
|||
|
|
|||
|
userRes := &LoginData{}
|
|||
|
//登陆
|
|||
|
bodyStr := `{"TelNum": "` + telNum + `","Password": "` + password + `"}`
|
|||
|
|
|||
|
// 目标URL
|
|||
|
url := getGetLoginUrl()
|
|||
|
|
|||
|
fmt.Println(bodyStr)
|
|||
|
// 创建POST请求
|
|||
|
requestObj, err := http.NewRequest("POST", url, bytes.NewBufferString(bodyStr))
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error creating request:", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 设置Headers
|
|||
|
requestObj.Header.Set("Content-Type", "application/json")
|
|||
|
// 初始化HTTP客户端
|
|||
|
client := &http.Client{}
|
|||
|
fmt.Println(1)
|
|||
|
|
|||
|
// 发送请求
|
|||
|
response, err := client.Do(requestObj)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error sending POST request:", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer response.Body.Close()
|
|||
|
fmt.Println(2)
|
|||
|
|
|||
|
// 检查HTTP响应状态码
|
|||
|
if response.StatusCode != http.StatusOK {
|
|||
|
fmt.Printf("Error: HTTP status code is %d\n", response.StatusCode)
|
|||
|
return "", errors.New(fmt.Sprintf("Error: HTTP status code is %d\n", response.StatusCode))
|
|||
|
}
|
|||
|
|
|||
|
fmt.Println(3)
|
|||
|
// 直接将响应内容复制到标准输出
|
|||
|
body, err := io.ReadAll(response.Body)
|
|||
|
if err != nil {
|
|||
|
// 处理复制内容时出现的错误
|
|||
|
fmt.Printf("Error copying response to stdout: %s\n", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
fmt.Println(4)
|
|||
|
err = json.Unmarshal(body, &userRes)
|
|||
|
if err != nil {
|
|||
|
// 处理复制内容时出现的错误
|
|||
|
fmt.Printf("json.Error copying response to stdout: %s\n", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
if userRes.Status != 0 {
|
|||
|
// 处理复制内容时出现的错误
|
|||
|
fmt.Printf("json.Error copying response to stdout: %s\n", err)
|
|||
|
return "", errors.New("翻译失败,帐号信息 " + userRes.Msg)
|
|||
|
}
|
|||
|
|
|||
|
return userRes.Data.Token, nil
|
|||
|
}
|
|||
|
|
|||
|
// getLoginAuth 获取登陆标志,过期则重新获取
|
|||
|
func getAuth() (string, error) {
|
|||
|
|
|||
|
fmt.Println(authObj.expiredAt)
|
|||
|
fmt.Println(authObj.expiredAt.After(time.Now()))
|
|||
|
|
|||
|
//帐号未过期
|
|||
|
if authObj.expiredAt.After(time.Now()) {
|
|||
|
return authObj.auth, nil
|
|||
|
}
|
|||
|
|
|||
|
//重新获取
|
|||
|
authCode, err := getLoginAuth()
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
authObj.expiredAt = time.Now().Add(2 * time.Hour)
|
|||
|
authObj.auth = authCode
|
|||
|
return authCode, err
|
|||
|
}
|
|||
|
|
|||
|
func setAuthExpire() {
|
|||
|
authObj.expiredAt = authObj.expiredAt.AddDate(-1, 0, 0)
|
|||
|
}
|
|||
|
|
|||
|
// GptContentLand gpt翻译成语言
|
|||
|
func GptContentLand(content, land string) (newContent string, err error) {
|
|||
|
if isDefaultLang(land) {
|
|||
|
return content, nil
|
|||
|
}
|
|||
|
|
|||
|
val := cache.RedisClient.HGet(cache.GetLangHashKey(land), content).Val()
|
|||
|
|
|||
|
if val != "" {
|
|||
|
return val, nil
|
|||
|
}
|
|||
|
|
|||
|
newContent, err = realGptContentLand(content, land)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
cache.RedisClient.HSet(cache.GetLangHashKey(land), content, newContent)
|
|||
|
|
|||
|
return newContent, err
|
|||
|
}
|
|||
|
|
|||
|
func isDefaultLang(lang string) bool {
|
|||
|
|
|||
|
if lang != "Ja" && lang != "ZhTW" && lang != "EN" {
|
|||
|
return true
|
|||
|
}
|
|||
|
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// realGptContentLand gpt翻译成语言
|
|||
|
func realGptContentLand(content, land string) (newContent string, err error) {
|
|||
|
|
|||
|
if land == "Ja" {
|
|||
|
newContent, err = gptContent("翻译成日语:" + content)
|
|||
|
fmt.Println(newContent)
|
|||
|
|
|||
|
} else if land == "ZhTW" {
|
|||
|
newContent, err = gptContent("翻译成繁体:" + content)
|
|||
|
} else if land == "EN" {
|
|||
|
newContent, err = gptContent("翻译成英语:" + content)
|
|||
|
if err == nil {
|
|||
|
parts := strings.Split(newContent, "\n")
|
|||
|
fmt.Println(newContent)
|
|||
|
fmt.Println(parts)
|
|||
|
if len(parts) > 1 {
|
|||
|
newContent = parts[1]
|
|||
|
newContent = strings.Replace(newContent, "\\", "", 0)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
newContent = content
|
|||
|
}
|
|||
|
|
|||
|
//去重空格
|
|||
|
fmt.Println("1-------", newContent)
|
|||
|
newContent = removeAfterNewline(newContent)
|
|||
|
|
|||
|
fmt.Println("2-------", newContent)
|
|||
|
|
|||
|
return newContent, err
|
|||
|
}
|
|||
|
|
|||
|
func removeAfterNewline(s string) string {
|
|||
|
// 编译正则表达式,匹配第一个换行符(包括 \n, \r\n, \r)及其后的内容
|
|||
|
re := regexp.MustCompile(`(\r\n|\r|\n|\\n).*`)
|
|||
|
// 替换匹配部分为空字符串
|
|||
|
return re.ReplaceAllString(s, "")
|
|||
|
}
|
|||
|
|
|||
|
func gptContent(content string) (string, error) {
|
|||
|
|
|||
|
authCode, err := getAuth()
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
fmt.Println(content)
|
|||
|
|
|||
|
res, err := getGptContent(content, authCode)
|
|||
|
if err != nil {
|
|||
|
errMsg := err.Error()
|
|||
|
if errMsg == "请先登陆" {
|
|||
|
setAuthExpire()
|
|||
|
authCode1, err1 := getAuth()
|
|||
|
if err1 != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
res1, err1 := getGptContent(content, authCode1)
|
|||
|
if err1 != nil {
|
|||
|
return "", err1
|
|||
|
}
|
|||
|
return res1, nil
|
|||
|
}
|
|||
|
return "", err
|
|||
|
}
|
|||
|
return res, nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// GetGptContent 获取翻译
|
|||
|
func getGptContent(content, authCode string) (string, error) {
|
|||
|
var res *GptRes
|
|||
|
|
|||
|
if content == "" {
|
|||
|
return "", errors.New("内容不能为空")
|
|||
|
}
|
|||
|
|
|||
|
//增加文字的黄反鉴别
|
|||
|
strBody := `{
|
|||
|
"model": "gpt-4-1106-preview",
|
|||
|
"max_tokens": 1000,
|
|||
|
"temperature": 1,
|
|||
|
"top_p": 1,
|
|||
|
"presence_penalty": 0,
|
|||
|
"frequency_penalty": 0,
|
|||
|
"messages": [
|
|||
|
{
|
|||
|
"role": "user",
|
|||
|
"content": "` + content + `"
|
|||
|
}
|
|||
|
],
|
|||
|
"listUuid": "",
|
|||
|
"stream": true
|
|||
|
}`
|
|||
|
|
|||
|
// 目标URL
|
|||
|
url := getGptTextUrl()
|
|||
|
|
|||
|
// 创建POST请求
|
|||
|
requestObj, err := http.NewRequest("POST", url, bytes.NewBufferString(strBody))
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error creating request:", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 设置Headers
|
|||
|
requestObj.Header.Set("Content-Type", "application/json")
|
|||
|
requestObj.Header.Set("Authorization", authCode)
|
|||
|
|
|||
|
// 初始化HTTP客户端
|
|||
|
client := &http.Client{}
|
|||
|
|
|||
|
// 发送请求
|
|||
|
response, err := client.Do(requestObj)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error sending POST request:", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer response.Body.Close()
|
|||
|
|
|||
|
// 检查HTTP响应状态码
|
|||
|
if response.StatusCode != http.StatusOK {
|
|||
|
fmt.Printf("Error: HTTP status code is %d\n", response.StatusCode)
|
|||
|
return "", errors.New(fmt.Sprintf("Error: HTTP status code is %d\n", response.StatusCode))
|
|||
|
}
|
|||
|
|
|||
|
// 直接将响应内容复制到标准输出
|
|||
|
body, err := io.ReadAll(response.Body)
|
|||
|
if err != nil {
|
|||
|
// 处理复制内容时出现的错误
|
|||
|
fmt.Printf("Error copying response to stdout: %s\n", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
err = json.Unmarshal(body, &res)
|
|||
|
if err != nil {
|
|||
|
// 处理复制内容时出现的错误
|
|||
|
fmt.Printf("json.Error copying response to stdout: %s\n", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
if res.Status != 0 {
|
|||
|
return "", errors.New(res.Msg)
|
|||
|
}
|
|||
|
|
|||
|
return res.Data.Answer, nil
|
|||
|
}
|