knowledgeService.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. package service
  2. import (
  3. cm "app.yhyue.com/moapp/jybase/common"
  4. . "app.yhyue.com/moapp/jybase/encrypt"
  5. elastic "app.yhyue.com/moapp/jybase/esv1"
  6. "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/usercenter"
  7. . "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/entity"
  8. "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/rpc/knowledge/knowledgeclient"
  9. "bp.jydev.jianyu360.cn/SocialPlatform/knowledgeBase/rpc/knowledge/util"
  10. "context"
  11. "database/sql"
  12. "errors"
  13. "github.com/zeromicro/go-zero/core/logx"
  14. "log"
  15. "strconv"
  16. "time"
  17. )
  18. type KnowledgeService struct{}
  19. var (
  20. Index = "smart_new"
  21. Type = "smart"
  22. )
  23. func (k *KnowledgeService) KnowledgeAdd(param *knowledgeclient.AddRequest, segment string) (bool, string, error) {
  24. //先查找知识库Id
  25. query := map[string]interface{}{"status": 1, "appid": param.AppId, "ent_id": param.EntId}
  26. datalist := Mysql.Find(util.KNOWLEDGE, query, "id", "", -1, -1)
  27. if datalist != nil && *datalist != nil && len(*datalist) > 0 {
  28. //问题进行分词
  29. keywords := ""
  30. keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
  31. log.Println("keywordsArr", keywordsArr)
  32. if len(keywordsArr) != 0 {
  33. for _, val := range keywordsArr {
  34. keywords += val + " "
  35. }
  36. }
  37. if keywords == "" {
  38. keywords = param.Question
  39. }
  40. //通过entUserId获取创建人名称,调用用户中心
  41. req := &usercenter.EntUserReq{
  42. EntId: param.EntId,
  43. EntUserId: param.EntUserId,
  44. AppId: param.AppId,
  45. }
  46. resp, err := UserCenterLib.GetEntUserInfo(context.Background(), req)
  47. if err != nil {
  48. logx.Info("查询用户中台创建人信息失败", param.EntId, param.EntUserId, "err:", err)
  49. return false, "查询用户中台创建人信息失败", err
  50. }
  51. createPerson := resp.Data.Name
  52. var answerId int64
  53. nowTime := time.Now().Local().Format(util.Date_Full_Layout)
  54. fool := Mysql.ExecTx("添加知识", func(tx *sql.Tx) bool {
  55. //插入答案
  56. answerData := map[string]interface{}{
  57. "knowledge_id": (*datalist)[0]["id"],
  58. "status": 1,
  59. "create_time": nowTime,
  60. "update_time": nowTime,
  61. "create_person": createPerson,
  62. "content": param.Answer,
  63. }
  64. answerId = Mysql.Insert(util.ANSWER, answerData)
  65. //插入问题
  66. questionData := map[string]interface{}{
  67. "answer_id": answerId,
  68. "content": param.Question,
  69. "keywords": keywords,
  70. }
  71. questionId := Mysql.Insert(util.QUESTION, questionData)
  72. return answerId > 0 && questionId > 0
  73. })
  74. if fool {
  75. //插入es
  76. knowledge := map[string]interface{}{
  77. "knowledgeId": (*datalist)[0]["id"],
  78. "status": 1,
  79. "createTime": time.Now().Unix(),
  80. "createPerson": createPerson,
  81. "answer": param.Answer,
  82. "question": param.Question,
  83. "keywords": keywords,
  84. "answerId": answerId,
  85. "entId": param.EntId,
  86. }
  87. b := elastic.Save(Index, Type, knowledge)
  88. if b {
  89. return true, "插入es成功", nil
  90. } else {
  91. return false, "插入es出错", errors.New("插入es出错")
  92. }
  93. } else {
  94. return false, "插入mysql出错", errors.New("插入mysql出错")
  95. }
  96. } else {
  97. return false, "租户不存在", errors.New("租户不存在")
  98. }
  99. }
  100. func (k *KnowledgeService) KnowledgeEdit(param *knowledgeclient.KnowledgeEditReq, segment string) (ok bool, msg string, err error) {
  101. //获取问题分词
  102. keywords := ""
  103. keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
  104. log.Println("keywordsArr", keywordsArr)
  105. if len(keywordsArr) != 0 {
  106. for _, val := range keywordsArr {
  107. keywords += val + " "
  108. }
  109. }
  110. if keywords == "" {
  111. keywords = param.Question
  112. }
  113. //通过entUserId获取创建人名称
  114. req := &usercenter.EntUserReq{
  115. EntId: param.EntId,
  116. EntUserId: param.EntUserId,
  117. AppId: param.AppId,
  118. }
  119. resp := &usercenter.EntUserResp{}
  120. resp, err = UserCenterLib.GetEntUserInfo(context.Background(), req)
  121. if err != nil {
  122. logx.Info("查询用户中台创建人信息失败", param.EntId, param.EntUserId, "err:", err)
  123. return false, "查询用户中台创建人信息失败", err
  124. }
  125. createPerson := resp.Data.Name
  126. fool := Mysql.ExecTx("编辑问题、答案", func(tx *sql.Tx) bool {
  127. //修改答案
  128. answerUpdate := map[string]interface{}{
  129. "update_time": time.Now().Local().Format(util.Date_Full_Layout),
  130. "content": param.Answer,
  131. }
  132. ok1 := Mysql.UpdateByTx(tx, util.ANSWER, map[string]interface{}{"id": param.AnswerId}, answerUpdate)
  133. //修改问题
  134. questionUpdate := map[string]interface{}{
  135. "content": param.Question,
  136. "keywords": keywords,
  137. }
  138. ok2 := Mysql.UpdateByTx(tx, util.QUESTION, map[string]interface{}{"answer_id": param.AnswerId}, questionUpdate)
  139. return ok1 && ok2
  140. })
  141. if fool {
  142. query := `{"query":{"bool":{"must":[{"term":{"answerId":"` + strconv.Itoa(int(param.AnswerId)) + `"}}],"must_not":[],"should":[]}},"from":0,"size":10,"sort":[],"facets":{}}`
  143. //修改es数据
  144. newKnowledge := map[string]interface{}{
  145. "knowledgeId": param.KnowledgeId,
  146. "status": 1,
  147. "createTime": time.Now().Unix(),
  148. "createPerson": createPerson,
  149. "answer": param.Answer,
  150. "question": param.Question,
  151. "keywords": keywords,
  152. "answerId": param.AnswerId,
  153. "entId": param.EntId,
  154. }
  155. ok1 := elastic.Del(Index, Type, query)
  156. ok := elastic.Save(Index, Type, newKnowledge)
  157. if ok && ok1 {
  158. ok = true
  159. msg = "修改问题成功"
  160. } else {
  161. ok = false
  162. err = errors.New("删除es问题失败")
  163. msg = "删除es问题失败"
  164. }
  165. } else {
  166. ok = false
  167. err = errors.New("修改mysql问题失败")
  168. msg = "修改mysql问题失败"
  169. }
  170. return
  171. }
  172. func (k *KnowledgeService) KnowledgeList(param *knowledgeclient.ListRequest) *knowledgeclient.ListData {
  173. var knowledgeList knowledgeclient.ListData
  174. var data []*knowledgeclient.KnowledgeEntity
  175. countSql := "SELECT COUNT(b.id) FROM " + util.KNOWLEDGE +
  176. " a LEFT JOIN " + util.ANSWER + " b ON a.id = b.knowledge_id LEFT JOIN " + util.QUESTION +
  177. " c ON b.id = c.answer_id WHERE b.`status` =1 and a.ent_id=?"
  178. count := Mysql.CountBySql(countSql, param.EntId)
  179. log.Println("总数:", count)
  180. if count > 0 {
  181. //列表数据
  182. sql1 := "SELECT b.content as answer,c.content as question,b.id,b.knowledge_id FROM " + util.KNOWLEDGE +
  183. " a LEFT JOIN " + util.ANSWER + " b ON a.id = b.knowledge_id LEFT JOIN " + util.QUESTION +
  184. " c ON b.id = c.answer_id WHERE b.`status` =1 and a.ent_id=? order by b.update_time desc limit ?,?"
  185. //log.Println(sql, param.EntId, (param.PageIndex-1)*param.PageSize, param.PageSize)
  186. datalist := Mysql.SelectBySql(sql1, param.EntId, (param.PageIndex-1)*param.PageSize, param.PageSize)
  187. if datalist != nil && *datalist != nil && len(*datalist) > 0 {
  188. for _, value := range *datalist {
  189. knowledge := knowledgeclient.KnowledgeEntity{}
  190. knowledge.Answer = cm.ObjToString(value["answer"])
  191. knowledge.Question = cm.ObjToString(value["question"])
  192. knowledge.AnswerId = cm.Int64All(value["id"])
  193. knowledge.KnowledgeId = cm.Int64All(value["knowledge_id"])
  194. data = append(data, &knowledge)
  195. }
  196. }
  197. //log.Println("数据:", data)
  198. knowledgeList.Total = count
  199. knowledgeList.Data = data
  200. }
  201. return &knowledgeList
  202. }
  203. func (k *KnowledgeService) KnowledgeInfo(answerId int64) (data *knowledgeclient.KnowledgeEntity, ok bool) {
  204. sql1 := "SELECT b.content as answer,c.content as question,b.id,b.knowledge_id FROM " + util.ANSWER +
  205. " b LEFT JOIN " + util.QUESTION + " c ON b.id = c.answer_id WHERE b.`status` =1 AND b.id = ? "
  206. datalist := Mysql.SelectBySql(sql1, answerId)
  207. if datalist != nil && *datalist != nil && len(*datalist) > 0 {
  208. knowledge := knowledgeclient.KnowledgeEntity{}
  209. knowledge.Answer = cm.ObjToString((*datalist)[0]["answer"])
  210. knowledge.Question = cm.ObjToString((*datalist)[0]["question"])
  211. knowledge.AnswerId = cm.Int64All((*datalist)[0]["id"])
  212. knowledge.KnowledgeId = cm.Int64All((*datalist)[0]["knowledge_id"])
  213. return &knowledge, true
  214. }
  215. return nil, false
  216. }
  217. func (k *KnowledgeService) KnowledgeDel(answerId int64) (ok bool, msg string) {
  218. //修改答案
  219. answerUpdate := map[string]interface{}{
  220. "update_time": time.Now().Local().Format(util.Date_Full_Layout),
  221. "status": 0,
  222. }
  223. fool := Mysql.Update(util.ANSWER, map[string]interface{}{"id": answerId}, answerUpdate)
  224. if fool {
  225. //删除es数据
  226. query := `{"query":{"bool":{"must":[{"term":{"answerId":"` + strconv.Itoa(int(answerId)) + `"}}],"must_not":[],"should":[]}},"from":0,"size":10,"sort":[],"facets":{}}`
  227. ok := elastic.Del(Index, Type, query)
  228. if ok {
  229. return true, "删除成功"
  230. } else {
  231. return false, "删除es问题失败"
  232. }
  233. }
  234. return false, "删除mysql问题失败"
  235. }
  236. func (k *KnowledgeService) FindAnswer(param *knowledgeclient.FindAnswerReq, addr, index, segment string) *knowledgeclient.Question {
  237. var question knowledgeclient.Question
  238. robotEntId := SE.Decode4Hex(param.RobotEntId)
  239. //组装es query
  240. query := util.DSL4SmartResponse(param.Question, robotEntId, int(param.Type), addr, index, segment)
  241. logx.Info("query:", query)
  242. if query != "" {
  243. res := elastic.Get(Index, Type, query)
  244. if res != nil && len(*res) > 0 {
  245. data := (*res)[0]
  246. question.Answer = cm.ObjToString(data["answer"])
  247. question.Question = cm.ObjToString(data["question"])
  248. }
  249. }
  250. return &question
  251. }
  252. func (k *KnowledgeService) RecommendAnswer(param *knowledgeclient.FindAnswerReq, segment string) []*knowledgeclient.Question {
  253. var (
  254. keyWords = ""
  255. searchField = `"answer","question"`
  256. answers []*knowledgeclient.Question
  257. )
  258. //根据问题进行分词
  259. keywordsArr := util.HanlpGetNormalWords(param.Question, segment)
  260. log.Println("keywordsArr", keywordsArr)
  261. if len(keywordsArr) != 0 {
  262. for _, val := range keywordsArr {
  263. keyWords += val + " "
  264. }
  265. }
  266. if keyWords == "" {
  267. keyWords = param.Question
  268. }
  269. log.Println("问题分词关键字2:", keyWords)
  270. var query = util.DSL4SearchByKwsOrid(keyWords, SE.Decode4Hex(param.RobotEntId))
  271. res := elastic.GetAllByNgram(Index, Type, query, "", "", searchField, 0, 3, 0, false)
  272. log.Println("推荐3个答案:", res)
  273. if res != nil && len(*res) > 0 {
  274. for _, val := range *res {
  275. answers = append(answers, &knowledgeclient.Question{
  276. Question: cm.ObjToString(val["question"]),
  277. Answer: cm.ObjToString(val["answer"]),
  278. })
  279. }
  280. }
  281. return answers
  282. }