Эх сурвалжийг харах

wip:提交常见问题及猜你想问

wangkaiyue 2 жил өмнө
parent
commit
cc5a1648c4

+ 15 - 18
api/v1/aiChatApi.go

@@ -4,17 +4,11 @@ import (
 	"github.com/gogf/gf/v2/frame/g"
 )
 
-type CommonRes struct {
-	ErrorMsg  string      `json:"error_msg"`
-	ErrorCode int64       `json:"error_code"`
-	Data      interface{} `json:"data"`
-}
-
 // ChatHistoryReq 历史记录
 type ChatHistoryReq struct {
 	g.Meta   `path:"/chatHistory" tags:"AiChat" method:"post" summary:"查询聊天历史记录"`
-	PageSize int `v:"between:1,20" dc:"每页数据量"`
-	PageNum  int `v:"between:1,20" dc:"页码"`
+	PageSize int `json:"pageSize" v:"between:1,20" dc:"每页数据量"`
+	PageNum  int `json:"pageNum" v:"between:1,20" dc:"页码,从0开始"`
 }
 
 type History struct {
@@ -34,27 +28,30 @@ type ChatHistoryRes struct {
 // EvaluateReq 评价
 type EvaluateReq struct {
 	g.Meta    `path:"/evaluate" tags:"AiChat" method:"post" summary:"评价回复的问题"`
-	MessageId string `v:"required"`
-	Evaluate  int    `v:"in:-1,1" dc:"-1:没用;1:有用"`
+	MessageId string `json:"messageId" v:"required"`
+	Evaluate  int    `json:"evaluate" v:"in:-1,1" dc:"-1:没用;1:有用"`
 }
 
 type EvaluateRes struct {
+	ErrorMsg  string `json:"error_msg"`
+	ErrorCode int64  `json:"error_code"`
+	Data      bool   `json:"data" dc:"true:成功 false:失败"`
+}
+
+type QuestionRes struct {
+	ErrorMsg  string   `json:"error_msg"`
+	ErrorCode int64    `json:"error_code"`
+	Data      []string `json:"data" dc:"true:成功 false:失败"`
 }
 
 // GuessQuestionReq 猜你想问
 type GuessQuestionReq struct {
 	g.Meta `path:"/guessQuestion" tags:"AiChat" method:"post" summary:"获取场景下的猜你想问"`
-	Href   string `v:"required|length:6,16"`
-}
-
-type GuessQuestionRes struct {
+	Href   string `json:"href "v:"required|length:6,16"`
 }
 
 // UsuallyProblemReq 常见问题
 type UsuallyProblemReq struct {
 	g.Meta `path:"/usuallyProblem" tags:"AiChat" method:"post" summary:"获取场景下的常见问题"`
-	Href   string `v:"required|length:6,16"`
-}
-
-type UsuallyProblemRes struct {
+	Href   string `json:"href" v:"required|length:6,16"`
 }

+ 7 - 9
internal/cmd/cmd.go

@@ -2,7 +2,7 @@ package cmd
 
 import (
 	"aiChat/internal/controller"
-	"aiChat/utility"
+	"aiChat/internal/middleware"
 	"context"
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/net/ghttp"
@@ -16,16 +16,14 @@ var (
 		Brief: "start http aiChat server",
 		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
 			s := g.Server()
-			s.Use(utility.MiddlewareHandlerResponse)
+			s.Use(middleware.MiddlewareHandlerResponse)
+			s.Use(middleware.MiddlewareHandlerSession)
 			s.Group("/aiChat", func(group *ghttp.RouterGroup) {
-				group.ALL("/ws", controller.ChatWs)               //websocket 聊天
-				group.ALL("/chatHistory", controller.ChatHistory) //历史记录
-				group.ALL("/evaluate", controller.Evaluate)
-
+				group.ALL("/ws", controller.ChatWs) //websocket 聊天
 				group.Bind(
-					//	controller.ChatHistory,    //历史记录
-					//	controller.Evaluate,       //评价
-					//	controller.GuessQuestion,  //猜你想问
+					controller.ChatHistory,    //历史记录
+					controller.Evaluate,       //评价
+					controller.GuessQuestion,  //猜你想问
 					controller.UsuallyProblem, //常见问题
 				)
 			})

+ 5 - 0
internal/consts/consts.go

@@ -1 +1,6 @@
 package consts
+
+const (
+	JY_SESSIONNAME = "SESSIONID"
+	ContextKey     = "ContextKey"
+)

+ 26 - 32
internal/controller/chatHistory.go

@@ -3,41 +3,35 @@ package controller
 import (
 	v1 "aiChat/api/v1"
 	"aiChat/internal/model"
-	"aiChat/utility"
 	"app.yhyue.com/moapp/jybase/encrypt"
-	"github.com/gogf/gf/v2/net/ghttp"
+	"context"
 	"github.com/gogf/gf/v2/os/glog"
 )
 
-// ChatHistory 获取聊天记录
-func ChatHistory(r *ghttp.Request) {
-	final := func() (res v1.ChatHistoryRes) {
-		res = v1.ChatHistoryRes{}
-		session, _ := utility.GetSession(r)
-		if session.AccountId == 0 {
-			res.ErrorCode = -1
-			res.ErrorMsg = "未登陆"
-			return
-		}
-		pageSize := r.Get("PageSize", 5).Int()
-		pageNum := r.Get("PageNum", 0).Int()
-		history, err := model.Message.GetMessage(session.AccountId, pageNum, pageSize)
-		if err != nil {
-			glog.Error(r.Context(), "%d查询聊天记录异常,error:%s", session.AccountId, err)
-			res.ErrorCode = -1
-			res.ErrorMsg = "数据查询异常"
-			return
-		}
-		for _, v := range history {
-			res.Data = append(res.Data, v1.History{
-				Id:         encrypt.SE.Encode2Hex(v.Id),
-				Content:    v.Content,
-				Type:       v.Type,
-				Useful:     v.Useful,
-				CreateTime: v.CreateTime.Unix(),
-			})
-		}
+var (
+	ChatHistory = cChatHistory{}
+)
+
+type cChatHistory struct{}
+
+// Method 获取聊天记录
+func (c *cChatHistory) Method(ctx context.Context, req *v1.ChatHistoryReq) (res *v1.ChatHistoryRes, err error) {
+	res = &v1.ChatHistoryRes{}
+	history, err := model.Message.GetMessage(model.SessionCtx.Get(ctx).JSession.AccountId, req.PageNum, req.PageSize)
+	if err != nil {
+		glog.Error(ctx, "%d查询聊天记录异常,error:%s", model.SessionCtx.Get(ctx).JSession.AccountId, err)
+		res.ErrorCode = -1
+		res.ErrorMsg = "数据查询异常"
 		return
-	}()
-	r.Response.Write(final)
+	}
+	for _, v := range history {
+		res.Data = append(res.Data, v1.History{
+			Id:         encrypt.SE.Encode2Hex(v.Id),
+			Content:    v.Content,
+			Type:       v.Type,
+			Useful:     v.Useful,
+			CreateTime: v.CreateTime.Unix(),
+		})
+	}
+	return
 }

+ 1 - 2
internal/controller/chatWs.go

@@ -2,7 +2,6 @@ package controller
 
 import (
 	"aiChat/internal/model"
-	"aiChat/utility"
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/net/ghttp"
 	"github.com/gogf/gf/v2/os/gctx"
@@ -11,7 +10,7 @@ import (
 
 // ChatWs 聊天websocket请求
 var ChatWs = func(r *ghttp.Request) {
-	session, _ := utility.GetSession(r)
+	session, _ := model.GetSession(r)
 	wsChat := model.NewMessage(gctx.New(), session.AccountId)
 	// 创建ws链接
 	ws, err := r.WebSocket()

+ 17 - 27
internal/controller/evaluate.go

@@ -3,35 +3,25 @@ package controller
 import (
 	v1 "aiChat/api/v1"
 	"aiChat/internal/model"
-	"aiChat/utility"
 	"app.yhyue.com/moapp/jybase/encrypt"
-	"github.com/gogf/gf/v2/net/ghttp"
+	"context"
 )
 
-// Evaluate 点评问答
-func Evaluate(r *ghttp.Request) {
-	final := func() (res v1.CommonRes) {
-		session, _ := utility.GetSession(r)
-		if session.AccountId == 0 {
-			res.ErrorCode = -1
-			res.ErrorMsg = "未登陆"
-			return
-		}
-		evaluate := r.Get("Evaluate").Int()
-		id := encrypt.SE.Decode4Hex(r.Get("MessageId").String())
-		if id == "" {
-			res.ErrorCode = -1
-			res.ErrorMsg = "未找到记录"
-			return
-		}
-		err := model.Message.Evaluate(session.AccountId, id, evaluate)
-		if err != nil {
-			res.ErrorCode = -1
-			res.ErrorMsg = "评价异常"
-			return
-		}
-		res.Data = true
+var (
+	Evaluate = cEvaluate{}
+)
+
+type cEvaluate struct{}
+
+func (c *cEvaluate) Method(ctx context.Context, req *v1.EvaluateReq) (res *v1.EvaluateRes, err error) {
+	res = &v1.EvaluateRes{}
+	id := encrypt.SE.Decode4Hex(req.MessageId)
+	err = model.Message.Evaluate(model.SessionCtx.Get(ctx).JSession.AccountId, id, req.Evaluate)
+	if err != nil {
+		res.Data = false
 		return
-	}()
-	r.Response.Write(final)
+	} else {
+		res.Data = true
+	}
+	return
 }

+ 3 - 3
internal/controller/guessQuestion.go

@@ -2,6 +2,7 @@ package controller
 
 import (
 	v1 "aiChat/api/v1"
+	"aiChat/internal/model"
 	"context"
 	"github.com/gogf/gf/v2/frame/g"
 )
@@ -12,7 +13,6 @@ var (
 
 type cGuessQuestion struct{}
 
-func (c *cGuessQuestion) Method(ctx context.Context, req *v1.GuessQuestionReq) (res *v1.GuessQuestionRes, err error) {
-	g.RequestFromCtx(ctx).Response.Writeln("Hi!")
-	return
+func (c *cGuessQuestion) Method(ctx context.Context, req *v1.GuessQuestionReq) (res *v1.QuestionRes, err error) {
+	return &v1.QuestionRes{Data: model.Question.GetProblem(model.GetScenario(req.Href), 1, g.Config().MustGet(ctx, "chat.usuallyProblem", 5).Int())}, nil
 }

+ 3 - 3
internal/controller/usuallyProblem.go

@@ -2,6 +2,7 @@ package controller
 
 import (
 	v1 "aiChat/api/v1"
+	"aiChat/internal/model"
 	"context"
 	"github.com/gogf/gf/v2/frame/g"
 )
@@ -12,7 +13,6 @@ var (
 
 type cUsuallyProblem struct{}
 
-func (c *cUsuallyProblem) Method(ctx context.Context, req *v1.UsuallyProblemReq) (res *v1.UsuallyProblemRes, err error) {
-	g.RequestFromCtx(ctx).Response.Writeln("Hi!123123", req.Href)
-	return
+func (c *cUsuallyProblem) Method(ctx context.Context, req *v1.UsuallyProblemReq) (res *v1.QuestionRes, err error) {
+	return &v1.QuestionRes{Data: model.Question.GetProblem(model.GetScenario(req.Href), 0, g.Config().MustGet(ctx, "chat.guessQuestion", 5).Int())}, nil
 }

+ 8 - 4
utility/resMiddleware.go → internal/middleware/resMiddleware.go

@@ -1,4 +1,4 @@
-package utility
+package middleware
 
 import (
 	"github.com/gogf/gf/v2/errors/gcode"
@@ -25,9 +25,9 @@ func MiddlewareHandlerResponse(r *ghttp.Request) {
 	r.Middleware.Next()
 
 	// There's custom buffer content, it then exits current handler.
-	if r.Response.BufferLength() > 0 {
-		return
-	}
+	//if r.Response.BufferLength() > 0 {
+	//	return
+	//}
 
 	var (
 		msg  string
@@ -40,6 +40,8 @@ func MiddlewareHandlerResponse(r *ghttp.Request) {
 			code = gcode.CodeInternalError
 		}
 		msg = err.Error()
+		res = nil //异常置空返回值
+		r.Response.ClearBuffer()
 	} else {
 		if r.Response.Status > 0 && r.Response.Status != http.StatusOK {
 			msg = http.StatusText(r.Response.Status)
@@ -56,6 +58,8 @@ func MiddlewareHandlerResponse(r *ghttp.Request) {
 			r.SetError(err)
 		} else {
 			code = gcode.CodeOK
+			r.Response.WriteJson(res)
+			return
 		}
 	}
 

+ 14 - 0
internal/middleware/sessionMiddleware.go

@@ -0,0 +1,14 @@
+package middleware
+
+import (
+	"aiChat/internal/model"
+	"github.com/gogf/gf/v2/net/ghttp"
+)
+
+func MiddlewareHandlerSession(r *ghttp.Request) {
+	session, _ := model.GetSession(r)
+	model.SessionCtx.Init(r, &model.Context{
+		JSession: session,
+	})
+	r.Middleware.Next()
+}

+ 2 - 0
internal/model/message.go

@@ -48,10 +48,12 @@ func (m *cMessage) SaveMessage(msg *SaveMessage) {
 		r, err := g.Model("ai_message").Data(val).Insert()
 		if err != nil {
 			glog.Error(ctx, "插入聊天记录异常,error:%s\ndata:%v", err, val)
+			g.Dump(val)
 		}
 		affect, _ := r.RowsAffected()
 		if len(tmp) == gconv.Int(affect) {
 			glog.Error(ctx, "插入聊天记录异常 共%d条 插入%d条,error:%s\ndata:%v", len(tmp), affect, err, val)
+			g.Dump(val)
 		} else {
 			glog.Info(ctx, "插入%d条聊天记录成功", affect)
 		}

+ 0 - 30
internal/model/message_test.go

@@ -1,30 +0,0 @@
-package model
-
-import (
-	"app.yhyue.com/moapp/jybase/date"
-	"encoding/json"
-	"fmt"
-	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
-	"testing"
-	"time"
-)
-
-func Test_cMessage_SaveMessage(t *testing.T) {
-	for i := 0; i < 10; i++ {
-		Message.SaveMessage(&SaveMessage{
-			Content:    "111",
-			Type:       1,
-			Item:       1,
-			Refer:      "demo",
-			PersonId:   450062,
-			CreateTime: time.Now().Format(date.Date_Full_Layout),
-		})
-	}
-}
-
-func Test_cMessage_GetMessage(t *testing.T) {
-	list := Message.GetMessage(450062, 0, 5)
-	fmt.Println(list)
-	b, _ := json.Marshal(list)
-	fmt.Println(string(b))
-}

+ 86 - 0
internal/model/question.go

@@ -0,0 +1,86 @@
+package model
+
+import (
+	elastic "app.yhyue.com/moapp/jybase/esv1"
+	"context"
+	"fmt"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/util/gconv"
+)
+
+var (
+	Question = &cQuestion{}
+)
+
+const (
+	answerFrom = iota
+	Answer_UsuallyProblem
+	Answer_Isbusiness
+	Answer_ChatGPT
+
+	index, itype          = "aiquestion", "aiquestion"
+	GetQuestionListSql    = `{"query":{"bool":{"must":[{"term":{"status":1}},{"term":{"isbusiness":%d}},{"term":{"source":"%s"}}]}},"from":0,"size":%d,"sort":[{"id":"desc"}],"_source": ["question"]}`
+	GetAnswerFromQuestion = `{"query":{"bool":{"must":[{"term":{"status":1}},{"multi_match":{"query":"%s","minimum_should_match":"%s","fields":["question"]}}]}},"from":0,"size":1,"_source":["check_member","isbusiness","question","answer","auto_url","joggle","service_id","noperm","source"]}`
+)
+
+type cQuestion struct {
+}
+
+// QuestionReq 用户发送过来的问题详情
+type QuestionReq struct {
+	Context string `json:"context"` //内容
+	History []struct {
+		Q string `json:"q"` //问题
+		A string `json:"a"` //答案
+	} `json:"history,omitempty"` //会话上下文,会话历史
+	Href string `json:"href,omitempty"` //咨询页面
+}
+
+// QuestionEsRes 问题检索库查询结果
+type QuestionEsRes struct {
+	CheckMember int    `json:"check_member" dc:"是否校验大会员权限"`
+	Isbusiness  int    `json:"isbusiness" dc:"业务意图 0:否 1:是"`
+	Answer      string `json:"answer" dc:"答案"`
+	AutoUrl     string `json:"auto_url" dc:"默认url"`
+	Joggle      string `json:"joggle" dc:"业务接口"`
+	Noperm      string `json:"noperm" dc:"无权限回复"`
+	Source      string `json:"source" dc:"问题所属"`
+	ServiceId   string `json:"service_id" dc:"大会员功能服务id"`
+}
+
+// GetProblem 获取常见问题及猜你想问
+func (q *cQuestion) GetProblem(scenario, isbusiness, limit int) (list []string) {
+	list = make([]string, 0, limit)
+	res := elastic.Get(index, itype, fmt.Sprintf(GetQuestionListSql, isbusiness, scenarioName[scenario], limit))
+	if res != nil && len(*res) > 0 {
+		for _, m := range *res {
+			list = append(list, gconv.MapStrStr(m)["question"])
+		}
+	}
+	return
+}
+
+// GetAnswer 获取答案
+func (q *cQuestion) GetAnswer(ctx context.Context, question *QuestionReq) (itemFrom int, detail string, err error) {
+	res := elastic.Get(index, itype, fmt.Sprintf(GetAnswerFromQuestion, question.Context, g.Config().MustGet(ctx, "chat.match", "70%").String()))
+	if res == nil || len(*res) == 0 {
+		return getAnswerFromChatGPT()
+	}
+	qResObj := &QuestionEsRes{}
+	gconv.Struct((*res)[0], qResObj)
+
+	// 非业务问题直接返回
+	if qResObj.Isbusiness == 0 {
+		return Answer_UsuallyProblem, qResObj.Answer, nil
+	}
+
+	// 业务问题
+	//qResObj.CheckMember
+
+	return Answer_Isbusiness, "", nil
+}
+
+// getChatGPT 获取ChatGPT答案
+func getAnswerFromChatGPT() (int, string, error) {
+	return Answer_ChatGPT, "", nil
+}

+ 39 - 0
internal/model/scenario.go

@@ -0,0 +1,39 @@
+package model
+
+import (
+	"net/url"
+	"regexp"
+	"strings"
+)
+
+const (
+	IndexPage = iota //b=0
+	DetailPage
+	WorkDesk //c=1   相当于c=iota
+)
+
+var (
+	scenarioName = map[int]string{
+		IndexPage:  "index",    //网站首页
+		DetailPage: "detail",   //三级页
+		WorkDesk:   "workDesk", //工作桌面
+	}
+	regExpDetail = regexp.MustCompile("^/article/(\\w+)/(.*).html")
+)
+
+// GetScenario 获取场景
+func GetScenario(refer string) int {
+	u, err := url.Parse(refer)
+	if err == nil {
+		if strings.HasPrefix(u.Path, "/page_workDesktop") {
+			if strings.HasPrefix(u.Path, "/page_workDesktop/work-bench/page") {
+				uu, err := url.Parse(u.Query().Get("link"))
+				if err == nil && regExpDetail.MatchString(uu.Path) {
+					return DetailPage
+				}
+			}
+			return WorkDesk
+		}
+	}
+	return IndexPage
+}

+ 32 - 5
utility/sessionMiddleware.go → internal/model/session.go

@@ -1,6 +1,8 @@
-package utility
+package model
 
 import (
+	"aiChat/internal/consts"
+	"context"
 	"fmt"
 	"github.com/gogf/gf/v2/encoding/gjson"
 	"github.com/gogf/gf/v2/frame/g"
@@ -9,10 +11,35 @@ import (
 	"net/url"
 )
 
-const (
-	JY_SESSIONNAME = "SESSIONID"
+type (
+	sSessionCtx struct{}
+	Context     struct {
+		JSession *JySession
+	}
 )
 
+var SessionCtx = sSessionCtx{}
+
+func (s *sSessionCtx) Init(r *ghttp.Request, customCtx *Context) {
+	r.SetCtxVar(consts.ContextKey, customCtx)
+}
+
+func (s *sSessionCtx) Get(ctx context.Context) *Context {
+	value := ctx.Value(consts.ContextKey)
+	if value == nil {
+		return nil
+	}
+	if localCtx, ok := value.(*Context); ok {
+		return localCtx
+	}
+	return nil
+}
+
+// SetSession injects business user object into context.
+func (s *sSessionCtx) SetSession(ctx context.Context, session *JySession) {
+	s.Get(ctx).JSession = session
+}
+
 // JySession 剑鱼程序SESSION获取
 type JySession struct {
 	UserId            string // 上下文用户信息
@@ -39,7 +66,7 @@ type JySession struct {
 
 func GetSession(r *ghttp.Request) (jSession *JySession, err error) {
 	jSession = &JySession{}
-	cookie, err := r.Request.Cookie(JY_SESSIONNAME)
+	cookie, err := r.Request.Cookie(consts.JY_SESSIONNAME)
 	if err != nil {
 		return
 	}
@@ -50,7 +77,7 @@ func GetSession(r *ghttp.Request) (jSession *JySession, err error) {
 	findKey, _ := url.QueryUnescape(cookie.Value)
 	rVal, err := g.Redis("session").Get(r.GetCtx(), findKey)
 	if err != nil {
-		return nil, err
+		return jSession, err
 	}
 
 	var data map[string]interface{}

+ 2 - 11
internal/model/ws.go

@@ -10,15 +10,6 @@ import (
 	"time"
 )
 
-type Req struct {
-	Context string `json:"context"` //内容
-	History []struct {
-		Q string `json:"q"` //问题
-		A string `json:"a"` //答案
-	} `json:"history,omitempty"` //会话上下文,会话历史
-	Href string `json:"href,omitempty"` //咨询页面
-}
-
 type wsChat struct {
 	Ctx    context.Context
 	UserId int64
@@ -34,7 +25,7 @@ func NewMessage(ctx context.Context, userId int64) *wsChat {
 // Handle 处理消息
 func (m *wsChat) Handle(ws *ghttp.WebSocket, msg []byte, ip, agent string) {
 	defer Catch()
-	req := &Req{}
+	req := &QuestionReq{}
 	if err := gjson.Unmarshal(msg, req); err != nil {
 		glog.Errorf(m.Ctx, "%d 接收消息Unmarshal出错:%v", m.UserId, err)
 	}
@@ -55,6 +46,6 @@ func (m *wsChat) Handle(ws *ghttp.WebSocket, msg []byte, ip, agent string) {
 	//	cache.SetCustomerServiceHeartbeat(entId, entUserId, userId)
 	//}
 
-	//查询检索库
+	Question.GetAnswer(m.Ctx, req)
 
 }

+ 0 - 29
internal/service/session.go

@@ -1,29 +0,0 @@
-// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
-// ==========================================================================
-
-package service
-
-import (
-	"aiChat/utility"
-	"context"
-)
-
-type ISession interface {
-	SetUser(ctx context.Context, user *utility.JySession) error
-	GetUser(ctx context.Context) *utility.JySession
-	RemoveUser(ctx context.Context) error
-}
-
-var localSession ISession
-
-func Session() ISession {
-	if localSession == nil {
-		panic("implement not found for interface ISession, forgot register?")
-	}
-	return localSession
-}
-
-func RegisterSession(i ISession) {
-	localSession = i
-}

+ 1 - 0
main.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"aiChat/internal/cmd"
+	_ "aiChat/utility"
 	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
 	_ "github.com/gogf/gf/contrib/nosql/redis/v2"
 	"github.com/gogf/gf/v2/os/gctx"

+ 33 - 25
manifest/config/config.yaml

@@ -1,47 +1,55 @@
 server:
-  address:     ":8000"
+  address: ":8000"
   openapiPath: "/api.json"
   swaggerPath: "/swagger"
   graceful: true # 是否开启平滑重启特性,开启时将会在本地增加10000的本地TCP端口用于进程间通信。默认false
   gracefulTimeout: 2 # 父进程在平滑重启后多少秒退出,默认2秒。若请求耗时大于该值,可能会导致请求中断
+  LogPath: "logs/server"
+  LogStdout: true
+  ErrorStack: true
+  ErrorLogEnabled: true
+  ErrorLogPattern: "error.{Ymd}.log"
+  AccessLogEnabled: true
+  AccessLogPattern: "access.{Ymd}.log"
+
+chat:
+  usuallyProblem: 5 # 常见问题返回数量
+  guessQuestion: 5 # 猜你想问返回数量
+  match: 50% # 检索库匹配值
+
 
 redis:
   session:
     address: 192.168.3.11:1713
-
   main:
     address: 192.168.3.206:1712
 
+elasticsearch:
+  address: "http://192.168.3.206:9800"
+  size: 5
+
 database:
   default:
     link: "mysql:root:=PDT49#80Z!RVv52_z@tcp(192.168.3.217:4000)/base_service"
     maxIdle: "5"
     maxOpen: "5"
 
-mysql:
-  dBName: base_service
-  address: "192.168.3.217:4000"
-  userName: root
-  passWord: "=PDT49#80Z!RVv52_z"
-  maxOpenConns: 5
-  maxIdleConns: 5
-
 logger:
-  path:                  "logs"        # 日志文件路径。默认为空,表示关闭,仅输出到终端
-  file:                  "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log"
-  prefix:                ""            # 日志内容输出前缀。默认为空
-  level:                 "all"         # 日志输出级别
-  ctxKeys:               []            # 自定义Context上下文变量名称,自动打印Context的变量到日志中。默认为空
-  header:                true          # 是否打印日志的头信息。默认true
-  stdout:                true          # 日志是否同时输出到终端。默认true
-  rotateSize:            0             # 按照日志文件大小对文件进行滚动切分。默认为0,表示关闭滚动切分特性
-  rotateExpire:          0             # 按照日志文件时间间隔对文件滚动切分。默认为0,表示关闭滚动切分特性
-  rotateBackupLimit:     0             # 按照切分的文件数量清理切分文件,当滚动切分特性开启时有效。默认为0,表示不备份,切分则删除
-  rotateBackupExpire:    0             # 按照切分的文件有效期清理切分文件,当滚动切分特性开启时有效。默认为0,表示不备份,切分则删除
-  rotateBackupCompress:  0             # 滚动切分文件的压缩比(0-9)。默认为0,表示不压缩
-  rotateCheckInterval:   "1h"          # 滚动切分的时间检测间隔,一般不需要设置。默认为1小时
-  stdoutColorDisabled:   false         # 关闭终端的颜色打印。默认开启
-  writerColorEnable:     false         # 日志文件是否带上颜色。默认false,表示不带颜色
+  path: "logs"        # 日志文件路径。默认为空,表示关闭,仅输出到终端
+  file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log"
+  prefix: ""            # 日志内容输出前缀。默认为空
+  level: "all"         # 日志输出级别
+  ctxKeys: [ ]            # 自定义Context上下文变量名称,自动打印Context的变量到日志中。默认为空
+  header: true          # 是否打印日志的头信息。默认true
+  stdout: true          # 日志是否同时输出到终端。默认true
+  rotateSize: 0             # 按照日志文件大小对文件进行滚动切分。默认为0,表示关闭滚动切分特性
+  rotateExpire: 0             # 按照日志文件时间间隔对文件滚动切分。默认为0,表示关闭滚动切分特性
+  rotateBackupLimit: 0             # 按照切分的文件数量清理切分文件,当滚动切分特性开启时有效。默认为0,表示不备份,切分则删除
+  rotateBackupExpire: 0             # 按照切分的文件有效期清理切分文件,当滚动切分特性开启时有效。默认为0,表示不备份,切分则删除
+  rotateBackupCompress: 0             # 滚动切分文件的压缩比(0-9)。默认为0,表示不压缩
+  rotateCheckInterval: "1h"          # 滚动切分的时间检测间隔,一般不需要设置。默认为1小时
+  stdoutColorDisabled: false         # 关闭终端的颜色打印。默认开启
+  writerColorEnable: false         # 日志文件是否带上颜色。默认false,表示不带颜色
 
 
 

+ 20 - 0
utility/elasticsearch.go

@@ -0,0 +1,20 @@
+package utility
+
+import (
+	elastic "app.yhyue.com/moapp/jybase/esv1"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gctx"
+)
+
+type esConf struct {
+	Address string `json:"address"`
+	Size    int    `json:"size"`
+}
+
+func init() {
+	var EsConf esConf
+	ctx := gctx.New()
+	_ = g.Cfg().MustGet(ctx, "elasticsearch", "").Scan(&EsConf)
+	elastic.InitElasticSize(EsConf.Address, EsConf.Size)
+	g.Log().Info(ctx, "初始化 elasticsearch", EsConf)
+}