fonchain-fiee/pkg/common/gpt/gpt.go

340 lines
7.2 KiB
Go
Raw Normal View History

2025-02-20 08:24:49 +00:00
package gpt
import (
"bytes"
"encoding/json"
"errors"
"fmt"
2025-02-20 11:52:27 +00:00
"fonchain-fiee/pkg/cache"
2025-02-20 08:24:49 +00:00
"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
}