fix(integration): 更新Authorization令牌并移除代理设置
- 替换camel_oil_api中CreateOrder方法的Authorization令牌 - 注释掉基于订单ID获取和设置代理IP的逻辑 feat(merchant): 使用SSE实现订单查询总结的流式返回 - 修改merchant_v1_order_query_summary中queryAppleResult为流式SSE返回 - 通过OpenAI流式API逐块发送总结内容,实时推送客户端 - 设置响应头支持SSE并在响应中刷新缓冲区 fix(api): 修正OrderQuerySummaryRes返回的内容类型 - 将OrderQuerySummaryRes结构的mime类型改为text/event-stream以支持流式响应
This commit is contained in:
@@ -34,6 +34,5 @@ type OrderQuerySummaryReq struct {
|
||||
}
|
||||
|
||||
type OrderQuerySummaryRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Message string `json:"message" dc:"结论"`
|
||||
g.Meta `mime:"text/event-stream"`
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/pointer"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/openai/openai-go/v3"
|
||||
"github.com/openai/openai-go/v3/option"
|
||||
"kami/internal/service"
|
||||
@@ -50,29 +51,63 @@ func (c *ControllerV1) OrderQuerySummary(ctx context.Context, req *v1.OrderQuery
|
||||
redeemRecord := queryRedeemCard(ctx, req.MerchantOrderNo)
|
||||
record = append(record, redeemRecord...)
|
||||
if len(record) > 0 {
|
||||
msg, err2 := queryAppleResult(ctx, record)
|
||||
if err2 != nil {
|
||||
msg = "总结失败,请稍候重试"
|
||||
r := ghttp.RequestFromCtx(ctx)
|
||||
if r != nil {
|
||||
queryAppleResult(ctx, r, record)
|
||||
return nil, nil
|
||||
}
|
||||
res.Message = msg
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func queryAppleResult(ctx context.Context, record []*v1.OrderQueryRecord) (string, error) {
|
||||
recordStr, _ := json.Marshal(record)
|
||||
// queryAppleResult 通过 SSE 流式返回 AI 总结结果
|
||||
func queryAppleResult(ctx context.Context, r *ghttp.Request, record []*v1.OrderQueryRecord) {
|
||||
var copyRecord []*struct {
|
||||
Operation string
|
||||
Remark string
|
||||
}
|
||||
for _, queryRecord := range record {
|
||||
copyRecord = append(copyRecord, &struct {
|
||||
Operation string
|
||||
Remark string
|
||||
}{
|
||||
Operation: queryRecord.Operation,
|
||||
Remark: queryRecord.Remark,
|
||||
})
|
||||
}
|
||||
recordStr, _ := json.Marshal(copyRecord)
|
||||
|
||||
// 设置 SSE 响应头
|
||||
r.Response.Header().Set("Content-Type", "text/event-stream")
|
||||
r.Response.Header().Set("Cache-Control", "no-cache")
|
||||
r.Response.Header().Set("Connection", "keep-alive")
|
||||
|
||||
client := openai.NewClient(
|
||||
option.WithAPIKey("sk-jYRlGtXAJ3Q82TS_FxWLFX6wn_VubNnyCtfxYZYP32ccqfQaGwQJHMq5I7k"),
|
||||
option.WithBaseURL("https://hk.uniapi.io/v1"),
|
||||
)
|
||||
chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
|
||||
|
||||
// 使用流式 API 获取结果
|
||||
stream := client.Chat.Completions.NewStreaming(ctx, openai.ChatCompletionNewParams{
|
||||
Messages: []openai.ChatCompletionMessageParamUnion{
|
||||
openai.UserMessage(fmt.Sprintf("%s\n只生成简洁结论,不需要建议,使用中文", string(recordStr))),
|
||||
openai.UserMessage(fmt.Sprintf("%s\n只生成简洁结论,不需要建议,中文回复", string(recordStr))),
|
||||
},
|
||||
Model: "deepseek-v3.2-exp",
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
// 逐块发送流式数据
|
||||
for stream.Next() {
|
||||
chunk := stream.Current()
|
||||
if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
|
||||
content := chunk.Choices[0].Delta.Content
|
||||
// 创建 SSE 格式的数据
|
||||
eventData := map[string]interface{}{
|
||||
"content": content,
|
||||
}
|
||||
dataBytes, _ := json.Marshal(eventData)
|
||||
r.Response.Write([]byte(fmt.Sprintf("data: %s\n\n", string(dataBytes))))
|
||||
// 使用 GoFrame 内置的 Flush 方法立即刷新缓冲区
|
||||
r.Response.Flush()
|
||||
}
|
||||
}
|
||||
return chatCompletion.Choices[0].Message.Content, nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/gogf/gf/v2/encoding/gbase64"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"kami/internal/service"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -33,7 +32,6 @@ func NewClient() *Client {
|
||||
"channel": "app",
|
||||
"content-type": "application/json",
|
||||
"host": "recharge3.bac365.com",
|
||||
"priority": "u=3, i",
|
||||
"user-agent": "Mozilla/5.0 (iPad; CPU OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Html5Plus/1.0 (Immersed/20) uni-app",
|
||||
})
|
||||
client.SetBrowserMode(true)
|
||||
@@ -179,7 +177,7 @@ func (c *Client) QueryAvailableDenominations(ctx context.Context, token string)
|
||||
func (c *Client) CreateOrder(ctx context.Context, phone, token string, amount float64) (orderId string, payUrl string, err error) {
|
||||
//c.Client.SetHeader("Authorization", "Bearer "+c.getAuth(ctx, token))
|
||||
|
||||
c.Client.SetHeader("Authorization", "Bearer lIHCzNDVEWP9RVZcTAWRTGsIEm+GxSN0g4PYU6ydsIfSLH/v+6tIOy/wPhgLGIDpoUdSQUtUW8KV2OABmz2shbE4otvjn1EH0Nf7W9NHm+BuTAAaeMKqW9otAZ2K2clltxefiAXl3PhaRgsqybfsq+ELkqPoYVdyksQLS8Y6kA8=")
|
||||
c.Client.SetHeader("Authorization", "Bearer 2TL5/6FN+qWSZzsLeobeFnHORq3ZBbhxoyvKcrXeO7vtLe/sSKhaYe8rfhJT7OmcgSbI5BIH7EVCSYoiyIqESzOP9vP8Hwel5a446ba4/qGByJDT6JQau60ik5z4j3tvZC3pLjGQ5FxbaftlNe7l6FJz4GE5MObkKgWNOYwMP8w=")
|
||||
|
||||
//
|
||||
goods, err := c.QueryAvailableDenominations(ctx, token)
|
||||
@@ -282,15 +280,15 @@ func (c *Client) CreateOrder(ctx context.Context, phone, token string, amount fl
|
||||
Channel string `json:"channel"`
|
||||
Yanqian bool `json:"yanqian"`
|
||||
}{
|
||||
BodyStr: "AzturcN0yAHCHi/k+xbcLwT+ZwbP7MFoEXeTt89fyx+wSTcjm+A8u7CBpieoET4WUde4aau04pbczjTd/grr0Cm0tZJEdK89eAMXQVU8u/NVImAKlyRdZ2/klP6A3B89Ff6YohGS2DhrRwE4i62E+v+HA2fskO1JRIuXvTN9vySPyD2bTopW1ZxoSU4Pg20BWdAdqaQ7UevggIdUyOu8htQH3j10tTy9XaNW6lrGDOut1FuCCvf5V3JLJQUDy8xWiDnqx7gM476RDwuuEdYtgsGopJCGxmMjWrVvAgrcErHoLHYzRb421ztXc+sZao1GmajpISO+Wa+EBp2Qv2r1jCTS0dcSudMMnb6ElGD3zw2Hw6CiROwSPO2S/BhhgyZbZzd6iFXM35GvxPNfFoKp0YqEe9uVXx0p2jwDtLXG3waOuc+8XC+XtNdzlhOSDop9zG94OfA86+v/ENK2M2xMzUKihUo1+Mkek2ABLZsCiUlBxkzA0nPecqCiiX8/qfjUBZgB5dphDY/PBAgvIDivlOQUBiErTMiNYZJ5ZYMcIOI4Z61TWadmxq/3yABP/cSugj5sSro7415au85T6l//8vADxa41bsJ77JGMNcM1qTT8o3Y1a7fekiHk4ZagKEDHMPVLMwrphzeTUyaRe9VPcO0zl3VTbz7xtBD44bWWz/FI9yxe9BTrnqjn12bpxB5xZHP+FAYLhMfrNdVh5+cloJ+gHBGnAfIH+6ejloMiGSJcJl1/Tdv4Bv06cV+6xuo1H/KVZ8GWtLUVGRxtk7WfVFNqcic5LGnOkOyn1MDwq6Gl0Gmy+xbvp23ziRDKXdJRK57Klk/zSdb5cL6fKIHTpI+4igf69nv6x2aQwML2/QAZ3+D4mkd+t0V04U4YRwBBIKHL+VijVp1fUaftpCty2byCR1aMsMGg50bSH4SU+bq3UCSDHMmyaU11/WBoCIgKq5kdOtCinMBiDCqcQJG8C1jixNJO4TUODi+SgS6s7F2fRg+9ugz5s5tbpxLFW1XlIWvXYSB4/HCUB5jVBPvIzAesrhF4sHK8GxNWEoH5hsT/pym0dBeFOvx8fX3yQdGvau70/hW11qUMpinc8dH3mFgF0aXZQwbmL5ipL7Vx/KAAsQeUQlDa2N4usa3VrAwyD68/aloIw2rsFLcseQ5i2FxCtReBZipt91+eYjITebY=",
|
||||
BodyStr: "gusr/ro/aXwDOxQTbct9/koDxFSzX1R5tRiHtg9YdOx563WvtpU14Yw5Q9plLegeWaJSiyY3vgNB79tyIZXZ0AdsRS/qb4JLSZssQKuNVWG19pdX449uMQuI7f/YqbfEwxht4auuwSKYyg9G5OzLS0NSqZLR/y00w4zSuPGMfdKBk9UTlIiBdK9/RF2e+pUWT4Xds+kG6zWxUFvNdgheojlYTYFK7EMZvROaw25sRjuI9tzujZxW0+eszDDgn9DQ1uNVYImuaRe2C3gJwRcbsf1Av7j0SZmWnviyAsSutEyrsuYp9YUaMHtU/hjW+OouwaIXVf/INdXwySoY1kbcF3jvwke56lLBuXn7iSQh24V7AsAna4Uh8Xf6pBGf871IOyYhGBgjeT+iDj0FxcY/ivJb0B8CzeHfz/Bu1Rjbw0wpFu8J9v9Uf1TgcCinj2bQgnjbJ6a2N+av1fKx0xC2rpqPsnelISO50cLsIEAyy8vz2cKabyq5/IMGBK2EyPE4BB32v2a+e8MKF2dQ0Gy9Z8seXN7moPwB4V4JkmbYMHA6+Rdf87s8Z9LfRJzZSMtlMUouFV0oVlc4aKDs3wcZgrXBdb5lLmA5U0RzipaT0feoq0Q9TYN1uFHRKCmgysK0fxRVFvl4rYaiMQFaTtuHZ9jgcYSPTca2KvjiRLXpQ+8ZLkehiHBd89I+RIt5aGYOp+e/XW4xX/NUWLbimXRs8F5mSYhoko6qidr90psRo9JezNKc1wG1HVMJ4Su7MYcB+UoZI9t9EiPIJ+3avnuW8qQDgqqq7Bi+Vn+PjmvkeujejuwJL5J3WFfSjPP74HwoXg73jgmX2KLI5mU8FDqnojj/KMJmQa3eloOvSZu+uhwFWQdXabaM+o0vNJdSeJjQ7XJNQE9PWag9IxdkHmpZgsAzuu5Ctk41IGPqA/vstekhXRWyTAkl5qj8VI/duVlWWGDzQNaOYi1qnrabBwvffop450xGoCs8ahI7JLOcprIEY5icpmylIh3dvmMGnGOtYbcwQBKNsiA8xbslEdtmdytYobEYwX1UC7ByR9VPvA+3q2MZtxFOa3nKz+meuCAbaHNzEaer1TyjGloQ95sLQKL5xQMacf+0VbkcKJY7mIHaziRkQ9DOTHYgL4IAzsL9UT0bgmmrpP/zzCyzMm/cuZO7YOr4RLICjU3AXhLnPjo=",
|
||||
Channel: "app",
|
||||
Yanqian: true,
|
||||
}
|
||||
proxy, err2 := service.ProxyPool().GetProxyByOrderId(ctx, phone)
|
||||
if err2 == nil && proxy.Host != "" {
|
||||
glog.Info(ctx, "代理 ip", proxy.String())
|
||||
c.Client.SetProxy(proxy.String())
|
||||
}
|
||||
//proxy, err2 := service.ProxyPool().GetProxyByOrderId(ctx, phone)
|
||||
//if err2 == nil && proxy.Host != "" {
|
||||
// glog.Info(ctx, "代理 ip", proxy.String())
|
||||
// c.Client.SetProxy(proxy.String())
|
||||
//}
|
||||
resp, err1 := c.Client.ContentJson().Post(ctx, "https://recharge3.bac365.com/camel_wechat_mini_oil_server/eCardMall/createShoppingOrder", req)
|
||||
if err1 != nil {
|
||||
resultMutex.Lock()
|
||||
|
||||
Reference in New Issue
Block a user