|
@@ -2,39 +2,140 @@ package aiSearch
|
|
|
|
|
|
import (
|
|
|
"aiChat/api/aiSearch/v1"
|
|
|
+ "aiChat/internal/model"
|
|
|
+ "aiChat/internal/model/bidSearch"
|
|
|
"context"
|
|
|
- "errors"
|
|
|
"fmt"
|
|
|
"io/ioutil"
|
|
|
- "log"
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
+ "github.com/gogf/gf/v2/util/gconv"
|
|
|
+
|
|
|
+ . "app.yhyue.com/moapp/jybase/encrypt"
|
|
|
+ "github.com/gogf/gf/v2/database/gdb"
|
|
|
"github.com/gogf/gf/v2/encoding/gjson"
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
|
)
|
|
|
|
|
|
func (c *ControllerV1) Chat(ctx context.Context, req *v1.ChatReq) (res *v1.ChatRes, err error) {
|
|
|
- content := fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoPrompt").String(), gtime.Now().Format("Ymd"), req.Content)
|
|
|
- query, largeModelReply, err := c.doubao(ctx, content)
|
|
|
- if err != nil {
|
|
|
- content = fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuPrompt").String(), gtime.Now().Format("Ymd"), req.Content)
|
|
|
- query, largeModelReply, err = c.zhipu(ctx, content)
|
|
|
+ res = &v1.ChatRes{ErrorCode: 0}
|
|
|
+ sid := gconv.Int64(SE.Decode4HexByCheck(req.SId))
|
|
|
+ if sid == 0 {
|
|
|
+ g.Log().Error(ctx, "无效的sid参数", req.SId)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ startTime := gtime.Now().Format("Y-m-d h:m:s.u")
|
|
|
+ success := 0
|
|
|
+ prompt := fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoPrompt").String(), gtime.Now().Format("Ymd"), req.Question)
|
|
|
+ large_model := "doubao"
|
|
|
+ callLogs := g.List{}
|
|
|
+ content, largeModelReply, err, isLimit := c.doubao(ctx, prompt)
|
|
|
+ if !isLimit {
|
|
|
+ large_model_success := 1
|
|
|
+ error_msg := ""
|
|
|
+ if err != nil {
|
|
|
+ error_msg = err.Error()
|
|
|
+ large_model_success = 0
|
|
|
+ }
|
|
|
+ callLogs = append(callLogs, g.Map{
|
|
|
+ "large_model": large_model,
|
|
|
+ "large_model_reply": largeModelReply,
|
|
|
+ "large_model_starttime": startTime,
|
|
|
+ "large_model_endtime": gtime.Now().Format("Y-m-d h:m:s.u"),
|
|
|
+ "large_model_success": large_model_success,
|
|
|
+ "error_msg": error_msg,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if isLimit || err != nil {
|
|
|
+ prompt = fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuPrompt").String(), gtime.Now().Format("Ymd"), req.Question)
|
|
|
+ content, largeModelReply, err, _ = c.zhipu(ctx, prompt)
|
|
|
+ large_model = "zhipu"
|
|
|
+ large_model_success := 1
|
|
|
+ error_msg := ""
|
|
|
+ if err != nil {
|
|
|
+ error_msg = err.Error()
|
|
|
+ large_model_success = 0
|
|
|
+ }
|
|
|
+ callLogs = append(callLogs, g.Map{
|
|
|
+ "large_model": large_model,
|
|
|
+ "large_model_reply": largeModelReply,
|
|
|
+ "large_model_starttime": startTime,
|
|
|
+ "large_model_endtime": gtime.Now().Format("Y-m-d h:m:s.u"),
|
|
|
+ "large_model_success": large_model_success,
|
|
|
+ "error_msg": error_msg,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ large_model_endtime := gtime.Now().Format("Y-m-d h:m:s.u")
|
|
|
+ if err == nil {
|
|
|
+ success = 1
|
|
|
+ } else {
|
|
|
+ large_model = ""
|
|
|
+ }
|
|
|
+ sess, sessErr := model.GetSession(g.RequestFromCtx(ctx))
|
|
|
+ if sessErr != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ bs, bsErr := bidSearch.NewBidSearch(ctx, sess.PersonId, content)
|
|
|
+ if bsErr != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ query, list := bs.Search()
|
|
|
+ answer := ""
|
|
|
+ if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
|
+ chatId, chatErr := tx.InsertAndGetId("ai_search_chat", g.Map{
|
|
|
+ "position_id": sess.PositionId,
|
|
|
+ "item": req.Item,
|
|
|
+ "question": req.Question,
|
|
|
+ "answer": answer,
|
|
|
+ "starttime": startTime,
|
|
|
+ "large_model_endtime": large_model_endtime,
|
|
|
+ "endtime": gtime.Now().Format("Y-m-d h:m:s.u"),
|
|
|
+ "success": success,
|
|
|
+ "es_query": query,
|
|
|
+ "list_count": len(list),
|
|
|
+ "session_id": sid,
|
|
|
+ "status": 1,
|
|
|
+ "large_model": large_model,
|
|
|
+ "create_time": gtime.Datetime(),
|
|
|
+ })
|
|
|
+ if chatErr != nil {
|
|
|
+ g.Log().Error(ctx, "ai_search_chat保存出错", chatErr)
|
|
|
+ return chatErr
|
|
|
+ }
|
|
|
+ //
|
|
|
+ // bids := g.List{}
|
|
|
+ // for _, v := range list {
|
|
|
+ // bids = append(bids, g.Map{
|
|
|
+ // "position_id": sess.PositionId,
|
|
|
+ // "chat_id": chatId,
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ for _, v := range callLogs {
|
|
|
+ v["chat_id"] = chatId
|
|
|
+ v["create_time"] = gtime.Datetime()
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }); err == nil {
|
|
|
+ res.ErrorCode = 1
|
|
|
+ res.List = list
|
|
|
+ } else {
|
|
|
+ g.Log().Error(ctx, sess.PositionId, "保存数据库出错", err)
|
|
|
}
|
|
|
- log.Println(query, largeModelReply, err)
|
|
|
- return nil, nil
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
//调用豆包大模型
|
|
|
-func (c *ControllerV1) doubao(ctx context.Context, content string) (string, string, error) {
|
|
|
+func (c *ControllerV1) doubao(ctx context.Context, content string) (string, string, error, bool) {
|
|
|
count, err := g.Redis("main").Incr(ctx, fmt.Sprintf("aiSearch_doubaoCall_%s", gtime.Now().Format("Ymd")))
|
|
|
if err != nil {
|
|
|
g.Log().Error(ctx, "从redis获取doubao调用次数出错", err)
|
|
|
- return "", "", err
|
|
|
+ return "", "", err, true
|
|
|
} else if doubaoCallMax := g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoCallMax").Int64(); count > doubaoCallMax {
|
|
|
g.Log().Info(ctx, "doubao调用次数达到上限", doubaoCallMax, count)
|
|
|
- return "", "", errors.New("doubao调用次数达到上限")
|
|
|
+ return "", "", nil, true
|
|
|
}
|
|
|
// 构造请求数据
|
|
|
messages := []map[string]interface{}{}
|
|
@@ -53,14 +154,14 @@ func (c *ControllerV1) doubao(ctx context.Context, content string) (string, stri
|
|
|
}
|
|
|
|
|
|
//调用智普大模型
|
|
|
-func (c *ControllerV1) zhipu(ctx context.Context, content string) (string, string, error) {
|
|
|
+func (c *ControllerV1) zhipu(ctx context.Context, content string) (string, string, error, bool) {
|
|
|
count, err := g.Redis("main").Incr(ctx, fmt.Sprintf("aiSearch_zhipuCall_%s", gtime.Now().Format("YYYYmmdd")))
|
|
|
if err != nil {
|
|
|
g.Log().Error(ctx, "从redis获取zhipu调用次数出错", err)
|
|
|
- return "", "", err
|
|
|
+ return "", "", err, true
|
|
|
} else if doubaoCallMax := g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuCallMax").Int64(); count > doubaoCallMax {
|
|
|
g.Log().Info(ctx, "zhipu调用次数达到上限", doubaoCallMax, count)
|
|
|
- return "", "", errors.New("zhipu调用次数达到上限")
|
|
|
+ return "", "", nil, true
|
|
|
}
|
|
|
// 构造请求数据
|
|
|
messages := []map[string]interface{}{}
|
|
@@ -78,39 +179,61 @@ func (c *ControllerV1) zhipu(ctx context.Context, content string) (string, strin
|
|
|
return c.post(ctx, "zhipu", "https://open.bigmodel.cn/api/paas/v4/chat/completions", "3d84d30b7ab4c94dbf71853cb7e44719.hLLS4CA2MqVQs6kR", requestData)
|
|
|
}
|
|
|
|
|
|
-func (c *ControllerV1) post(ctx context.Context, t, apiURL, pass string, requestData map[string]interface{}) (string, string, error) {
|
|
|
+func (c *ControllerV1) post(ctx context.Context, t, apiURL, pass string, requestData map[string]interface{}) (string, string, error, bool) {
|
|
|
+ ddd := `{
|
|
|
+"关键词": {
|
|
|
+"选择": ["软件"],
|
|
|
+"排除": []
|
|
|
+},
|
|
|
+"发布时间范围": "20210126-20250226",
|
|
|
+"搜索范围": ["标题", "正文"],
|
|
|
+"匹配模式": "精准匹配",
|
|
|
+"信息类型": "招标公告",
|
|
|
+"地区": {
|
|
|
+"选择": ["广东", "广西", "海南","北京"],
|
|
|
+"排除": []
|
|
|
+},
|
|
|
+"金额": "0-2000万",
|
|
|
+"采购单位联系方式": "不限",
|
|
|
+"中标单位联系方式": "不限",
|
|
|
+"附件": "不限",
|
|
|
+"采购单位": "不限",
|
|
|
+"中标单位": "不限",
|
|
|
+"招标代理": "不限"
|
|
|
+}`
|
|
|
+ return ddd, "", nil, false
|
|
|
resp, err := g.Client().Timeout(time.Duration(g.Cfg("ai_search.yaml").MustGet(ctx, "timeout").Int())*time.Second).
|
|
|
SetHeader("Authorization", fmt.Sprintf("Bearer %s", pass)).
|
|
|
ContentType("application/json").
|
|
|
Post(ctx, apiURL, requestData)
|
|
|
if err != nil {
|
|
|
g.Log().Error(ctx, t, "请求出错", err)
|
|
|
- return "", "", err
|
|
|
+ return "", "", err, false
|
|
|
}
|
|
|
defer resp.Body.Close()
|
|
|
b, be := ioutil.ReadAll(resp.Body)
|
|
|
if be != nil {
|
|
|
g.Log().Error(ctx, t, "gjson.LoadJson出错", be)
|
|
|
- return "", "", err
|
|
|
+ return "", "", err, false
|
|
|
}
|
|
|
largeModelReply := string(b)
|
|
|
g.Log().Info(ctx, t, "请求回复", largeModelReply)
|
|
|
r, re := gjson.LoadJson(b)
|
|
|
if re != nil {
|
|
|
g.Log().Error(ctx, t, largeModelReply, "gjson.LoadJson出错", re)
|
|
|
- return "", largeModelReply, err
|
|
|
+ return "", largeModelReply, err, false
|
|
|
}
|
|
|
content := ""
|
|
|
choices := r.GetJsons("choices")
|
|
|
if len(choices) == 0 {
|
|
|
- return "", largeModelReply, err
|
|
|
+ return "", largeModelReply, err, false
|
|
|
}
|
|
|
message := choices[0].GetJson("message")
|
|
|
if message == nil {
|
|
|
- return "", largeModelReply, err
|
|
|
+ return "", largeModelReply, err, false
|
|
|
}
|
|
|
content = message.Get("content").String()
|
|
|
content = strings.ReplaceAll(content, "```json", "")
|
|
|
content = strings.ReplaceAll(content, "```", "")
|
|
|
- return content, largeModelReply, nil
|
|
|
+ return content, largeModelReply, nil, false
|
|
|
}
|