123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- package service
- import (
- cm "app.yhyue.com/moapp/jybase/common"
- . "app.yhyue.com/moapp/jybase/encrypt"
- elastic "app.yhyue.com/moapp/jybase/esv1"
- . "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/entity"
- ki "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/rpc/knowledge/init"
- "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/rpc/knowledge/knowledgeclient"
- "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/rpc/knowledge/util"
- "database/sql"
- "fmt"
- "github.com/zeromicro/go-zero/core/logx"
- "log"
- "strconv"
- "time"
- )
- type KnowledgeService struct{}
- var (
- Index = "smart_new"
- Type = "smart"
- )
- // KnowledgeAdd 添加问题
- func (k *KnowledgeService) KnowledgeAdd(param *knowledgeclient.AddRequest, segment string) (bool, string) {
- //先查找知识库Id
- query := map[string]interface{}{"status": 1, "appid": param.AppId, "ent_id": param.EntId}
- datalist := Mysql.Find(util.KNOWLEDGE, query, "id", "", -1, -1)
- if datalist != nil && *datalist != nil && len(*datalist) > 0 {
- //问题进行分词
- keywords := ""
- keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
- if len(keywordsArr) != 0 {
- for _, val := range keywordsArr {
- keywords += val + " "
- }
- }
- if keywords == "" {
- keywords = param.Question
- }
- createPerson := param.EntUserId
- var answerId int64
- nowTime := time.Now().Local().Format(util.DateFullLayout)
- fool := Mysql.ExecTx("添加知识", func(tx *sql.Tx) bool {
- //插入答案
- answerData := map[string]interface{}{
- "knowledge_id": (*datalist)[0]["id"],
- "status": 1,
- "create_time": nowTime,
- "update_time": nowTime,
- "create_person": createPerson,
- "content": param.Answer,
- }
- answerId = Mysql.Insert(util.ANSWER, answerData)
- //插入问题
- questionData := map[string]interface{}{
- "answer_id": answerId,
- "content": param.Question,
- "keywords": keywords,
- }
- questionId := Mysql.Insert(util.QUESTION, questionData)
- return answerId > 0 && questionId > 0
- })
- if fool {
- //插入es
- knowledge := map[string]interface{}{
- "knowledgeId": (*datalist)[0]["id"],
- "status": 1,
- "createTime": time.Now().Unix(),
- "createPerson": createPerson,
- "answer": param.Answer,
- "question": param.Question,
- "keywords": keywords,
- "answerId": answerId,
- "entId": param.EntId,
- }
- b := elastic.Save(Index, Type, knowledge)
- if !b {
- logx.Error("es 保存失败")
- return false, "es 保存失败"
- }
- questionVector, err := util.EncodeVector(keywords)
- if err != nil {
- logx.Error("获取 向量失败 ", err)
- return false, "获取 向量失败 :" + err.Error()
- }
- // 存入向量库
- //插入es
- knowledgeV := map[string]interface{}{
- "mod_time": time.Now().Unix(),
- "answer": param.Answer,
- "question": param.Question,
- "keywords": keywords,
- "_id": answerId,
- "entId": param.EntId,
- "questionVector": questionVector,
- }
- if !ESV7.Save(ESV7Index, ESV7Type, knowledgeV) {
- logx.Error("知识库添加向量失败:", knowledgeV)
- return false, "知识库添加向量失败"
- }
- return b, ""
- }
- return fool, "插入mysql出错"
- }
- return false, "租户不存在"
- }
- // KnowledgeEdit 编辑问题
- func (k *KnowledgeService) KnowledgeEdit(param *knowledgeclient.KnowledgeEditReq, segment string) (ok bool) {
- ok = false
- //获取问题分词
- keywords := ""
- keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
- logx.Info("keywordsArr", keywordsArr)
- if len(keywordsArr) != 0 {
- for _, val := range keywordsArr {
- keywords += val + " "
- }
- }
- if keywords == "" {
- keywords = param.Question
- }
- //通过entUserId获取创建人名称
- /*req := &usercenter.EntUserReq{
- EntId: param.EntId,
- EntUserId: param.EntUserId,
- AppId: param.AppId,
- }
- resp, err := UserCenterLib.GetEntUserInfo(context.Background(), req)
- if resp.ErrorCode != 0 {
- logx.Info("查询用户中台创建人信息失败", param.EntId, param.EntUserId, "err:", err)
- return ok
- }*/
- createPerson := param.EntUserId
- fool := Mysql.ExecTx("编辑问题、答案", func(tx *sql.Tx) bool {
- //修改答案
- answerUpdate := map[string]interface{}{
- "update_time": time.Now().Local().Format(util.DateFullLayout),
- "content": param.Answer,
- }
- ok1 := Mysql.UpdateByTx(tx, util.ANSWER, map[string]interface{}{"id": param.AnswerId}, answerUpdate)
- //修改问题
- questionUpdate := map[string]interface{}{
- "content": param.Question,
- "keywords": keywords,
- }
- ok2 := Mysql.UpdateByTx(tx, util.QUESTION, map[string]interface{}{"answer_id": param.AnswerId}, questionUpdate)
- return ok1 && ok2
- })
- if fool {
- query := `{"query":{"bool":{"must":[{"term":{"answerId":"` + strconv.Itoa(int(param.AnswerId)) + `"}}],"must_not":[],"should":[]}},"from":0,"size":10,"sort":[],"facets":{}}`
- //修改es数据
- newKnowledge := map[string]interface{}{
- "knowledgeId": param.KnowledgeId,
- "status": 1,
- "createTime": time.Now().Unix(),
- "createPerson": createPerson,
- "answer": param.Answer,
- "question": param.Question,
- "keywords": keywords,
- "answerId": param.AnswerId,
- "entId": param.EntId,
- }
- ok1 := elastic.Del(Index, Type, query)
- ok2 := elastic.Save(Index, Type, newKnowledge)
- questionVector, err := util.EncodeVector(keywords)
- if err != nil {
- log.Println("001 获取 向量失败 :" + err.Error())
- return false
- }
- // 存入向量库
- //插入es
- knowledgeV := map[string]interface{}{
- "mod_time": time.Now().Unix(),
- "answer": param.Answer,
- "question": param.Question,
- "_id": param.AnswerId,
- "entId": param.EntId,
- "keywords": keywords,
- "questionVector": questionVector,
- }
- if !ESV7.Save(ESV7Index, ESV7Type, knowledgeV) {
- logx.Error("知识库添加向量失败:", knowledgeV)
- }
- return ok1 && ok2
- }
- return ok
- }
- // KnowledgeList 问题列表
- func (k *KnowledgeService) KnowledgeList(param *knowledgeclient.ListRequest) *knowledgeclient.ListData {
- var knowledgeList knowledgeclient.ListData
- var data []*knowledgeclient.KnowledgeEntity
- countSql := fmt.Sprintf("SELECT COUNT(b.id) FROM %s a LEFT JOIN %s b ON a.id = b.knowledge_id LEFT JOIN %s c ON b.id = c.answer_id WHERE b.`status` =1 and a.ent_id=%d", util.KNOWLEDGE, util.ANSWER, util.QUESTION, param.EntId)
- count := Mysql.CountBySql(countSql)
- if count > 0 {
- //列表数据
- sql1 := fmt.Sprintf("SELECT b.content as answer,c.content as question,b.id,b.knowledge_id FROM %s a LEFT JOIN %s b ON a.id = b.knowledge_id LEFT JOIN %s c ON b.id = c.answer_id WHERE b.`status` =1 and a.ent_id=? order by b.update_time desc limit ?,?", util.KNOWLEDGE, util.ANSWER, util.QUESTION)
- datalist := Mysql.SelectBySql(sql1, param.EntId, (param.PageIndex-1)*param.PageSize, param.PageSize)
- if datalist != nil && *datalist != nil && len(*datalist) > 0 {
- for _, value := range *datalist {
- knowledge := knowledgeclient.KnowledgeEntity{}
- knowledge.Answer = cm.ObjToString(value["answer"])
- knowledge.Question = cm.ObjToString(value["question"])
- knowledge.AnswerId = cm.Int64All(value["id"])
- knowledge.KnowledgeId = cm.Int64All(value["knowledge_id"])
- data = append(data, &knowledge)
- }
- }
- knowledgeList.Total = count
- knowledgeList.Data = data
- }
- return &knowledgeList
- }
- // KnowledgeInfo 问题详情
- func (k *KnowledgeService) KnowledgeInfo(answerId int64) (data *knowledgeclient.KnowledgeEntity, ok bool) {
- //util.ANSWER,util.QUESTION
- sql1 := fmt.Sprintf("SELECT b.content as answer,c.content as question,b.id,b.knowledge_id FROM %s b LEFT JOIN %s c ON b.id = c.answer_id WHERE b.`status` =1 AND b.id = %d", util.ANSWER, util.QUESTION, answerId)
- datalist := Mysql.SelectBySql(sql1)
- if datalist != nil && *datalist != nil && len(*datalist) > 0 {
- knowledge := knowledgeclient.KnowledgeEntity{}
- knowledge.Answer = cm.ObjToString((*datalist)[0]["answer"])
- knowledge.Question = cm.ObjToString((*datalist)[0]["question"])
- knowledge.AnswerId = cm.Int64All((*datalist)[0]["id"])
- knowledge.KnowledgeId = cm.Int64All((*datalist)[0]["knowledge_id"])
- return &knowledge, true
- }
- return nil, false
- }
- // KnowledgeDel 删除问题
- func (k *KnowledgeService) KnowledgeDel(answerId int64) (ok bool) {
- ok = false
- //修改答案
- answerUpdate := map[string]interface{}{
- "update_time": time.Now().Local().Format(util.DateFullLayout),
- "status": 0,
- }
- fool := Mysql.Update(util.ANSWER, map[string]interface{}{"id": answerId}, answerUpdate)
- if fool {
- //删除es数据
- query := `{"query":{"bool":{"must":[{"term":{"answerId":"` + strconv.Itoa(int(answerId)) + `"}}],"must_not":[],"should":[]}},"from":0,"size":1,"sort":[],"facets":{}}`
- ok = elastic.Del(Index, Type, query)
- if !ESV7.DelById(ESV7Index, ESV7Type, cm.InterfaceToStr(answerId)) {
- logx.Error("删除向量库失败:", answerId)
- }
- }
- return ok
- }
- // FindAnswer 根据问题推荐一个答案
- func (k *KnowledgeService) FindAnswer(param *knowledgeclient.FindAnswerReq, addr, index, segment string) *knowledgeclient.Question {
- var question knowledgeclient.Question
- if len([]rune(param.Question)) <= 1 {
- return &question
- }
- robotEntId := SE.Decode4Hex(param.RobotEntId)
- //组装es query
- //query := util.DSL4SmartResponse(param.Question, robotEntId, int(param.Type), addr, index, segment)
- //问题进行分词
- keywords := ""
- keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
- if len(keywordsArr) != 0 {
- for _, val := range keywordsArr {
- keywords += val + " "
- }
- }
- if keywords == "" {
- keywords = param.Question
- }
- minScore := 1.75
- if len(ki.C.MinScore) > 0 {
- minScore = ki.C.MinScore[0]
- }
- query := util.GetAnswerQueryStr(keywords, robotEntId, 1, minScore)
- logx.Info("query:", query)
- if query != "" {
- res := ESV7.Get(ESV7Index, ESV7Type, query)
- if res != nil && len(*res) > 0 {
- data := (*res)[0]
- question.Answer = cm.ObjToString(data["answer"])
- question.Question = cm.ObjToString(data["question"])
- }
- }
- return &question
- }
- // RecommendAnswer 根据问题推荐三个答案
- func (k *KnowledgeService) RecommendAnswer(param *knowledgeclient.FindAnswerReq, segment string, recommendQuestionCount int) []*knowledgeclient.Question {
- var (
- answers []*knowledgeclient.Question
- )
- if len([]rune(param.Question)) <= 1 {
- return answers
- }
- limit := 3
- if param.ReqSource == 1 {
- limit = recommendQuestionCount
- }
- //问题进行分词
- keywords := ""
- keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
- if len(keywordsArr) != 0 {
- for _, val := range keywordsArr {
- keywords += val + " "
- }
- }
- if keywords == "" {
- keywords = param.Question
- }
- for i := 0; i < len(ki.C.MinScore); i++ {
- query := util.GetAnswerQueryStr(keywords, param.RobotEntId, limit, ki.C.MinScore[i])
- logx.Info("query:", query)
- res := ESV7.Get(ESV7Index, ESV7Type, query)
- logx.Info("res:", res)
- if res != nil && len(*res) > 0 {
- if i < 1 {
- for _, val := range *res {
- answers = append(answers, &knowledgeclient.Question{
- Question: cm.ObjToString(val["question"]),
- Answer: cm.ObjToString(val["answer"]),
- })
- }
- return answers
- } else {
- answers = append(answers, &knowledgeclient.Question{
- Question: cm.ObjToString((*res)[0]["question"]),
- Answer: cm.ObjToString((*res)[0]["answer"]),
- })
- return answers
- }
- }
- }
- return answers
- }
|