Преглед изворни кода

Merge branch 'feature/deepseek_rag_1.0' into debug

kobe6258 пре 1 недеља
родитељ
комит
71272e341f

+ 81 - 92
controllers/llm/abstract.go

@@ -2,16 +2,17 @@ package llm
 
 import (
 	"encoding/json"
+	"eta/eta_api/cache"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/rag"
 	"eta/eta_api/models/rag/request"
 	"eta/eta_api/models/rag/response"
+	"eta/eta_api/services"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
-	"strings"
-	"time"
 )
 
 // AbstractController
@@ -55,28 +56,66 @@ func (c *AbstractController) List() {
 	}
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
-	var condition string
-	var pars []interface{}
+	var total int
+	viewList := make([]rag.WechatArticleAbstractView, 0)
 
-	if keyWord != "" {
-		condition += fmt.Sprintf(` AND a.%s like ?`, rag.WechatArticleAbstractColumns.Content)
-		pars = append(pars, `%`+keyWord+`%`)
-	}
+	if keyWord == `` {
+		var condition string
+		var pars []interface{}
+		condition += fmt.Sprintf(` AND c.%s = ?`, rag.WechatPlatformColumns.Enabled)
+		pars = append(pars, 1)
 
-	if tagId > 0 {
-		condition += fmt.Sprintf(` AND d.%s = ?`, rag.WechatPlatformTagMappingColumns.TagID)
-		pars = append(pars, tagId)
-	}
+		if keyWord != "" {
+			condition += fmt.Sprintf(` AND a.%s like ?`, rag.WechatArticleAbstractColumns.Content)
+			pars = append(pars, `%`+keyWord+`%`)
+		}
 
-	obj := new(rag.WechatArticleAbstract)
-	total, list, err := obj.GetPageListByTagAndPlatformCondition(condition, pars, startSize, pageSize)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取失败,Err:" + err.Error()
-		return
-	}
+		if tagId > 0 {
+			condition += fmt.Sprintf(` AND d.%s = ?`, rag.WechatPlatformTagMappingColumns.TagID)
+			pars = append(pars, tagId)
+		}
 
-	viewList := obj.WechatArticleAbstractItem(list)
+		obj := new(rag.WechatArticleAbstract)
+		tmpTotal, list, err := obj.GetPageListByTagAndPlatformCondition(condition, pars, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		viewList = obj.WechatArticleAbstractItem(list)
+	} else {
+		sortMap := map[string]string{
+			"ModifyTime":              "desc",
+			"WechatArticleAbstractId": "desc",
+		}
+
+		obj := new(rag.WechatPlatform)
+		platformList, err := obj.GetListByCondition(` AND enabled = 1 `, []interface{}{}, 0, 100000)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		platformIdList := make([]int, 0)
+		for _, v := range platformList {
+			platformIdList = append(platformIdList, v.WechatPlatformId)
+		}
+		tagList := make([]int, 0)
+		if tagId > 0 {
+			tagList = append(tagList, tagId)
+		}
+		tmpTotal, list, err := elastic.WechatArticleAbstractEsSearch(keyWord, tagList, platformIdList, startSize, pageSize, sortMap)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		total = int(tmpTotal)
+		if list != nil && len(list) > 0 {
+			viewList = list[0].ToViewList(list)
+		}
+	}
 
 	page := paging.GetPaging(currentIndex, pageSize, total)
 	resp := response.AbstractListListResp{
@@ -90,56 +129,6 @@ func (c *AbstractController) List() {
 	br.Data = resp
 }
 
-// 向量库删除
-// 摘要库删除
-// 批量加入到向量库
-
-// vector_key
-
-// Add
-// @Title 新增问题
-// @Description 新增问题
-// @Param	request	body request.AddQuestionReq true "type json string"
-// @Success 200 Ret=200 新增成功
-// @router /abstract/add [post]
-func (c *AbstractController) Add() {
-	br := new(models.BaseResponse).Init()
-	defer func() {
-		c.Data["json"] = br
-		c.ServeJSON()
-	}()
-	var req request.AddQuestionReq
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
-	if err != nil {
-		br.Msg = "参数解析异常!"
-		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-		return
-	}
-	req.Content = strings.TrimSpace(req.Content)
-	if req.Content == "" {
-		br.Msg = "请输入问题"
-		br.IsSendEmail = false
-		return
-	}
-	item := &rag.Question{
-		QuestionId:      0,
-		QuestionContent: req.Content,
-		Sort:            0,
-		ModifyTime:      time.Now(),
-		CreateTime:      time.Now(),
-	}
-	err = item.Create()
-	if err != nil {
-		br.Msg = "添加失败"
-		br.ErrMsg = "添加失败,Err:" + err.Error()
-		return
-	}
-
-	br.Ret = 200
-	br.Success = true
-	br.Msg = `添加成功`
-}
-
 // Del
 // @Title 删除摘要
 // @Description 删除摘要
@@ -178,17 +167,26 @@ func (c *AbstractController) Del() {
 	}
 
 	if len(list) > 0 {
+		// 删除向量库
+		err = services.DelDoc(list)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除向量库失败,Err:" + err.Error()
+			return
+		}
+
+		// 删除摘要
 		err = obj.DelByIdList(req.WechatArticleAbstractIdList)
 		if err != nil {
 			br.Msg = "删除失败"
 			br.ErrMsg = "删除失败,Err:" + err.Error()
 			return
 		}
-	}
 
-	//for _,v:=range list{
-	//	// todo 删除向量库
-	//}
+		for _, v := range list {
+			go services.AddOrEditEsWechatArticleAbstract(v.WechatArticleAbstractId)
+		}
+	}
 
 	br.Ret = 200
 	br.Success = true
@@ -231,15 +229,13 @@ func (c *AbstractController) VectorDel() {
 		}
 		return
 	}
-	for _, item := range list {
-		// todo 删除向量库
-		item.VectorKey = ``
-		err = item.Update([]string{"vector_key", "modify_time"})
-		if err != nil {
-			br.Msg = "删除失败"
-			br.ErrMsg = "删除失败,Err:" + err.Error()
-			return
-		}
+
+	// 删除向量库
+	err = services.DelDoc(list)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
 	}
 
 	br.Ret = 200
@@ -284,17 +280,10 @@ func (c *AbstractController) AddVector() {
 		return
 	}
 	for _, item := range list {
-		// todo 删除向量库
-		item.VectorKey = ``
-		err = item.Update([]string{"vector_key", "modify_time"})
-		if err != nil {
-			br.Msg = "删除失败"
-			br.ErrMsg = "删除失败,Err:" + err.Error()
-			return
-		}
+		cache.AddWechatArticleLlmOpToCache(item.WechatArticleId, ``)
 	}
 
 	br.Ret = 200
 	br.Success = true
-	br.Msg = `添加成功`
+	br.Msg = `添加向量库中,请稍后查看`
 }

+ 1 - 1
controllers/llm/question.go

@@ -58,7 +58,7 @@ func (c *QuestionController) List() {
 	var pars []interface{}
 
 	if keyWord != "" {
-		condition += fmt.Sprintf(` AND %s = ?`, rag.QuestionColumns.QuestionContent)
+		condition += fmt.Sprintf(` AND %s like ?`, rag.QuestionColumns.QuestionContent)
 		pars = append(pars, `%`+keyWord+`%`)
 	}
 

+ 162 - 48
controllers/llm/wechat_platform.go

@@ -9,6 +9,8 @@ import (
 	"eta/eta_api/models/rag/request"
 	"eta/eta_api/models/rag/response"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
@@ -115,25 +117,49 @@ func (c *WechatPlatformController) Add() {
 		return
 	}
 
-	var condition string
-	var pars []interface{}
-	condition += fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.Nickname)
-	pars = append(pars, req.Name)
-	obj := new(rag.WechatPlatform)
-	item, err := obj.GetByCondition(condition, pars)
-	if err != nil && !utils.IsErrNoRow(err) {
-		br.Msg = "公众号信息获取失败"
-		br.ErrMsg = "公众号信息获取失败,Err:" + err.Error()
-		return
+	// 名称校验
+	{
+		var condition string
+		var pars []interface{}
+		condition += fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.Nickname)
+		pars = append(pars, req.Name)
+		obj := new(rag.WechatPlatform)
+		item, err := obj.GetByCondition(condition, pars)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "公众号信息获取失败"
+			br.ErrMsg = "公众号信息获取失败,Err:" + err.Error()
+			return
+		}
+
+		if item.WechatPlatformId > 0 {
+			br.Msg = "公众号名称重复"
+			br.IsSendEmail = false
+			return
+		}
 	}
 
-	if item.WechatPlatformId > 0 {
-		br.Msg = "公众号名称重复"
-		br.IsSendEmail = false
-		return
+	// 链接校验
+	{
+		var condition string
+		var pars []interface{}
+		condition += fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.ArticleLink)
+		pars = append(pars, req.Link)
+		obj := new(rag.WechatPlatform)
+		item, err := obj.GetByCondition(condition, pars)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "公众号信息获取失败"
+			br.ErrMsg = "公众号信息获取失败,Err:" + err.Error()
+			return
+		}
+
+		if item.WechatPlatformId > 0 {
+			br.Msg = "公众号链接重复"
+			br.IsSendEmail = false
+			return
+		}
 	}
 
-	item = &rag.WechatPlatform{
+	item := &rag.WechatPlatform{
 		WechatPlatformId: 0,
 		FakeId:           "",
 		Nickname:         req.Name,
@@ -260,7 +286,7 @@ func (c *WechatPlatformController) PublicList() {
 	var pars []interface{}
 
 	if keyWord != "" {
-		condition += fmt.Sprintf(` AND %s = ?`, rag.WechatPlatformColumns.Nickname)
+		condition += fmt.Sprintf(` AND %s like ?`, rag.WechatPlatformColumns.Nickname)
 		pars = append(pars, `%`+keyWord+`%`)
 	}
 
@@ -363,7 +389,7 @@ func (c *WechatPlatformController) Op() {
 		return
 	}
 	obj := rag.WechatPlatform{}
-	wechatPlatform, err := obj.GetByID(req.WechatPlatformId)
+	wechatPlatform, err := obj.GetById(req.WechatPlatformId)
 	if err != nil {
 		br.Msg = "修改失败"
 		br.ErrMsg = "修改失败,Err:" + err.Error()
@@ -382,6 +408,9 @@ func (c *WechatPlatformController) Op() {
 		return
 	}
 
+	// 异步处理公众号下面的文章
+	go services.AddOrEditEsWechatPlatformId(wechatPlatform.WechatPlatformId)
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "修改成功"
@@ -419,7 +448,7 @@ func (c *WechatPlatformController) Refresh() {
 	}
 
 	obj := rag.WechatPlatform{}
-	wechatPlatform, err := obj.GetByID(req.WechatPlatformId)
+	wechatPlatform, err := obj.GetById(req.WechatPlatformId)
 	if err != nil {
 		br.Msg = "修改失败"
 		br.ErrMsg = "修改失败,Err:" + err.Error()
@@ -479,34 +508,71 @@ func (c *WechatPlatformController) ArticleList() {
 	}
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
-	var condition string
-	var pars []interface{}
+	//var condition string
+	//var pars []interface{}
+	//
+	//if keyWord != "" {
+	//	condition += fmt.Sprintf(` AND (b.%s like ? or a.%s like ? ) `, rag.WechatPlatformColumns.Nickname, rag.WechatArticleColumns.Title)
+	//	pars = append(pars, `%`+keyWord+`%`, `%`+keyWord+`%`)
+	//}
+	//
+	//if wechatPlatformId > 0 {
+	//	condition += fmt.Sprintf(` AND a.%s = ?`, rag.WechatArticleColumns.WechatPlatformID)
+	//	pars = append(pars, wechatPlatformId)
+	//}
+	//
+	//condition += fmt.Sprintf(` AND b.%s = ? `, rag.WechatPlatformColumns.Enabled)
+	//pars = append(pars, 1)
+
+	var total int
+	viewList := make([]rag.WechatArticleView, 0)
 
-	if keyWord != "" {
-		condition += fmt.Sprintf(` AND (b.%s like ? or a.%s like ? ) `, rag.WechatPlatformColumns.Nickname, rag.WechatArticleColumns.Title)
-		pars = append(pars, `%`+keyWord+`%`, `%`+keyWord+`%`)
-	}
+	if keyWord == `` {
+		var condition string
+		var pars []interface{}
 
-	if wechatPlatformId > 0 {
-		condition += fmt.Sprintf(` AND a.%s = ?`, rag.WechatArticleColumns.WechatPlatformID)
-		pars = append(pars, wechatPlatformId)
-	}
+		if keyWord != "" {
+			condition += fmt.Sprintf(` AND (b.%s like ? or a.%s like ? ) `, rag.WechatPlatformColumns.Nickname, rag.WechatArticleColumns.Title)
+			pars = append(pars, `%`+keyWord+`%`, `%`+keyWord+`%`)
+		}
 
-	condition += fmt.Sprintf(` AND b.%s = ? `, rag.WechatPlatformColumns.Enabled)
-	pars = append(pars, 1)
+		if wechatPlatformId > 0 {
+			condition += fmt.Sprintf(` AND a.%s = ?`, rag.WechatArticleColumns.WechatPlatformID)
+			pars = append(pars, wechatPlatformId)
+		}
 
-	obj := new(rag.WechatArticle)
-	total, list, err := obj.GetPageListByPlatformCondition(condition, pars, startSize, pageSize)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取失败,Err:" + err.Error()
-		return
-	}
+		//condition += fmt.Sprintf(` AND b.%s = ? `, rag.WechatPlatformColumns.Enabled)
+		//pars = append(pars, 1)
 
-	viewList := make([]rag.WechatArticleView, 0)
-	if list != nil && len(list) > 0 {
-		viewList = obj.ArticleAndPlatformListToViewList(list)
+		obj := new(rag.WechatArticle)
+		tmpTotal, list, err := obj.GetPageListByPlatformCondition(condition, pars, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+
+		if list != nil && len(list) > 0 {
+			viewList = obj.ArticleAndPlatformListToViewList(list)
+		}
+	} else {
+		sortMap := map[string]string{
+			"ArticleCreateTime": "desc",
+			"WechatArticleId":   "desc",
+		}
+		tmpTotal, list, err := elastic.WechatArticleEsSearch(keyWord, wechatPlatformId, startSize, pageSize, sortMap)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		total = int(tmpTotal)
+		if list != nil && len(list) > 0 {
+			viewList = list[0].ArticleAndPlatformListToViewList(list)
+		}
 	}
+
 	page := paging.GetPaging(currentIndex, pageSize, total)
 	resp := response.WechatArticleListListResp{
 		List:   viewList,
@@ -624,6 +690,9 @@ func (c *WechatPlatformController) ArticleDel() {
 		return
 	}
 
+	// 修改ES信息
+	services.AddOrEditEsWechatArticle(item.WechatArticleId)
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "删除成功"
@@ -649,15 +718,60 @@ func (c *WechatPlatformController) ArticleDel() {
 //	//item, _ := obj.GetByID(2)
 //	//fmt.Println(llm.BeachAddWechatPlatform(item))
 //
-//	obj := rag.WechatArticle{}
-//	list, _ := obj.GetListByCondition(`wechat_article_id,content`, ` AND wechat_article_id!=314 `, []interface{}{}, 0, 1000)
-//	//obj := rag.WechatPlatform{}
-//	//list, _ := obj.GetListByCondition(` AND wechat_platform_id !=1 `, []interface{}{}, 0, 100)
-//	//llm.ArticleToTmpFile(item.TextContent)
-//	for _, item := range list {
-//		//llm.ArticleToKnowledge(item)
-//		services.ReplaceWechatArticlePic(item)
+//	//obj := rag.WechatArticle{}
+//	//list, _ := obj.GetListByCondition(`wechat_article_id,content`, `  `, []interface{}{}, 0, 1)
+//	////obj := rag.WechatPlatform{}
+//	////list, _ := obj.GetListByCondition(` AND wechat_platform_id !=1 `, []interface{}{}, 0, 100)
+//	////llm.ArticleToTmpFile(item.TextContent)
+//	//for _, item := range list {
+//	//	//llm.ArticleToKnowledge(item)
+//	//	services.ReGenerateArticleAbstract(item)
+//	//}
+//
+//	// 重新生成摘要
+//	{
+//		obj := rag.WechatArticle{}
+//		list, _ := obj.GetListByCondition(``, ` AND text_content !='' AND abstract_status = 0`, []interface{}{}, 0, 300)
+//		for _, item := range list {
+//			services.GenerateArticleAbstract(item)
+//		}
 //	}
 //
+//	//// 删除摘要向量库
+//	//{
+//	//	obj := rag.WechatArticleAbstract{}
+//	//	list, _ := obj.GetListByCondition(`vector_key,wechat_article_abstract_id`, ` AND wechat_article_id in (25,27) `, []interface{}{}, 0, 10000)
+//	//	fmt.Println(services.DelDoc(list))
+//	//}
+//
 //	fmt.Println("修复结束")
 //}
+
+//func init() {
+//	//// 微信文章加到es
+//	//{
+//	//	obj := rag.WechatArticle{}
+//	//	list, _ := obj.GetListByCondition(` wechat_article_id `, ` `, []interface{}{}, 0, 10000)
+//	//	total := len(list)
+//	//	for k, item := range list {
+//	//		fmt.Println(k, "/", total)
+//	//		services.AddOrEditEsWechatArticle(item.WechatArticleId)
+//	//	}
+//	//
+//	//	fmt.Println("结束了")
+//	//}
+//
+//	//// 微信文章加到es
+//	{
+//		obj := rag.WechatArticleAbstract{}
+//		list, _ := obj.GetListByCondition(` wechat_article_abstract_id `, ` `, []interface{}{}, 0, 10000)
+//		total := len(list)
+//		for k, item := range list {
+//			fmt.Println(k, "/", total)
+//			services.AddOrEditEsWechatArticleAbstract(item.WechatArticleAbstractId)
+//		}
+//
+//		fmt.Println("结束了")
+//	}
+//
+//}

+ 1 - 0
controllers/user_login.go

@@ -560,6 +560,7 @@ func (this *UserLoginController) Login() {
 	}
 	resp.ProductName = productName
 	resp.Authority = sysUser.Authority
+	resp.Mobile = sysUser.Mobile
 
 	// 设置redis缓存
 	{

+ 11 - 2
models/business_conf.go

@@ -60,8 +60,10 @@ const (
 	BusinessConfEsIndexNameDataSource        = "EsIndexNameDataSource"        // ES索引名称-数据源
 	BusinessConfIsOpenChartExpired = "IsOpenChartExpired" // 图表是否鉴权
 	LLMInitConfig                            = "llmInitConfig"
-	KnowledgeBaseName                        = "KnowledgeBaseName"    // 摘要库
-	KnowledgeArticleName                     = "KnowledgeArticleName" // 原文库
+	KnowledgeBaseName                        = "KnowledgeBaseName"                // 摘要库
+	KnowledgeArticleName                     = "KnowledgeArticleName"             // 原文库
+	BusinessConfEsWechatArticle              = "EsIndexNameWechatArticle"         // ES索引名称-微信文章
+	BusinessConfEsWechatArticleAbstract      = "EsIndexNameWechatArticleAbstract" // ES索引名称-微信文章摘要
 )
 
 const (
@@ -266,6 +268,13 @@ func InitBusinessConf() {
 	if BusinessConfMap[BusinessConfEsIndexNameDataSource] != "" {
 		utils.EsDataSourceIndexName = BusinessConfMap[BusinessConfEsIndexNameDataSource]
 	}
+	// ES索引名称
+	if BusinessConfMap[BusinessConfEsWechatArticle] != "" {
+		utils.EsWechatArticleName = BusinessConfMap[BusinessConfEsWechatArticle]
+	}
+	if BusinessConfMap[BusinessConfEsWechatArticleAbstract] != "" {
+		utils.EsWechatArticleAbstractName = BusinessConfMap[BusinessConfEsWechatArticleAbstract]
+	}
 	confStr := BusinessConfMap[LLMInitConfig]
 	if confStr != "" {
 		var config LLMConfig

+ 1 - 1
models/rag/question.go

@@ -103,7 +103,7 @@ func (m *Question) GetByCondition(condition string, pars []interface{}) (item *Q
 }
 
 func (m *Question) GetListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*Question, err error) {
-	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s order by sort asc,question_id asc LIMIT ?,?`, m.TableName(), condition)
+	sqlStr := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s order by question_id desc LIMIT ?,?`, m.TableName(), condition)
 	pars = append(pars, startSize, pageSize)
 	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Find(&items).Error
 

+ 5 - 5
models/rag/wechat_article.go

@@ -18,7 +18,7 @@ type WechatArticle struct {
 	Description       string    `gorm:"column:description;type:varchar(255);comment:描述;" description:"描述"`
 	Content           string    `gorm:"column:content;type:longtext;comment:报告详情;" description:"报告详情"`
 	TextContent       string    `gorm:"column:text_content;type:text;comment:文本内容;" description:"文本内容"`
-	Abstract          string    `gorm:"column:abstract;type:text;comment:摘要;" description:"摘要"`
+	AbstractStatus    int       `gorm:"column:abstract_status;type:tinyint(4);comment:摘要生成情况,-1:生成失败,0:待生成,1:已生成;default:0;" description:"摘要生成情况,-1:生成失败,0:待生成,1:已生成"`
 	Country           string    `gorm:"column:country;type:varchar(255);comment:国家;" description:"国家"`
 	Province          string    `gorm:"column:province;type:varchar(255);comment:省;" description:"省"`
 	City              string    `gorm:"column:city;type:varchar(255);comment:市;" description:"市"`
@@ -45,7 +45,7 @@ var WechatArticleColumns = struct {
 	Description       string
 	Content           string
 	TextContent       string
-	Abstract          string
+	AbstractStatus    string
 	Country           string
 	Province          string
 	City              string
@@ -63,7 +63,7 @@ var WechatArticleColumns = struct {
 	Description:       "description",
 	Content:           "content",
 	TextContent:       "text_content",
-	Abstract:          "abstract",
+	AbstractStatus:    "abstract_status",
 	Country:           "country",
 	Province:          "province",
 	City:              "city",
@@ -83,6 +83,7 @@ type WechatArticleView struct {
 	Description                string `gorm:"column:description;type:varchar(255);comment:描述;" description:"描述"`
 	Content                    string `gorm:"column:content;type:longtext;comment:报告详情;" description:"报告详情"`
 	TextContent                string `gorm:"column:text_content;type:text;comment:文本内容;" description:"文本内容"`
+	AbstractStatus             int    `gorm:"column:abstract_status;type:tinyint(4);comment:摘要生成情况,-1:生成失败,0:待生成,1:已生成;default:0;" description:"摘要生成情况,-1:生成失败,0:待生成,1:已生成"`
 	Abstract                   string `gorm:"column:abstract;type:text;comment:摘要;" description:"摘要"`
 	Country                    string `gorm:"column:country;type:varchar(255);comment:国家;" description:"国家"`
 	Province                   string `gorm:"column:province;type:varchar(255);comment:省;" description:"省"`
@@ -116,7 +117,7 @@ func (m *WechatArticle) ToView() WechatArticleView {
 		Description:                m.Description,
 		Content:                    m.Content,
 		TextContent:                m.TextContent,
-		Abstract:                   m.Abstract,
+		AbstractStatus:             m.AbstractStatus,
 		Country:                    m.Country,
 		Province:                   m.Province,
 		City:                       m.City,
@@ -289,7 +290,6 @@ func (m *WechatArticle) GetCountByPlatformCondition(condition string, pars []int
 }
 
 func (m *WechatArticle) GetPageListByPlatformCondition(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*WechatArticleAndPlatform, err error) {
-
 	total, err = m.GetCountByPlatformCondition(condition, pars)
 	if err != nil {
 		return

+ 26 - 0
models/rag/wechat_article_abstract.go

@@ -70,6 +70,17 @@ func (m *WechatArticleAbstract) GetByIdList(idList []int) (items []*WechatArticl
 	return
 }
 
+func (m *WechatArticleAbstract) GetListByCondition(field, condition string, pars []interface{}, startSize, pageSize int) (items []*WechatArticleAbstract, err error) {
+	if field == "" {
+		field = "*"
+	}
+	sqlStr := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s  order by wechat_article_abstract_id desc LIMIT ?,?`, field, m.TableName(), condition)
+	pars = append(pars, startSize, pageSize)
+	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Find(&items).Error
+
+	return
+}
+
 func (m *WechatArticleAbstract) DelByIdList(idList []int) (err error) {
 	if len(idList) <= 0 {
 		return
@@ -97,6 +108,7 @@ func (m *WechatArticleAbstract) GetByWechatArticleId(id int) (item *WechatArticl
 type WechatArticleAbstractView struct {
 	WechatArticleAbstractId int    `gorm:"column:wechat_article_abstract_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"wechat_article_abstract_id"`
 	WechatArticleId         int    `gorm:"column:wechat_article_id;type:int(9) UNSIGNED;comment:关联的微信报告id;default:0;" description:"关联的微信报告id"`
+	WechatPlatformId        int    `gorm:"column:wechat_platform_id;type:int(11);comment:归属公众号id;default:0;" description:"归属公众号id"`
 	Abstract                string `gorm:"column:abstract;type:longtext;comment:摘要内容;" description:"摘要内容"` //
 	Version                 int    `gorm:"column:version;type:int(10) UNSIGNED;comment:版本号;default:1;" description:"版本号"`
 	VectorKey               string `gorm:"column:vector_key;type:varchar(255);comment:向量key标识;" description:"向量key标识"`
@@ -227,3 +239,17 @@ func (m *WechatArticleAbstract) GetPageListByTagAndPlatformCondition(condition s
 
 	return
 }
+
+// DelVectorKey
+// @Description: 批量删除向量库
+// @author: Roc
+// @receiver m
+// @datetime 2025-03-12 16:47:52
+// @param wechatArticleAbstractIdList []int
+// @return err error
+func (m *WechatArticleAbstract) DelVectorKey(wechatArticleAbstractIdList []int) (err error) {
+	sqlStr := fmt.Sprintf(`UPDATE %s set vector_key = '' WHERE wechat_article_abstract_id IN (?)`, m.TableName())
+	err = global.DbMap[utils.DbNameAI].Exec(sqlStr, wechatArticleAbstractIdList).Error
+
+	return
+}

+ 1 - 1
models/rag/wechat_platform.go

@@ -78,7 +78,7 @@ func (m *WechatPlatform) Del() (err error) {
 	return
 }
 
-func (m *WechatPlatform) GetByID(wechatPlatformId int) (item *WechatPlatform, err error) {
+func (m *WechatPlatform) GetById(wechatPlatformId int) (item *WechatPlatform, err error) {
 	err = global.DbMap[utils.DbNameAI].Where(fmt.Sprintf("%s = ?", WechatPlatformColumns.WechatPlatformID), wechatPlatformId).First(&item).Error
 
 	return

+ 1 - 0
models/system/sys_user.go

@@ -23,6 +23,7 @@ type LoginResp struct {
 	SysRoleTypeCode string `description:"角色类型编码"`
 	AdminId         int    `description:"系统用户id"`
 	ProductName     string `description:"产品名称:admin,ficc,权益"`
+	Mobile          string `description:"手机号"`
 	Authority       int    `description:"管理权限,0:无,1:部门负责人,2:小组负责人,或者ficc销售主管,4:ficc销售组长"`
 }
 

+ 0 - 9
routers/commentsRouter.go

@@ -8611,15 +8611,6 @@ func init() {
             Filters: nil,
             Params: nil})
 
-    beego.GlobalControllerRouter["eta/eta_api/controllers/llm:AbstractController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/llm:AbstractController"],
-        beego.ControllerComments{
-            Method: "Add",
-            Router: `/abstract/add`,
-            AllowHTTPMethods: []string{"post"},
-            MethodParams: param.Make(),
-            Filters: nil,
-            Params: nil})
-
     beego.GlobalControllerRouter["eta/eta_api/controllers/llm:AbstractController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/llm:AbstractController"],
         beego.ControllerComments{
             Method: "Del",

+ 302 - 0
services/elastic/wechat_article.go

@@ -0,0 +1,302 @@
+package elastic
+
+import (
+	"context"
+	"encoding/json"
+	"eta/eta_api/models/rag"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/olivere/elastic/v7"
+	"time"
+)
+
+// WechatArticleAndPlatform
+// @Description: 存入ES的数据
+type WechatArticleAndPlatform struct {
+	WechatArticleId  int    `gorm:"column:wechat_article_id;type:int(10) UNSIGNED;primaryKey;not null;" description:""`
+	WechatPlatformId int    `gorm:"column:wechat_platform_id;type:int(11);comment:归属公众号id;default:0;" description:"归属公众号id"`
+	FakeId           string `gorm:"column:fake_id;type:varchar(255);comment:公众号唯一id;" description:"公众号唯一id"`
+	Title            string `gorm:"column:title;type:varchar(255);comment:标题;" description:"标题"`
+	Link             string `gorm:"column:link;type:varchar(255);comment:链接;" description:"链接"`
+	CoverUrl         string `gorm:"column:cover_url;type:varchar(255);comment:公众号封面;" description:"公众号封面"`
+	Description      string `gorm:"column:description;type:varchar(255);comment:描述;" description:"描述"`
+	Content          string `gorm:"column:content;type:longtext;comment:报告详情;" description:"报告详情"`
+	TextContent      string `gorm:"column:text_content;type:text;comment:文本内容;" description:"文本内容"`
+	//Abstract          string    `gorm:"column:abstract;type:text;comment:摘要;" description:"摘要"`
+	Country           string    `gorm:"column:country;type:varchar(255);comment:国家;" description:"国家"`
+	Province          string    `gorm:"column:province;type:varchar(255);comment:省;" description:"省"`
+	City              string    `gorm:"column:city;type:varchar(255);comment:市;" description:"市"`
+	ArticleCreateTime time.Time `gorm:"column:article_create_time;type:datetime;comment:报告创建时间;default:NULL;" description:"报告创建时间"`
+	IsDeleted         int       `gorm:"column:is_deleted;type:tinyint(4);comment:是否删除,0:未删除,1: 已删除;default:0;" description:"是否删除,0:未删除,1: 已删除"`
+	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime;comment:修改时间;default:NULL;" description:"修改时间"`
+	CreateTime        time.Time `gorm:"column:create_time;type:datetime;comment:入库时间;default:NULL;" description:"入库时间"`
+	Nickname          string    `gorm:"column:nickname;type:varchar(255);comment:公众号名称;" description:"nickname"`          // 公众号名称
+	Alias             string    `gorm:"column:alias;type:varchar(255);comment:别名;" description:"alias"`                   // 别名
+	RoundHeadImg      string    `gorm:"column:round_head_img;type:varchar(255);comment:头像;" description:"round_head_img"` // 头像
+}
+
+func (m *WechatArticleAndPlatform) ToView() rag.WechatArticleView {
+	var articleCreateTime, modifyTime, createTime string
+
+	if !m.ArticleCreateTime.IsZero() {
+		articleCreateTime = m.ArticleCreateTime.Format(utils.FormatDateTime)
+	}
+	if !m.CreateTime.IsZero() {
+		createTime = m.CreateTime.Format(utils.FormatDateTime)
+	}
+	if !m.ModifyTime.IsZero() {
+		modifyTime = m.ModifyTime.Format(utils.FormatDateTime)
+	}
+	return rag.WechatArticleView{
+		WechatArticleId:  m.WechatArticleId,
+		WechatPlatformId: m.WechatPlatformId,
+		FakeId:           m.FakeId,
+		Title:            m.Title,
+		Link:             m.Link,
+		CoverUrl:         m.CoverUrl,
+		Description:      m.Description,
+		Content:          m.Content,
+		TextContent:      m.TextContent,
+		//Abstract:                   m.Abstract,
+		Country:                    m.Country,
+		Province:                   m.Province,
+		City:                       m.City,
+		ArticleCreateTime:          articleCreateTime,
+		ModifyTime:                 modifyTime,
+		CreateTime:                 createTime,
+		WechatPlatformName:         m.Nickname,
+		WechatPlatformRoundHeadImg: m.RoundHeadImg,
+	}
+}
+
+func (m *WechatArticleAndPlatform) ArticleAndPlatformListToViewList(list []*WechatArticleAndPlatform) (wechatArticleViewList []rag.WechatArticleView) {
+	wechatArticleViewList = make([]rag.WechatArticleView, 0)
+
+	for _, v := range list {
+		wechatArticleViewList = append(wechatArticleViewList, v.ToView())
+	}
+	return
+}
+
+// WechatArticleEsAddOrEdit
+// @Description: 新增/编辑微信文章
+// @author: Roc
+// @datetime 2025-03-13 10:24:05
+// @param docId string
+// @param item WechatArticleAndPlatform
+// @return err error
+func WechatArticleEsAddOrEdit(docId string, item WechatArticleAndPlatform) (err error) {
+	if docId == "" {
+		return
+	}
+	if utils.EsWechatArticleName == `` {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("WechatArticleEsAddOrEdit Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Index().Index(utils.EsWechatArticleName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
+	if err != nil {
+		fmt.Println("新增失败:", err.Error())
+		return err
+	}
+	if resp.Status == 0 {
+		fmt.Println("新增成功", resp.Result)
+		err = nil
+	} else {
+		fmt.Println("WechatArticleEsAddOrEdit", resp.Status, resp.Result)
+	}
+
+	return
+}
+
+// WechatArticleEsDel
+// @Description: 删除微信文章
+// @author: Roc
+// @datetime 2025-03-13 10:23:55
+// @param docId string
+// @return err error
+func WechatArticleEsDel(docId string) (err error) {
+	if docId == "" {
+		return
+	}
+	if utils.EsWechatArticleName == `` {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Delete().Index(utils.EsWechatArticleName).Id(docId).Refresh(`true`).Do(context.Background())
+	if err != nil {
+		return
+	}
+	if resp.Status == 0 {
+		fmt.Println("删除成功")
+	} else {
+		fmt.Println("WechatArticleEsDel", resp.Status, resp.Result)
+	}
+
+	return
+}
+
+func WechatArticleEsSearch(keywordStr string, wechatPlatformId, from, size int, sortMap map[string]string) (total int64, list []*WechatArticleAndPlatform, err error) {
+	indexName := utils.EsWechatArticleName
+	list = make([]*WechatArticleAndPlatform, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	query := elastic.NewBoolQuery()
+
+	if wechatPlatformId > 0 {
+		query = query.Must(elastic.NewTermQuery("WechatPlatformId", wechatPlatformId))
+	}
+
+	// 名字匹配
+	if keywordStr != `` {
+		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, "Title"))
+	}
+
+	// 排序
+	sortList := make([]*elastic.FieldSort, 0)
+	// 如果没有关键字,那么就走指标id倒序
+
+	for orderKey, orderType := range sortMap {
+		switch orderType {
+		case "asc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Asc())
+		case "desc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Desc())
+
+		}
+
+	}
+
+	return searchWechatArticle(indexName, query, sortList, from, size)
+}
+
+// searchEdbInfoDataV2 查询es中的数据
+func searchWechatArticle(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (total int64, list []*WechatArticleAndPlatform, err error) {
+	total, err = searchWechatArticleTotal(indexName, query)
+	if err != nil {
+		return
+	}
+
+	// 获取列表数据
+	list, err = searchWechatArticleList(indexName, query, sortList, from, size)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// searchEdbInfoDataTotal
+// @Description: 查询es中的数量
+// @author: Roc
+// @datetime 2024-12-23 11:19:04
+// @param indexName string
+// @param query elastic.Query
+// @return total int64
+// @return err error
+func searchWechatArticleTotal(indexName string, query elastic.Query) (total int64, err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoDataTotal Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	//根据条件数量统计
+	requestTotalHits := client.Count(indexName).Query(query)
+	total, err = requestTotalHits.Do(context.Background())
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// searchEdbInfoDataList
+// @Description: 查询es中的明细数据
+// @author: Roc
+// @datetime 2024-12-23 11:18:48
+// @param indexName string
+// @param query elastic.Query
+// @param sortList []*elastic.FieldSort
+// @param from int
+// @param size int
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func searchWechatArticleList(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (list []*WechatArticleAndPlatform, err error) {
+	list = make([]*WechatArticleAndPlatform, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoDataList Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+	// 高亮
+	highlight := elastic.NewHighlight()
+	highlight = highlight.Fields(elastic.NewHighlighterField("Title"))
+	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+
+	//request := client.Search(indexName).Highlight(highlight).From(from).Size(size) // sets the JSON request
+	request := client.Search(indexName).From(from).Size(size) // sets the JSON request
+
+	// 如果有指定排序,那么就按照排序来
+	if len(sortList) > 0 {
+		for _, v := range sortList {
+			request = request.SortBy(v)
+		}
+	}
+
+	searchMap := make(map[string]string)
+
+	searchResp, err := request.Query(query).Do(context.Background())
+	if err != nil {
+		return
+	}
+	//fmt.Println(searchResp)
+	//fmt.Println(searchResp.Status)
+	if searchResp.Status != 0 {
+		return
+	}
+	//total = searchResp.TotalHits()
+	if searchResp.Hits != nil {
+		for _, v := range searchResp.Hits.Hits {
+			if _, ok := searchMap[v.Id]; !ok {
+				itemJson, tmpErr := v.Source.MarshalJSON()
+				if tmpErr != nil {
+					err = tmpErr
+					fmt.Println("movieJson err:", err)
+					return
+				}
+				item := new(WechatArticleAndPlatform)
+				tmpErr = json.Unmarshal(itemJson, &item)
+				if tmpErr != nil {
+					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
+					err = tmpErr
+					return
+				}
+				if len(v.Highlight["Title"]) > 0 {
+					item.Title = v.Highlight["Title"][0]
+				}
+				list = append(list, item)
+				searchMap[v.Id] = v.Id
+			}
+		}
+	}
+
+	return
+}

+ 317 - 0
services/elastic/wechat_article_abstract.go

@@ -0,0 +1,317 @@
+package elastic
+
+import (
+	"context"
+	"encoding/json"
+	"eta/eta_api/models/rag"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/olivere/elastic/v7"
+	"time"
+)
+
+// 摘要索引
+var EsWechatArticleAbstractName = utils.EsWechatArticleAbstractName
+
+type WechatArticleAbstractItem struct {
+	WechatArticleAbstractId int       `gorm:"column:wechat_article_abstract_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"wechat_article_abstract_id"`
+	WechatArticleId         int       `gorm:"column:wechat_article_id;type:int(9) UNSIGNED;comment:关联的微信报告id;default:0;" description:"关联的微信报告id"`
+	WechatPlatformId        int       `gorm:"column:wechat_platform_id;type:int(9) UNSIGNED;comment:微信公众号id;default:0;" description:"微信公众号id"`
+	Abstract                string    `gorm:"column:abstract;type:longtext;comment:摘要内容;" description:"摘要内容"` //
+	Version                 int       `gorm:"column:version;type:int(10) UNSIGNED;comment:版本号;default:1;" description:"版本号"`
+	VectorKey               string    `gorm:"column:vector_key;type:varchar(255);comment:向量key标识;" description:"向量key标识"`
+	ModifyTime              time.Time `gorm:"column:modify_time;type:datetime;default:NULL;" description:"modify_time"`
+	CreateTime              time.Time `gorm:"column:create_time;type:datetime;default:NULL;" description:"create_time"`
+	Title                   string    `gorm:"column:title;type:varchar(255);comment:标题;" description:"标题"`
+	Link                    string    `gorm:"column:link;type:varchar(255);comment:链接;" description:"链接"`
+	TagIdList               []int     `description:"品种id列表"`
+}
+
+func (m *WechatArticleAbstractItem) ToView() rag.WechatArticleAbstractView {
+	var modifyTime, createTime string
+
+	if !m.CreateTime.IsZero() {
+		createTime = m.CreateTime.Format(utils.FormatDateTime)
+	}
+	if !m.ModifyTime.IsZero() {
+		modifyTime = m.ModifyTime.Format(utils.FormatDateTime)
+	}
+
+	tagId := 0
+	if len(m.TagIdList) > 0 {
+		tagId = m.TagIdList[0]
+	}
+	return rag.WechatArticleAbstractView{
+		WechatArticleAbstractId: m.WechatArticleAbstractId,
+		WechatArticleId:         m.WechatArticleId,
+		WechatPlatformId:        m.WechatPlatformId,
+		Abstract:                m.Abstract,
+		Version:                 m.Version,
+		VectorKey:               m.VectorKey,
+		ModifyTime:              modifyTime,
+		CreateTime:              createTime,
+		Title:                   m.Title,
+		Link:                    m.Link,
+		TagId:                   tagId,
+	}
+}
+
+func (m *WechatArticleAbstractItem) ToViewList(list []*WechatArticleAbstractItem) (wechatArticleViewList []rag.WechatArticleAbstractView) {
+	wechatArticleViewList = make([]rag.WechatArticleAbstractView, 0)
+
+	for _, v := range list {
+		wechatArticleViewList = append(wechatArticleViewList, v.ToView())
+	}
+	return
+}
+
+// WechatArticleEsAddOrEdit
+// @Description: 新增/编辑微信文章
+// @author: Roc
+// @datetime 2025-03-13 10:24:05
+// @param docId string
+// @param item WechatArticleAndPlatform
+// @return err error
+func WechatArticleAbstractEsAddOrEdit(docId string, item WechatArticleAbstractItem) (err error) {
+	if docId == "" {
+		return
+	}
+	if EsWechatArticleAbstractName == `` {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("WechatArticleEsAddOrEdit Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Index().Index(EsWechatArticleAbstractName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
+	if err != nil {
+		fmt.Println("新增失败:", err.Error())
+		return err
+	}
+	if resp.Status == 0 {
+		fmt.Println("新增成功", resp.Result)
+		err = nil
+	} else {
+		fmt.Println("WechatArticleEsAddOrEdit", resp.Status, resp.Result)
+	}
+
+	return
+}
+
+// WechatArticleEsDel
+// @Description: 删除微信文章
+// @author: Roc
+// @datetime 2025-03-13 10:23:55
+// @param docId string
+// @return err error
+func WechatArticleAbstractEsDel(docId string) (err error) {
+	if docId == "" {
+		return
+	}
+	if EsWechatArticleAbstractName == `` {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Delete().Index(EsWechatArticleAbstractName).Id(docId).Refresh(`true`).Do(context.Background())
+	if err != nil {
+		return
+	}
+	if resp.Status == 0 {
+		fmt.Println("删除成功")
+	} else {
+		fmt.Println("WechatArticleEsDel", resp.Status, resp.Result)
+	}
+
+	return
+}
+
+// WechatArticleAbstractEsSearch
+// @Description: 搜索
+// @author: Roc
+// @datetime 2025-03-13 19:54:54
+// @param keywordStr string
+// @param tagIdList []int
+// @param platformIdList []int
+// @param from int
+// @param size int
+// @param sortMap map[string]string
+// @return total int64
+// @return list []*WechatArticleAbstractItem
+// @return err error
+func WechatArticleAbstractEsSearch(keywordStr string, tagIdList, platformIdList []int, from, size int, sortMap map[string]string) (total int64, list []*WechatArticleAbstractItem, err error) {
+	indexName := EsWechatArticleAbstractName
+	list = make([]*WechatArticleAbstractItem, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	query := elastic.NewBoolQuery()
+
+	if len(tagIdList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range tagIdList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("TagIdList", termsList...))
+	}
+	if len(platformIdList) <= 0 {
+		return
+	}
+
+	{
+		termsList := make([]interface{}, 0)
+		for _, v := range platformIdList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("WechatPlatformId", termsList...))
+	}
+
+	// 名字匹配
+	if keywordStr != `` {
+		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, "Abstract"))
+	}
+
+	// 排序
+	sortList := make([]*elastic.FieldSort, 0)
+	// 如果没有关键字,那么就走指标id倒序
+
+	for orderKey, orderType := range sortMap {
+		switch orderType {
+		case "asc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Asc())
+		case "desc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Desc())
+
+		}
+
+	}
+
+	return searchWechatArticleAbstract(indexName, query, sortList, from, size)
+}
+
+// searchEdbInfoDataV2 查询es中的数据
+func searchWechatArticleAbstract(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (total int64, list []*WechatArticleAbstractItem, err error) {
+	total, err = searchWechatArticleAbstractTotal(indexName, query)
+	if err != nil {
+		return
+	}
+
+	// 获取列表数据
+	list, err = searchWechatArticleAbstractList(indexName, query, sortList, from, size)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// searchEdbInfoDataTotal
+// @Description: 查询es中的数量
+// @author: Roc
+// @datetime 2024-12-23 11:19:04
+// @param indexName string
+// @param query elastic.Query
+// @return total int64
+// @return err error
+func searchWechatArticleAbstractTotal(indexName string, query elastic.Query) (total int64, err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoDataTotal Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	//根据条件数量统计
+	requestTotalHits := client.Count(indexName).Query(query)
+	total, err = requestTotalHits.Do(context.Background())
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// searchEdbInfoDataList
+// @Description: 查询es中的明细数据
+// @author: Roc
+// @datetime 2024-12-23 11:18:48
+// @param indexName string
+// @param query elastic.Query
+// @param sortList []*elastic.FieldSort
+// @param from int
+// @param size int
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func searchWechatArticleAbstractList(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (list []*WechatArticleAbstractItem, err error) {
+	list = make([]*WechatArticleAbstractItem, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoDataList Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+	// 高亮
+	highlight := elastic.NewHighlight()
+	highlight = highlight.Fields(elastic.NewHighlighterField("Content"))
+	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+
+	//request := client.Search(indexName).Highlight(highlight).From(from).Size(size) // sets the JSON request
+	request := client.Search(indexName).From(from).Size(size) // sets the JSON request
+
+	// 如果有指定排序,那么就按照排序来
+	if len(sortList) > 0 {
+		for _, v := range sortList {
+			request = request.SortBy(v)
+		}
+	}
+
+	searchMap := make(map[string]string)
+
+	searchResp, err := request.Query(query).Do(context.Background())
+	if err != nil {
+		return
+	}
+	//fmt.Println(searchResp)
+	//fmt.Println(searchResp.Status)
+	if searchResp.Status != 0 {
+		return
+	}
+	//total = searchResp.TotalHits()
+	if searchResp.Hits != nil {
+		for _, v := range searchResp.Hits.Hits {
+			if _, ok := searchMap[v.Id]; !ok {
+				itemJson, tmpErr := v.Source.MarshalJSON()
+				if tmpErr != nil {
+					err = tmpErr
+					fmt.Println("movieJson err:", err)
+					return
+				}
+				item := new(WechatArticleAbstractItem)
+				tmpErr = json.Unmarshal(itemJson, &item)
+				if tmpErr != nil {
+					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
+					err = tmpErr
+					return
+				}
+				if len(v.Highlight["Content"]) > 0 {
+					item.Abstract = v.Highlight["Content"][0]
+				}
+				list = append(list, item)
+				searchMap[v.Id] = v.Id
+			}
+		}
+	}
+
+	return
+}

+ 65 - 2
services/llm/chat.go

@@ -11,6 +11,7 @@ import (
 	"mime/multipart"
 	"net/http"
 	"os"
+	"strings"
 )
 
 var (
@@ -63,9 +64,13 @@ func UploadTempDocs(filePath string) (resp UploadTempDocsResp, err error) {
 	return
 }
 
+type LlmBaseResp struct {
+	Code int    `json:"code"`
+	Msg  string `json:"msg"`
+}
+
 type UploadDocsResp struct {
-	Code int               `json:"code"`
-	Msg  string            `json:"msg"`
+	LlmBaseResp
 	Data UploadDocDataResp `json:"data"`
 }
 
@@ -121,6 +126,45 @@ func UploadDocsToKnowledge(filePath, knowledgeName string) (updateResp UploadDoc
 	return
 }
 
+// DelDocsToKnowledge
+// @Description: 从知识库中删除文件
+// @author: Roc
+// @datetime 2025-03-12 15:03:19
+// @param knowledgeName string
+// @param filePathList []string
+// @return resp LlmBaseResp
+// @return err error
+func DelDocsToKnowledge(knowledgeName string, filePathList []string) (resp LlmBaseResp, err error) {
+	postUrl := utils.LLM_SERVER + "/knowledge_base/delete_docs"
+
+	params := make(map[string]interface{})
+	params[`knowledge_base_name`] = knowledgeName
+	params[`file_names`] = filePathList
+	params[`delete_content`] = `true`        //
+	params[`not_refresh_vs_cache`] = `false` //
+	postData, err := json.Marshal(params)
+	if err != nil {
+		return
+	}
+
+	result, err := LlmHttpPost(postUrl, string(postData))
+	if err != nil {
+		return
+	}
+	utils.FileLog.Info("DelDocsToKnowledge:" + postUrl + ";" + string(postData) + ";result:" + string(result))
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
+	if resp.Code != 200 {
+		err = fmt.Errorf(`上传文件失败: %s`, resp.Msg)
+		return
+	}
+
+	return
+}
+
 // ChatResp 问答响应
 type ChatResp struct {
 	Answer string   `json:"answer"`
@@ -239,3 +283,22 @@ func PostFormData(url string, params map[string]string, files map[string]string)
 
 	return result, nil
 }
+
+func LlmHttpPost(url, postData string) ([]byte, error) {
+	body := io.NopCloser(strings.NewReader(postData))
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", url, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("authorization", utils.MD5(utils.APP_EDB_LIB_NAME_EN+utils.EDB_LIB_Md5_KEY))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	b, err := io.ReadAll(resp.Body)
+	utils.FileLog.Debug("HttpPost:" + string(b))
+	return b, err
+}

+ 1 - 1
services/llm/chat_service.go

@@ -129,7 +129,7 @@ func SaveChatRecordsToDB(chatId int) error {
 	var newRecords []*llm.UserChatRecord
 	for _, record := range list {
 		if record.Id == 0 {
-			sendTime, parseErr := time.Parse(utils.FormatDateTime, record.SendTime)
+			sendTime, parseErr := time.ParseInLocation(utils.FormatDateTime, record.SendTime, time.Local)
 			if parseErr != nil {
 				sendTime = time.Now()
 			}

+ 1 - 1
services/task.go

@@ -599,7 +599,7 @@ func HandleWechatArticleOp() {
 				fmt.Println("json unmarshal wrong!")
 				return
 			}
-			item, tmpErr := obj.GetByID(wechatArticleOp.WechatPlatformId)
+			item, tmpErr := obj.GetById(wechatArticleOp.WechatPlatformId)
 			if tmpErr != nil {
 				// 找不到就处理失败
 				return

+ 372 - 52
services/wechat_platform.go

@@ -5,6 +5,7 @@ import (
 	"eta/eta_api/cache"
 	"eta/eta_api/models"
 	"eta/eta_api/models/rag"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/services/llm"
 	"eta/eta_api/utils"
 	"eta/eta_api/utils/llm/eta_llm/eta_llm_http"
@@ -245,10 +246,17 @@ func GenerateArticleAbstract(item *rag.WechatArticle) {
 		}
 	}()
 
+	// 内容为空,那就不需要生成摘要
+	if item.TextContent == `` {
+		return
+	}
+
 	abstractObj := rag.WechatArticleAbstract{}
-	_, err = abstractObj.GetByWechatArticleId(item.WechatArticleId)
+	tmpAbstractItem, err := abstractObj.GetByWechatArticleId(item.WechatArticleId)
 	if err == nil {
 		// 摘要已经生成,不需要重复生成
+		AbstractToKnowledge(item, tmpAbstractItem, false)
+
 		return
 	}
 	if !utils.IsErrNoRow(err) {
@@ -292,53 +300,11 @@ func GenerateArticleAbstract(item *rag.WechatArticle) {
 	//tmpDocId := `2dde8afe62d24525a814e74e0a5e35e4` // 钢材
 	//tmpDocId := `7634cc1086c04b3687682220a2cf1a48` //
 
-	historyList := make([]eta_llm_http.HistoryContent, 0)
-
-	questionObj := rag.Question{}
-	questionList, err := questionObj.GetListByCondition(``, []interface{}{}, 0, 100)
-	if err != nil {
-		err = fmt.Errorf("获取问题列表失败,Err:" + err.Error())
-		return
-	}
-
-	addArticleChatRecordList := make([]*rag.WechatArticleChatRecord, 0)
-
-	var abstract string
 	//开始对话
-	for _, question := range questionList {
-		originalAnswer, tmpAnswer, tmpErr := getAnswerByContent(tmpDocId, question.QuestionContent, historyList)
-		if tmpErr != nil {
-			err = fmt.Errorf("LLM对话失败,Err:" + tmpErr.Error())
-			return
-		}
-		abstract = tmpAnswer
-
-		historyList = append(historyList, eta_llm_http.HistoryContent{
-			Role:    `user`,
-			Content: question.QuestionContent,
-		}, eta_llm_http.HistoryContent{
-			Role:    `assistant`,
-			Content: tmpAnswer,
-		})
-
-		// 待入库的数据
-		addArticleChatRecordList = append(addArticleChatRecordList, &rag.WechatArticleChatRecord{
-			WechatArticleChatRecordId: 0,
-			WechatArticleId:           item.WechatArticleId,
-			ChatUserType:              "user",
-			Content:                   question.QuestionContent,
-			SendTime:                  time.Now(),
-			CreatedTime:               time.Now(),
-			UpdateTime:                time.Now(),
-		}, &rag.WechatArticleChatRecord{
-			WechatArticleChatRecordId: 0,
-			WechatArticleId:           item.WechatArticleId,
-			ChatUserType:              "assistant",
-			Content:                   originalAnswer,
-			SendTime:                  time.Now(),
-			CreatedTime:               time.Now(),
-			UpdateTime:                time.Now(),
-		})
+	abstract, addArticleChatRecordList, tmpErr := getAnswerByContent(item.WechatArticleId, tmpDocId)
+	if tmpErr != nil {
+		err = fmt.Errorf("LLM对话失败,Err:" + tmpErr.Error())
+		return
 	}
 
 	// 添加问答记录
@@ -351,6 +317,16 @@ func GenerateArticleAbstract(item *rag.WechatArticle) {
 	}
 
 	if abstract != `` {
+		if abstract == `sorry` || strings.Index(abstract, `根据已知信息无法回答该问题`) == 0 {
+			item.AbstractStatus = 2
+			item.ModifyTime = time.Now()
+			err = item.Update([]string{"AbstractStatus", "ModifyTime"})
+			return
+		}
+		item.AbstractStatus = 1
+		item.ModifyTime = time.Now()
+		err = item.Update([]string{"AbstractStatus", "ModifyTime"})
+
 		abstractItem := &rag.WechatArticleAbstract{
 			WechatArticleAbstractId: 0,
 			WechatArticleId:         item.WechatArticleId,
@@ -365,12 +341,181 @@ func GenerateArticleAbstract(item *rag.WechatArticle) {
 			return
 		}
 
-		AbstractToKnowledge(item, abstractItem)
+		// 数据入ES库
+		go AddOrEditEsWechatArticleAbstract(abstractItem.WechatArticleAbstractId)
+
+		AbstractToKnowledge(item, abstractItem, false)
 	}
 }
 
-func getAnswerByContent(docId, question string, historyList []eta_llm_http.HistoryContent) (originalAnswer, answer string, err error) {
-	originalAnswer, result, err := llm.ChatByFile(docId, question, historyList)
+// ReGenerateArticleAbstract
+// @Description: 文章摘要重新生成
+// @author: Roc
+// @datetime 2025-03-10 16:17:53
+// @param item *rag.WechatArticle
+func ReGenerateArticleAbstract(item *rag.WechatArticle) {
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("文章转临时文件失败,err:%v", err)
+			fmt.Println("文章转临时文件失败,err:", err)
+		}
+	}()
+
+	abstractObj := rag.WechatArticleAbstract{}
+	abstractItem, err := abstractObj.GetByWechatArticleId(item.WechatArticleId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			// 直接生成
+			GenerateArticleAbstract(item)
+			return
+		}
+		// 异常了
+		return
+	}
+
+	// 生成临时文件
+	dateDir := time.Now().Format("20060102")
+	uploadDir := utils.STATIC_DIR + "ai/" + dateDir
+	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
+	if err != nil {
+		err = fmt.Errorf("存储目录创建失败,Err:" + err.Error())
+		return
+	}
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + `.md`
+	tmpFilePath := uploadDir + "/" + fileName
+	err = utils.SaveToFile(item.TextContent, tmpFilePath)
+	if err != nil {
+		err = fmt.Errorf("生成临时文件失败,Err:" + err.Error())
+		return
+	}
+	defer func() {
+		os.Remove(tmpFilePath)
+	}()
+
+	// 上传临时文件到LLM
+	tmpFileResp, err := llm.UploadTempDocs(tmpFilePath)
+	if err != nil {
+		err = fmt.Errorf("上传临时文件到LLM失败,Err:" + err.Error())
+		return
+	}
+
+	if tmpFileResp.Data.Id == `` {
+		err = fmt.Errorf("上传临时文件到LLM失败,Err:上传失败")
+		return
+	}
+	tmpDocId := tmpFileResp.Data.Id
+
+	//tmpDocId := `c4d2ee902808408c8b8ed398b33be103` // 钢材
+	//tmpDocId := `2dde8afe62d24525a814e74e0a5e35e4` // 钢材
+	//tmpDocId := `7634cc1086c04b3687682220a2cf1a48` //
+
+	//开始对话
+	abstract, addArticleChatRecordList, tmpErr := getAnswerByContent(item.WechatArticleId, tmpDocId)
+	if tmpErr != nil {
+		err = fmt.Errorf("LLM对话失败,Err:" + tmpErr.Error())
+		return
+	}
+
+	// 添加问答记录
+	if len(addArticleChatRecordList) > 0 {
+		recordObj := rag.WechatArticleChatRecord{}
+		err = recordObj.CreateInBatches(addArticleChatRecordList)
+		if err != nil {
+			return
+		}
+	}
+
+	if abstract != `` {
+		if abstract == `sorry` || strings.Index(abstract, `根据已知信息无法回答该问题`) == 0 {
+			item.AbstractStatus = 2
+			item.ModifyTime = time.Now()
+			err = item.Update([]string{"AbstractStatus", "ModifyTime"})
+			return
+		}
+		item.AbstractStatus = 1
+		item.ModifyTime = time.Now()
+		err = item.Update([]string{"AbstractStatus", "ModifyTime"})
+
+		abstractItem.Content = abstract
+		abstractItem.Version = abstractObj.Version + 1
+		abstractItem.ModifyTime = time.Now()
+		err = abstractItem.Update([]string{"content", "version", "modify_time"})
+		if err != nil {
+			return
+		}
+
+		AbstractToKnowledge(item, abstractItem, true)
+	}
+}
+
+// DelDoc
+// @Description: 删除摘要向量库
+// @author: Roc
+// @datetime 2025-03-12 16:55:05
+// @param wechatArticleAbstractList []*rag.WechatArticleAbstract
+// @return err error
+func DelDoc(wechatArticleAbstractList []*rag.WechatArticleAbstract) (err error) {
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("删除摘要向量库文件失败,err:%v", err)
+			fmt.Println("删除摘要向量库文件失败,err:", err)
+		}
+	}()
+
+	vectorKeyList := make([]string, 0)
+	wechatArticleAbstractIdList := make([]int, 0)
+
+	for _, v := range wechatArticleAbstractList {
+		if v.VectorKey == `` {
+			continue
+		}
+		vectorKeyList = append(vectorKeyList, v.VectorKey)
+		wechatArticleAbstractIdList = append(wechatArticleAbstractIdList, v.WechatArticleAbstractId)
+	}
+
+	// 没有就不删除
+	if len(vectorKeyList) <= 0 {
+		return
+	}
+
+	_, err = llm.DelDocsToKnowledge(models.BusinessConfMap[models.KnowledgeBaseName], vectorKeyList)
+	if err != nil {
+		err = fmt.Errorf("删除LLM摘要向量库文件失败,Err:" + err.Error())
+		return
+	}
+	//fmt.Println(resp)
+	obj := rag.WechatArticleAbstract{}
+	err = obj.DelVectorKey(wechatArticleAbstractIdList)
+
+	return
+}
+
+func getAnswerByContent(wechatArticleId int, docId string) (answer string, addArticleChatRecordList []*rag.WechatArticleChatRecord, err error) {
+	historyList := make([]eta_llm_http.HistoryContent, 0)
+	addArticleChatRecordList = make([]*rag.WechatArticleChatRecord, 0)
+
+	questionObj := rag.Question{}
+	questionList, err := questionObj.GetListByCondition(``, []interface{}{}, 0, 100)
+	if err != nil {
+		err = fmt.Errorf("获取问题列表失败,Err:" + err.Error())
+		return
+	}
+
+	// 没问题就不生成了
+	if len(questionList) <= 0 {
+		return
+	}
+
+	//你现在是一名资深的期货行业分析师,请基于以下的问题进行汇总总结,如果不能正常总结出来,那么就只需要回复我:sorry
+	questionStrList := []string{`你现在是一名资深的期货行业分析师,请基于以下的问题进行汇总总结,如果不能正常总结出来,那么就只需要回复我:sorry。以下是问题:`}
+	for _, v := range questionList {
+		questionStrList = append(questionStrList, v.QuestionContent)
+	}
+	questionStr := strings.Join(questionStrList, "\n")
+
+	originalAnswer, result, err := llm.ChatByFile(docId, questionStr, historyList)
 	fmt.Println(result)
 	if err != nil {
 		err = fmt.Errorf("LLM对话失败,Err:" + err.Error())
@@ -387,6 +532,25 @@ func getAnswerByContent(docId, question string, historyList []eta_llm_http.Histo
 
 	answer = strings.TrimSpace(answer)
 
+	// 待入库的数据
+	addArticleChatRecordList = append(addArticleChatRecordList, &rag.WechatArticleChatRecord{
+		WechatArticleChatRecordId: 0,
+		WechatArticleId:           wechatArticleId,
+		ChatUserType:              "user",
+		Content:                   questionStr,
+		SendTime:                  time.Now(),
+		CreatedTime:               time.Now(),
+		UpdateTime:                time.Now(),
+	}, &rag.WechatArticleChatRecord{
+		WechatArticleChatRecordId: 0,
+		WechatArticleId:           wechatArticleId,
+		ChatUserType:              "assistant",
+		Content:                   originalAnswer,
+		SendTime:                  time.Now(),
+		CreatedTime:               time.Now(),
+		UpdateTime:                time.Now(),
+	})
+
 	return
 }
 
@@ -453,12 +617,12 @@ func ArticleToKnowledge(item *rag.WechatArticle) {
 // @datetime 2025-03-10 16:14:59
 // @param wechatArticleItem *rag.WechatArticle
 // @param item *rag.WechatArticleAbstract
-func AbstractToKnowledge(wechatArticleItem *rag.WechatArticle, item *rag.WechatArticleAbstract) {
+func AbstractToKnowledge(wechatArticleItem *rag.WechatArticle, item *rag.WechatArticleAbstract, isReUpload bool) {
 	if item.Content == `` {
 		return
 	}
 	// 已经生成了,那就不处理了
-	if item.VectorKey != `` {
+	if item.VectorKey != `` && !isReUpload {
 		return
 	}
 	var err error
@@ -546,6 +710,9 @@ func replaceWechatArticleCoverPic(item *rag.WechatArticle) {
 			utils.FileLog.Error("替换公众号头像失败,err:%v", err)
 			fmt.Println("替换公众号头像失败,err:", err)
 		}
+
+		// 数据入ES库
+		AddOrEditEsWechatArticle(item.WechatArticleId)
 	}()
 	if item.CoverUrl == `` {
 		return
@@ -674,3 +841,156 @@ func handleNode(n *html2.Node) {
 		handleNode(c)
 	}
 }
+
+// AddOrEditEsWechatPlatformId
+// @Description: 批量处理某个公众号下的文章到ES
+// @author: Roc
+// @datetime 2025-03-13 11:01:28
+// @param articleId int
+func AddOrEditEsWechatPlatformId(wechatPlatformId int) {
+	if utils.EsWechatArticleName == `` {
+		return
+	}
+	obj := rag.WechatArticle{}
+	list, _ := obj.GetListByCondition(` wechat_article_id `, ` AND wechat_platform_id = ? `, []interface{}{wechatPlatformId}, 0, 1000000)
+	for _, item := range list {
+		AddOrEditEsWechatArticle(item.WechatArticleId)
+	}
+}
+
+// AddOrEditEsWechatArticle
+// @Description: 新增/编辑微信文章入ES
+// @author: Roc
+// @datetime 2025-03-13 11:01:28
+// @param articleId int
+func AddOrEditEsWechatArticle(articleId int) {
+	if utils.EsWechatArticleName == `` {
+		return
+	}
+
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("添加公众号微信信息到ES失败,err:%v", err)
+			fmt.Println("添加公众号微信信息到ES失败,err:", err)
+		}
+	}()
+	obj := rag.WechatArticle{}
+	articleInfo, err := obj.GetById(articleId)
+	if err != nil {
+		err = fmt.Errorf("获取公众号文章信息失败,Err:" + err.Error())
+		return
+	}
+	platformObj := rag.WechatPlatform{}
+	platformInfo, err := platformObj.GetById(articleInfo.WechatPlatformId)
+	if err != nil {
+		err = fmt.Errorf("获取公众号平台信息失败,Err:" + err.Error())
+		return
+	}
+
+	esItem := elastic.WechatArticleAndPlatform{
+		WechatArticleId:  articleInfo.WechatArticleId,
+		WechatPlatformId: articleInfo.WechatPlatformId,
+		FakeId:           articleInfo.FakeId,
+		Title:            articleInfo.Title,
+		Link:             articleInfo.Link,
+		CoverUrl:         articleInfo.CoverUrl,
+		Description:      articleInfo.Description,
+		//Content:          articleInfo.Content,
+		//TextContent: articleInfo.TextContent,
+		//AbstractStatus:          articleInfo.AbstractStatus,
+		Country:           articleInfo.Country,
+		Province:          articleInfo.Province,
+		City:              articleInfo.City,
+		ArticleCreateTime: articleInfo.ArticleCreateTime,
+		IsDeleted:         articleInfo.IsDeleted,
+		ModifyTime:        articleInfo.ModifyTime,
+		CreateTime:        articleInfo.CreateTime,
+		Nickname:          platformInfo.Nickname,
+		Alias:             platformInfo.Alias,
+		RoundHeadImg:      platformInfo.RoundHeadImg,
+	}
+
+	err = elastic.WechatArticleEsAddOrEdit(strconv.Itoa(articleInfo.WechatArticleId), esItem)
+}
+
+// AddOrEditEsWechatArticleAbstract
+// @Description: 新增/编辑微信文章摘要入ES
+// @author: Roc
+// @datetime 2025-03-13 14:13:47
+// @param articleAbstractId int
+func AddOrEditEsWechatArticleAbstract(articleAbstractId int) {
+	if utils.EsWechatArticleAbstractName == `` {
+		return
+	}
+
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("添加公众号微信信息到ES失败,err:%v", err)
+			fmt.Println("添加公众号微信信息到ES失败,err:", err)
+		}
+	}()
+	obj := rag.WechatArticleAbstract{}
+	abstractInfo, err := obj.GetById(articleAbstractId)
+	if err != nil {
+		err = fmt.Errorf("获取公众号文章信息失败,Err:" + err.Error())
+		return
+	}
+	articleObj := rag.WechatArticle{}
+	articleInfo, err := articleObj.GetById(abstractInfo.WechatArticleId)
+	if err != nil {
+		err = fmt.Errorf("获取公众号文章信息失败,Err:" + err.Error())
+		return
+	}
+
+	// 公众号平台关联的标签品种
+	tagObj := rag.WechatPlatformTagMapping{}
+	tagMappingList, err := tagObj.GetListByCondition(` AND wechat_platform_id = ? `, []interface{}{articleInfo.WechatPlatformId}, 0, 10000)
+	if err != nil {
+		err = fmt.Errorf("获取公众号平台关联的品种信息失败,Err:" + err.Error())
+		return
+	}
+
+	tagIdList := make([]int, 0)
+	for _, v := range tagMappingList {
+		tagIdList = append(tagIdList, v.TagId)
+	}
+
+	esItem := elastic.WechatArticleAbstractItem{
+		WechatArticleAbstractId: abstractInfo.WechatArticleAbstractId,
+		WechatArticleId:         abstractInfo.WechatArticleId,
+		WechatPlatformId:        articleInfo.WechatPlatformId,
+		Abstract:                abstractInfo.Content,
+		Version:                 abstractInfo.Version,
+		VectorKey:               abstractInfo.VectorKey,
+		ModifyTime:              articleInfo.ModifyTime,
+		CreateTime:              articleInfo.CreateTime,
+		Title:                   articleInfo.Title,
+		Link:                    articleInfo.Link,
+		TagIdList:               tagIdList,
+	}
+
+	err = elastic.WechatArticleAbstractEsAddOrEdit(strconv.Itoa(articleAbstractId), esItem)
+}
+
+// AddOrEditEsWechatArticleAbstract
+// @Description: 新增/编辑微信文章摘要入ES
+// @author: Roc
+// @datetime 2025-03-13 14:13:47
+// @param articleAbstractId int
+func DelEsWechatArticleAbstract(articleAbstractId int) {
+	if utils.EsWechatArticleAbstractName == `` {
+		return
+	}
+
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("添加公众号微信信息到ES失败,err:%v", err)
+			fmt.Println("添加公众号微信信息到ES失败,err:", err)
+		}
+	}()
+
+	err = elastic.WechatArticleAbstractEsDel(strconv.Itoa(articleAbstractId))
+}

+ 2 - 0
utils/config.go

@@ -146,6 +146,8 @@ var (
 	SmartReportIndexName           string //智能研报ES索引
 	EsExcelIndexName               string // 表格ES索引名称
 	EsDataSourceIndexName          string // 数据源ES索引名称
+	EsWechatArticleName            string // ES索引名称-微信文章
+	EsWechatArticleAbstractName    string // ES索引名称-微信文章摘要
 )
 
 var (