Explorar o código

Merge branch 'debug' of http://8.136.199.33:3000/eta_server/eta_api into debug

kobe6258 hai 1 mes
pai
achega
865dadb42b

+ 1 - 1
controllers/data_manage/edb_info.go

@@ -2417,7 +2417,7 @@ func (this *EdbInfoController) EdbInfoAdd() {
 
 	// 兼容钢联与上海钢联数据
 	if utils.InArrayByInt([]int{utils.DATA_SOURCE_GL, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, source) {
-		// 如果是钢联的话,那么就先判断是不是存在钢联化工
+		// 如果是钢联的话,那么就先判断是不是存在上海钢联
 		tmpInfo, err := data_manage.GetBaseFromMysteelChemicalIndexByCode(req.EdbCode)
 		if err != nil {
 			if !utils.IsErrNoRow(err) {

+ 1 - 1
controllers/data_manage/edb_info_refresh.go

@@ -751,7 +751,7 @@ func (c *EdbInfoController) SaveRelationEdbRefreshStatus() {
 	}
 
 	var edbList []*data_manage.EdbInfo
-	// 如果是钢联化工,那么需要过滤供应商暂停的指标
+	// 如果是上海钢联,那么需要过滤供应商暂停的指标
 	if req.Source == utils.DATA_SOURCE_MYSTEEL_CHEMICAL {
 		// 获取未被供应商暂停的指标
 		tmpEdbCodeList := make([]string, 0)

+ 1 - 1
controllers/data_manage/mysteel_chemical_data.go

@@ -761,7 +761,7 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 				return
 			}
 			if k == 0 {
-				windRow.AddCell().SetValue("钢联")
+				windRow.AddCell().SetValue("上海钢联")
 				secNameRow.AddCell().SetValue("指标名称")
 				indexCodeRow.AddCell().SetValue("指标ID")
 				frequencyRow.AddCell().SetValue("频率")

+ 44 - 13
controllers/data_manage/sci_hq_data.go

@@ -264,7 +264,7 @@ func (this *SciHqDataController) MoveClassify() {
 		return
 	}
 
-	err, errMsg := data.MoveSciHqClassify(req.ClassifyId, req.ParentId, req.PrevClassifyId, req.NextClassifyId)
+	err, errMsg := data.MoveSciHqClassify(req.ClassifyId, req.ParentClassifyId, req.PrevClassifyId, req.NextClassifyId)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -333,12 +333,12 @@ func (this *SciHqDataController) BatchIndexList() {
 	}
 	if req.IsSelectAll {
 		if len(req.SelectedId) > 0 {
-			condition += ` AND base_from_sci_hq_index_id NOT IN (` + utils.GetOrmInReplace(len(req.SelectedId)) + `)`
+			condition += ` AND base_from_sci_hq_index_id NOT IN (?)`
 			pars = append(pars, req.SelectedId)
 		}
 	} else {
 		if len(req.SelectedId) > 0 {
-			condition += ` AND base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(req.SelectedId)) + `)`
+			condition += ` AND base_from_sci_hq_index_id IN (?)`
 			pars = append(pars, req.SelectedId)
 		}
 	}
@@ -353,11 +353,14 @@ func (this *SciHqDataController) BatchIndexList() {
 			br.ErrMsg = "获取分类失败,Err:" + err.Error()
 			return
 		}
-		if len(childClassify) > 0 {
-			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
-			for _, child := range childClassify {
-				pars = append(pars, child.ClassifyId)
-			}
+		var childIds []int
+		for _, v := range childClassify {
+			childIds = append(childIds, v.ClassifyId)
+		}
+		if len(childIds) > 0 {
+			childIds = append(childIds, req.ClassifyId)
+			condition += `AND classify_id IN (?)`
+			pars = append(pars, childIds)
 		} else {
 			condition += ` AND classify_id=?`
 			pars = append(pars, req.ClassifyId)
@@ -762,6 +765,19 @@ func (this *SciHqDataController) AddEdbInfo() {
 		return
 	}
 
+	// 刷新指标数据
+	refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
+		return
+	}
+	if refreshRes != nil && refreshRes.Ret != 200 {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
+		return
+	}
+
 	// 试用平台更新用户累计新增指标数
 	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
 	if e != nil {
@@ -1096,6 +1112,19 @@ func (this *SciHqDataController) BatchAdd() {
 			continue
 		}
 
+		// 刷新指标数据
+		refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
+			return
+		}
+		if refreshRes != nil && refreshRes.Ret != 200 {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
+			return
+		}
+
 		// 试用平台更新用户累计新增指标数
 		if utils.BusinessCode == utils.BusinessCodeSandbox {
 			go func() {
@@ -1422,11 +1451,13 @@ func (this *SciHqDataController) ExportSciHqList() {
 			br.ErrMsg = "获取分类失败,Err:" + err.Error()
 			return
 		}
-		if len(childClassify) > 0 {
-			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
-			for _, child := range childClassify {
-				pars = append(pars, child.ClassifyId)
-			}
+		var childIds []int
+		for _, v := range childClassify {
+			childIds = append(childIds, v.ClassifyId)
+		}
+		if len(childIds) > 0 {
+			condition += `AND classify_id IN (?)`
+			pars = append(pars, childIds)
 		} else {
 			condition += ` AND classify_id=?`
 			pars = append(pars, classifyId)

+ 194 - 19
controllers/llm/question.go

@@ -7,6 +7,8 @@ import (
 	"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"
@@ -54,23 +56,131 @@ func (c *QuestionController) List() {
 	}
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
-	var condition string
-	var pars []interface{}
+	var total int
+	viewList := make([]rag.QuestionView, 0)
 
-	if keyWord != "" {
-		condition += fmt.Sprintf(` AND %s like ?`, rag.QuestionColumns.QuestionContent)
-		pars = append(pars, `%`+keyWord+`%`)
+	if keyWord == `` {
+		var condition string
+		var pars []interface{}
+
+		if keyWord != "" {
+			condition += fmt.Sprintf(` AND %s like ?`, rag.QuestionColumns.QuestionContent)
+			pars = append(pars, `%`+keyWord+`%`)
+		}
+		obj := new(rag.Question)
+		tmpTotal, list, err := obj.GetPageListByCondition(condition, pars, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+
+		if list != nil && len(list) > 0 {
+			viewList = list[0].ListToViewList(list)
+		}
+	} else {
+		sortMap := map[string]string{
+			//"ArticleCreateTime": "desc",
+			//"WechatArticleId":   "desc",
+		}
+		tmpTotal, list, err := elastic.RagQuestionEsSearch(keyWord, 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)
+		}
 	}
 
-	obj := new(rag.Question)
-	total, list, err := obj.GetPageListByCondition(condition, pars, startSize, pageSize)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取失败,Err:" + err.Error()
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := response.QuestionListListResp{
+		List:   viewList,
+		Paging: page,
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// TitleList
+// @Title 标题列表
+// @Description 标题列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Success 200 {object} []*rag.QuestionListListResp
+// @router /question/title/list [get]
+func (c *QuestionController) TitleList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
 		return
 	}
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	keyWord := c.GetString("KeyWord")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
 
-	viewList := obj.ListToViewList(list)
+	var total int
+	viewList := make([]rag.QuestionView, 0)
+
+	if keyWord == `` {
+		var condition string
+		var pars []interface{}
+
+		if keyWord != "" {
+			condition += fmt.Sprintf(` AND %s like ?`, rag.QuestionColumns.QuestionContent)
+			pars = append(pars, `%`+keyWord+`%`)
+		}
+		obj := new(rag.Question)
+		tmpTotal, list, err := obj.GetTitlePageListByCondition(condition, pars, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+
+		if list != nil && len(list) > 0 {
+			viewList = list[0].ListToViewList(list)
+		}
+	} else {
+		sortMap := map[string]string{
+			//"ArticleCreateTime": "desc",
+			//"WechatArticleId":   "desc",
+		}
+		tmpTotal, list, err := elastic.RagQuestionEsSearch(keyWord, 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.QuestionListListResp{
@@ -84,6 +194,47 @@ func (c *QuestionController) List() {
 	br.Data = resp
 }
 
+// Detail
+// @Title 列表
+// @Description 列表
+// @Param   QuestionId   query   int  true       "问题id"
+// @Success 200 {object} []*rag.QuestionListListResp
+// @router /question/detail [get]
+func (c *QuestionController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	questionId, _ := c.GetInt("QuestionId")
+	if questionId <= 0 {
+		br.Msg = "问题id不能为空"
+		br.ErrMsg = "问题id不能为空"
+		return
+	}
+
+	obj := new(rag.Question)
+	questionItem, err := obj.GetByID(questionId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Data = questionItem.ToView()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
 // Add
 // @Title 新增问题
 // @Description 新增问题
@@ -109,16 +260,18 @@ func (c *QuestionController) Add() {
 		br.IsSendEmail = false
 		return
 	}
-	obj := rag.Question{}
-	_, err = obj.GetByCondition(` AND question_content = ? `, []interface{}{req.Content})
-	if err == nil {
-		br.Msg = "问题已入库,请不要重复添加"
-		br.IsSendEmail = false
-		return
-	}
+	//obj := rag.Question{}
+	//_, err = obj.GetByCondition(` AND question_content = ? `, []interface{}{req.Content})
+	//if err == nil {
+	//	br.Msg = "问题已入库,请不要重复添加"
+	//	br.IsSendEmail = false
+	//	return
+	//}
 
+	title := utils.GetFirstNChars(req.Content, 20)
 	item := &rag.Question{
 		QuestionId:      0,
+		QuestionTitle:   title,
 		QuestionContent: req.Content,
 		Sort:            0,
 		ModifyTime:      time.Now(),
@@ -131,6 +284,9 @@ func (c *QuestionController) Add() {
 		return
 	}
 
+	// 新增/编辑ES数据
+	go services.AddOrEditEsRagQuestion(item.QuestionId)
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = `添加成功`
@@ -178,9 +334,10 @@ func (c *QuestionController) Edit() {
 		}
 		return
 	}
+	item.QuestionTitle = utils.GetFirstNChars(req.Content, 20)
 	item.QuestionContent = req.Content
 	item.ModifyTime = time.Now()
-	err = item.Update([]string{"question_content", "modify_time"})
+	err = item.Update([]string{"question_title", "question_content", "modify_time"})
 	if err != nil {
 		br.Msg = "修改失败"
 		br.ErrMsg = "修改失败,Err:" + err.Error()
@@ -235,7 +392,25 @@ func (c *QuestionController) Del() {
 		return
 	}
 
+	// 删除ES数据
+	go services.DelEsRagQuestion(item.QuestionId)
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = `删除成功`
 }
+
+//func init() {
+//	// 问题加到es
+//	{
+//		obj := rag.Question{}
+//		list, _ := obj.GetListByCondition(``, ` `, []interface{}{}, 0, 10000)
+//		total := len(list)
+//		for k, item := range list {
+//			fmt.Println(k, "/", total)
+//			services.AddOrEditEsRagQuestion(item.QuestionId)
+//		}
+//
+//		fmt.Println("结束了")
+//	}
+//}

+ 11 - 11
controllers/report_v2.go

@@ -960,17 +960,17 @@ func (this *ReportController) AuthorizedListReport() {
 	var list []*models.ReportList
 
 	// 没有输入信息,那就不展示
-	if keyword == `` && classifyIdFirst <= 0 {
-		page := paging.GetPaging(currentIndex, pageSize, 0)
-		resp := new(models.ReportListResp)
-		resp.Paging = page
-		resp.List = list
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		return
-	}
+	// if keyword == `` && classifyIdFirst <= 0 {
+	// 	page := paging.GetPaging(currentIndex, pageSize, 0)
+	// 	resp := new(models.ReportListResp)
+	// 	resp.Paging = page
+	// 	resp.List = list
+	// 	br.Ret = 200
+	// 	br.Success = true
+	// 	br.Msg = "获取成功"
+	// 	br.Data = resp
+	// 	return
+	// }
 
 	// 当前用户有权限的报告id列表
 	grantReportIdList := make([]int, 0)

+ 4 - 1
controllers/sys_admin.go

@@ -1325,9 +1325,12 @@ func (this *SysAdminController) ResetPass() {
 	_ = utils.Rc.Delete(utils.CACHE_KEY_ADMIN_ID)
 	abnormalKey := fmt.Sprint(utils.CACHE_ABNORMAL_LOGIN, adminInfo.AdminName)
 	errPassKey := fmt.Sprint(utils.CACHE_LOGIN_ERR_PASS, adminInfo.AdminName)
+	mobileAbnormalKey := fmt.Sprint(utils.MOBILE_CACHE_ABNORMAL_LOGIN, adminInfo.AdminName)
+	mobileErrPassKey := fmt.Sprint(utils.MOBILE_CACHE_LOGIN_ERR_PASS, adminInfo.AdminName)
 	_ = utils.Rc.Delete(abnormalKey)
 	_ = utils.Rc.Delete(errPassKey)
-
+	_ = utils.Rc.Delete(mobileAbnormalKey)
+	_ = utils.Rc.Delete(mobileErrPassKey)
 	br.Ret = 200
 	br.Success = true
 	br.IsAddLog = true

+ 16 - 3
controllers/sys_role.go

@@ -65,7 +65,7 @@ func (this *SysRoleController) Add() {
 	}
 
 	// 同步角色缓存
-	if utils.BusinessCode == utils.BusinessCodeRelease {
+	if utils.BusinessCode == utils.BusinessCodeRelease || utils.BusinessCode == utils.BusinessCodeDebug {
 		var syncData system.SyncRoleData
 		syncData.Source = utils.SOURCE_ETA_FLAG
 		syncData.RoleId = int(roleId)
@@ -122,6 +122,9 @@ func (this *SysRoleController) Edit() {
 		br.Msg = "admin用户不可编辑"
 		return
 	}
+
+	oldRoleCodeType := item.RoleTypeCode
+	oldRoleName := item.RoleName
 	exists, e := system.GetSysRoleByName(req.RoleName)
 	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
@@ -140,8 +143,18 @@ func (this *SysRoleController) Edit() {
 		return
 	}
 
+	if oldRoleName != req.RoleName || oldRoleCodeType != roleTypeCode {
+		// 查询所有和角色相关的管理员的信息,并更新成最新的角色
+		err = system.UpdateAdminRoleInfoByRoleId(req.RoleId, req.RoleName, roleTypeCode)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "更新管理员角色信息失败, Err: " + err.Error()
+			return
+		}
+	}
+
 	// 同步角色缓存
-	if utils.BusinessCode == utils.BusinessCodeRelease {
+	if utils.BusinessCode == utils.BusinessCodeRelease || utils.BusinessCode == utils.BusinessCodeDebug {
 		var syncData system.SyncRoleData
 		syncData.Source = utils.SOURCE_ETA_FLAG
 		syncData.RoleId = item.RoleId
@@ -201,7 +214,7 @@ func (this *SysRoleController) Delete() {
 	}
 
 	// 同步角色缓存
-	if utils.BusinessCode == utils.BusinessCodeRelease {
+	if utils.BusinessCode == utils.BusinessCodeRelease || utils.BusinessCode == utils.BusinessCodeDebug {
 		var syncData system.SyncRoleData
 		syncData.Source = utils.SOURCE_ETA_FLAG
 		syncData.RoleId = role.RoleId

+ 2 - 0
controllers/user_login.go

@@ -881,6 +881,8 @@ func (this *UserLoginController) ForgetResetPass() {
 	abnormalKey := fmt.Sprint(utils.CACHE_ABNORMAL_LOGIN, req.UserName)
 	_ = utils.Rc.Delete(abnormalKey)
 	_ = utils.Rc.Delete(successKey)
+	mobileAbnormalKey := fmt.Sprint(utils.MOBILE_CACHE_ABNORMAL_LOGIN, req.UserName)
+	_ = utils.Rc.Delete(mobileAbnormalKey)
 
 	// 同步ETA用户缓存
 	if utils.BusinessCode == utils.BusinessCodeRelease || utils.BusinessCode == utils.BusinessCodeSandbox {

+ 13 - 2
models/business_conf.go

@@ -64,8 +64,10 @@ const (
 	KnowledgeArticleName                     = "KnowledgeArticleName"             // 原文库
 	BusinessConfEsWechatArticle              = "EsIndexNameWechatArticle"         // ES索引名称-微信文章
 	BusinessConfEsWechatArticleAbstract      = "EsIndexNameWechatArticleAbstract" // ES索引名称-微信文章摘要
-	BusinessConfIsOpenChartExpired     = "IsOpenChartExpired"     // 是否开启图表有效期鉴权/报告禁止复制
-	BusinessConfReportChartExpiredTime = "ReportChartExpiredTime" // 图表有效期鉴权时间,单位:分钟
+	BusinessConfEsRagQuestion                = "EsIndexNameRagQuestion"           // ES索引名称-知识库问题
+	BusinessConfIsOpenChartExpired           = "IsOpenChartExpired"               // 是否开启图表有效期鉴权/报告禁止复制
+	BusinessConfReportChartExpiredTime       = "ReportChartExpiredTime"           // 图表有效期鉴权时间,单位:分钟
+	BusinessConfOssUrlReplace                = "OssUrlReplace"                    // OSS地址替换-兼容内网客户用
 )
 
 const (
@@ -277,6 +279,9 @@ func InitBusinessConf() {
 	if BusinessConfMap[BusinessConfEsWechatArticleAbstract] != "" {
 		utils.EsWechatArticleAbstractName = BusinessConfMap[BusinessConfEsWechatArticleAbstract]
 	}
+	if BusinessConfMap[BusinessConfEsRagQuestion] != "" {
+		utils.EsRagQuestionName = BusinessConfMap[BusinessConfEsRagQuestion]
+	}
 	confStr := BusinessConfMap[LLMInitConfig]
 	if confStr != "" {
 		var config LLMConfig
@@ -301,3 +306,9 @@ func InitBusinessConf() {
 	}
 
 }
+
+type OssUrlReplace struct {
+	IsReplace    bool   `description:"是否替换"`
+	OssUrlOrigin string `description:"被替换的资源地址"`
+	OssUrlNew    string `description:"新的资源地址"`
+}

+ 27 - 0
models/data_manage/base_from_sci_hq_classify.go

@@ -3,6 +3,7 @@ package data_manage
 import (
 	"eta/eta_api/global"
 	"eta/eta_api/utils"
+	"fmt"
 	"time"
 )
 
@@ -218,3 +219,29 @@ func MoveDownSciHqIndexClassifyBySort(parentId, prevSort, currentSort int) (err
 	err = o.Exec(sql, parentId, prevSort, currentSort).Error
 	return
 }
+
+// UpdateSciHqClassifySortByParentId 根据父类id更新排序
+func UpdateSciHqClassifySortByParentId(parentId, classifyId, nowSort int, updateSort string) (err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := ` update base_from_sci_hq_classify set sort = ` + updateSort + ` WHERE parent_id = ? AND sort > ? `
+	if classifyId > 0 {
+		sql += ` or ( classify_id > ` + fmt.Sprint(classifyId) + ` and sort = ` + fmt.Sprint(nowSort) + `)`
+	}
+	err = o.Exec(sql, parentId, nowSort).Error
+	return
+}
+
+// GetFirstSciHqClassifyByParentId 获取当前父级分类下,且排序数相同 的排序第一条的数据
+func GetFirstSciHqClassifyByParentId(parentId int) (item *BaseFromSciHqClassify, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := ` SELECT * FROM base_from_sci_hq_classify WHERE parent_id = ? ORDER BY sort ASC,classify_id ASC LIMIT 1`
+	err = o.Raw(sql, parentId).First(&item).Error
+	return
+}
+
+func GetSciHqClassifySortMaxByParentId(parentId int) (sort int, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := `SELECT COALESCE(Max(sort), 0) AS sort FROM base_from_sci_hq_classify WHERE parent_id = ?`
+	err = o.Raw(sql, parentId).Scan(&sort).Error
+	return
+}

+ 10 - 4
models/data_manage/base_from_sci_hq_index.go

@@ -25,6 +25,12 @@ type BaseFromSciHqIndex struct {
 	ModifyTime           time.Time
 }
 
+func (m *BaseFromSciHqIndex) AfterFind(db *gorm.DB) (err error) {
+	m.StartDate = utils.GormDateStrToDateStr(m.StartDate)
+	m.EndDate = utils.GormDateStrToDateStr(m.EndDate)
+	return
+}
+
 type BaseFromSciHqIndexView struct {
 	BaseFromSciHqIndexId int     `orm:"pk" gorm:"primaryKey"`
 	EdbInfoId            int     `description:"指标库id"`
@@ -44,10 +50,10 @@ type BaseFromSciHqIndexView struct {
 }
 
 func (b *BaseFromSciHqIndexView) AfterFind(db *gorm.DB) (err error) {
-			b.LatestDate = utils.GormDateStrToDateStr(b.LatestDate)
-			b.StartDate = utils.GormDateStrToDateStr(b.StartDate)
-			b.EndDate = utils.GormDateStrToDateStr(b.EndDate)
-			b.ModifyTime = utils.GormDateStrToDateTimeStr(b.ModifyTime)
+	b.LatestDate = utils.GormDateStrToDateStr(b.LatestDate)
+	b.StartDate = utils.GormDateStrToDateStr(b.StartDate)
+	b.EndDate = utils.GormDateStrToDateStr(b.EndDate)
+	b.ModifyTime = utils.GormDateStrToDateTimeStr(b.ModifyTime)
 	return
 }
 func (b *BaseFromSciHqIndex) Update(cols []string) (err error) {

+ 1 - 1
models/data_manage/edb_info.go

@@ -284,7 +284,7 @@ type BatchAddCheckReq struct {
 	IndexCodes []string `form:"IndexCodes" description:"全选为false时, 该数组为选中; 全选为true时, 该数组为不选的指标"`
 }
 
-// MysteelChemicalDataBatchAddCheckReq 钢联化工指标批量添加校验
+// MysteelChemicalDataBatchAddCheckReq 上海钢联指标批量添加校验
 type MysteelChemicalDataBatchAddCheckReq struct {
 	// MysteelChemicalDataListReq
 	IndexCodes []string `form:"IndexCodes" description:"全选为false时, 该数组为选中; 全选为true时, 该数组为不选的指标"`

+ 1 - 1
models/data_manage/mysteel_chemical_index.go

@@ -191,7 +191,7 @@ func GetMysteelChemicalFrequency(condition string, pars []interface{}) (items []
 // MysteelChemicalList 上海钢联指标列表
 type MysteelChemicalList struct {
 	Id                                int                    `gorm:"column:base_from_mysteel_chemical_index_id"`
-	BaseFromMysteelChemicalClassifyId int                    `gorm:"column:base_from_mysteel_chemical_classify_id" description:"钢联化工指标分类id"`
+	BaseFromMysteelChemicalClassifyId int                    `gorm:"column:base_from_mysteel_chemical_classify_id" description:"上海钢联指标分类id"`
 	ParentClassifyId                  int                    `description:"上海钢联指标父级分类id"`
 	IndexCode                         string                 `description:"指标编码"`
 	IndexName                         string                 `description:"指标名称"`

+ 4 - 4
models/data_manage/request/sci_hq_data.go

@@ -48,10 +48,10 @@ type SciHqDataBatchListReq struct {
 
 // MoveBaseFromSciHqClassifyReq 移动分类请求参数
 type MoveBaseFromSciHqClassifyReq struct {
-	ClassifyId     int `description:"分类id"`
-	ParentId       int `description:"父级分类id"`
-	PrevClassifyId int `description:"上一个兄弟节点分类id"`
-	NextClassifyId int `description:"下一个兄弟节点分类id"`
+	ClassifyId       int `description:"分类id"`
+	ParentClassifyId int `description:"父级分类id"`
+	PrevClassifyId   int `description:"上一个兄弟节点分类id"`
+	NextClassifyId   int `description:"下一个兄弟节点分类id"`
 }
 
 // MoveBaseFromSciHqReq 移动指标请求参数

+ 31 - 5
models/rag/question.go

@@ -10,8 +10,11 @@ import (
 
 type Question struct {
 	QuestionId      int       `gorm:"column:question_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"question_id"`
+	QuestionTitle   string    `gorm:"column:question_title;type:varchar(255);comment:问题标题;" description:"问题标题"`
 	QuestionContent string    `gorm:"column:question_content;type:varchar(255);comment:问题内容;" description:"问题内容"`
 	Sort            int       `gorm:"column:sort;type:int(11);comment:排序;default:0;" description:"排序"`
+	SysUserId       int       `gorm:"column:sys_user_id;type:int(11);comment:添加人id;default:0;" description:"添加人id"`
+	SysUserRealName string    `gorm:"column:sys_user_real_name;type:varchar(255);comment:添加人真实名称;" description:"添加人真实名称"`
 	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"`
 }
@@ -24,12 +27,14 @@ func (m *Question) TableName() string {
 // QuestionColumns get sql column name.获取数据库列名
 var QuestionColumns = struct {
 	QuestionID      string
+	QuestionTitle   string
 	QuestionContent string
 	Sort            string
 	ModifyTime      string
 	CreateTime      string
 }{
 	QuestionID:      "question_id",
+	QuestionTitle:   "question_title",
 	QuestionContent: "question_content",
 	Sort:            "sort",
 	ModifyTime:      "modify_time",
@@ -56,8 +61,11 @@ func (m *Question) Del() (err error) {
 
 type QuestionView struct {
 	QuestionId      int    `gorm:"column:question_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"question_id"`
-	QuestionContent string `gorm:"column:question_content;type:varchar(255);comment:问题内容;" description:"问题内容"` //
-	Sort            int    `gorm:"column:sort;type:int(11);comment:排序;default:0;" description:"sort"`          // 排序
+	QuestionTitle   string `gorm:"column:question_title;type:varchar(255);comment:问题标题;" description:"问题标题"`
+	QuestionContent string `gorm:"column:question_content;type:varchar(255);comment:问题内容;" description:"问题内容"`
+	Sort            int    `gorm:"column:sort;type:int(11);comment:排序;default:0;" description:"排序"`
+	SysUserId       int    `gorm:"column:sys_user_id;type:int(11);comment:添加人id;default:0;" description:"添加人id"`
+	SysUserRealName string `gorm:"column:sys_user_real_name;type:varchar(255);comment:添加人真实名称;" description:"添加人真实名称"`
 	ModifyTime      string `gorm:"column:modify_time;type:datetime;default:NULL;" description:"modify_time"`
 	CreateTime      string `gorm:"column:create_time;type:datetime;default:NULL;" description:"create_time"`
 }
@@ -73,8 +81,11 @@ func (m *Question) ToView() QuestionView {
 	}
 	return QuestionView{
 		QuestionId:      m.QuestionId,
+		QuestionTitle:   m.QuestionTitle,
 		QuestionContent: m.QuestionContent,
 		Sort:            m.Sort,
+		SysUserId:       m.SysUserId,
+		SysUserRealName: m.SysUserRealName,
 		ModifyTime:      modifyTime,
 		CreateTime:      createTime,
 	}
@@ -102,8 +113,11 @@ func (m *Question) GetByCondition(condition string, pars []interface{}) (item *Q
 	return
 }
 
-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 question_id desc LIMIT ?,?`, m.TableName(), condition)
+func (m *Question) GetListByCondition(field, condition string, pars []interface{}, startSize, pageSize int) (items []*Question, err error) {
+	if field == "" {
+		field = "*"
+	}
+	sqlStr := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s order by question_id desc LIMIT ?,?`, field, m.TableName(), condition)
 	pars = append(pars, startSize, pageSize)
 	err = global.DbMap[utils.DbNameAI].Raw(sqlStr, pars...).Find(&items).Error
 
@@ -128,7 +142,19 @@ func (m *Question) GetPageListByCondition(condition string, pars []interface{},
 		return
 	}
 	if total > 0 {
-		items, err = m.GetListByCondition(condition, pars, startSize, pageSize)
+		items, err = m.GetListByCondition(``, condition, pars, startSize, pageSize)
+	}
+
+	return
+}
+
+func (m *Question) GetTitlePageListByCondition(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*Question, err error) {
+	total, err = m.GetCountByCondition(condition, pars)
+	if err != nil {
+		return
+	}
+	if total > 0 {
+		items, err = m.GetListByCondition(`question_id,question_title,sort`, condition, pars, startSize, pageSize)
 	}
 
 	return

+ 1 - 1
models/report_rai.go

@@ -25,7 +25,7 @@ type ArticleResultApidate struct {
 	TitleEn       string                   `json:"title_en"`
 	Frequency     string                   `json:"frequency"`
 	CreateDate    string                   `json:"create_date"`
-	UpdateDate    string                   `json:"update_date"`
+	UpdateDate    time.Time                   `json:"update_date"`
 	PublishDate   time.Time                `json:"publish_date"`
 	PublishStatus int                      `json:"publish_status" description:"发布状态: 0未发布,2已发布,4已发布"`
 	IndustrId     int                      `json:"industry_id"`

+ 8 - 0
models/system/sys_role.go

@@ -285,3 +285,11 @@ func GetSysRoleByIdList(id []int) (items []*SysRole, err error) {
 	err = o.Raw(sql, id).Find(&items).Error
 	return
 }
+
+
+// 更新所有管理员的角色信息
+func UpdateAdminRoleInfoByRoleId(roleId int, roleName, roleTypeCode string) (err error) {
+	sql := `UPDATE admin SET role_name=?, role_type_code=? WHERE role_id=?`
+	err = global.DbMap[utils.DbNameMaster].Exec(sql, roleName, roleTypeCode, roleId).Error
+	return
+}

+ 18 - 0
routers/commentsRouter.go

@@ -8755,6 +8755,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/llm:QuestionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/llm:QuestionController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/question/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/llm:QuestionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/llm:QuestionController"],
         beego.ControllerComments{
             Method: "Edit",
@@ -8773,6 +8782,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/llm:QuestionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/llm:QuestionController"],
+        beego.ControllerComments{
+            Method: "TitleList",
+            Router: `/question/title/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/llm:UserChatController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/llm:UserChatController"],
         beego.ControllerComments{
             Method: "ChatRecordList",

+ 88 - 15
services/data/base_from_sci_hq.go

@@ -366,8 +366,9 @@ func MoveSciHqClassify(classifyId, parentClassifyId, prevClassifyId, nextClassif
 		classifyInfo.Level = parentClassifyInfo.Level + 1
 		updateCol = append(updateCol, "ParentId", "Level")
 	}
-	var currentSort, prevSort, nextSort int
-	currentSort = classifyInfo.Sort
+	var prevSort, nextSort int
+	//var currentSort, prevSort, nextSort int
+	//currentSort = classifyInfo.Sort
 
 	var prevClassify *data_manage.BaseFromSciHqClassify
 	var nextClassify *data_manage.BaseFromSciHqClassify
@@ -425,25 +426,97 @@ func MoveSciHqClassify(classifyId, parentClassifyId, prevClassifyId, nextClassif
 		}
 	}
 	//移到两个排序值中间操作
-	if prevSort >= currentSort {
-		//往下移动
-		err = data_manage.MoveDownSciHqIndexClassifyBySort(parentClassifyId, prevSort, currentSort)
+	//if prevSort >= currentSort {
+	//	//往下移动
+	//	err = data_manage.MoveDownSciHqIndexClassifyBySort(parentClassifyId, prevSort, currentSort)
+	//	if err != nil {
+	//		err = errors.New("向下移动出错:" + err.Error())
+	//		return
+	//	}
+	//	classifyInfo.Sort = prevSort
+	//} else if nextSort <= currentSort && nextSort != 0 {
+	//	//往上移动
+	//	err = data_manage.MoveUpSciHqIndexClassifyBySort(parentClassifyId, nextSort, currentSort)
+	//	if err != nil {
+	//		err = errors.New("向上移动出错:" + err.Error())
+	//		return
+	//	}
+	//	classifyInfo.Sort = nextSort
+	//}
+	//classifyInfo.ModifyTime = time.Now()
+	//updateCol = append(updateCol, "Sort", "ModifyTime")
+	//err = classifyInfo.Update(updateCol)
+	//if err != nil {
+	//	errMsg = "移动失败"
+	//	err = errors.New("修改失败,Err:" + err.Error())
+	//	return
+	//}
+
+	if prevSort >= 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == classifyInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateSciHqClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr)
+				} else {
+					_ = data_manage.UpdateSciHqClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateSciHqClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr)
+					} else {
+						_ = data_manage.UpdateSciHqClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr)
+					}
+				}
+			}
+		}
+
+		classifyInfo.Sort = prevSort + 1
+		classifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = data_manage.GetSciHqClassifySortMaxByParentId(parentClassifyId)
 		if err != nil {
-			err = errors.New("向下移动出错:" + err.Error())
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
 			return
 		}
-		classifyInfo.Sort = prevSort
-	} else if nextSort <= currentSort && nextSort != 0 {
-		//往上移动
-		err = data_manage.MoveUpSciHqIndexClassifyBySort(parentClassifyId, nextSort, currentSort)
-		if err != nil {
-			err = errors.New("向上移动出错:" + err.Error())
+		classifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		classifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstSciHqClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
 			return
 		}
-		classifyInfo.Sort = nextSort
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateSciHqClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr)
+		}
+		classifyInfo.Sort = 0 //那就是排在第一位
+		classifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
 	}
-	classifyInfo.ModifyTime = time.Now()
-	updateCol = append(updateCol, "Sort", "ModifyTime")
+
 	err = classifyInfo.Update(updateCol)
 	if err != nil {
 		errMsg = "移动失败"

+ 1 - 1
services/data/excel/excel_info.go

@@ -757,7 +757,7 @@ func GetEdbSourceByEdbInfoIdList(edbInfoIdList []int) (sourceNameList, sourceNam
 	}
 
 	for source, sourceName := range sourceMap {
-		if utils.InArrayByInt([]int{utils.DATA_SOURCE_MANUAL, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, source) {
+		if utils.InArrayByInt([]int{utils.DATA_SOURCE_MANUAL}, source) {
 			continue
 		}
 		sourceNameList = append(sourceNameList, sourceName)

+ 2 - 2
services/data/future_good/profit_chart_info.go

@@ -152,8 +152,8 @@ func GetProfitChartEdbData(baseEdbInfo *data_manage.EdbInfo, edbInfoList []*data
 			specialFutureGoodEdbInfoMap[v.FutureGoodEdbInfoId] = make(map[int]*future_good.FutureGoodEdbInfo)
 		}
 		// 获取数据
-		for findDateTime, childFutureGoodEdbInfo := range childFutureGoodEdbInfoAllMap {
-			for date, childFutureGoodEdbInfo := range childFutureGoodEdbInfo {
+		for findDateTime, childFutureGoodEdbInfoMap := range childFutureGoodEdbInfoAllMap {
+			for date, childFutureGoodEdbInfo := range childFutureGoodEdbInfoMap {
 				nAllMap[findDateTime] = append(nAllMap[findDateTime], date)
 				dataList := make([]*data_manage.EdbDataList, 0)
 				if _, ok := futureGoodDataListMap[childFutureGoodEdbInfo.FutureGoodEdbInfoId]; !ok {

+ 288 - 0
services/elastic/rag_question.go

@@ -0,0 +1,288 @@
+package elastic
+
+import (
+	"context"
+	"encoding/json"
+	"eta/eta_api/models/rag"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/olivere/elastic/v7"
+	"time"
+)
+
+// 问题索引
+var EsRagQuestionName = utils.EsRagQuestionName
+
+type RagQuestionItem struct {
+	QuestionId      int       `gorm:"column:question_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"question_id"`
+	QuestionTitle   string    `gorm:"column:question_title;type:varchar(255);comment:问题标题;" description:"问题标题"`
+	QuestionContent string    `gorm:"column:question_content;type:varchar(255);comment:问题内容;" description:"问题内容"`
+	Sort            int       `gorm:"column:sort;type:int(11);comment:排序;default:0;" description:"排序"`
+	SysUserId       int       `gorm:"column:sys_user_id;type:int(11);comment:添加人id;default:0;" description:"添加人id"`
+	SysUserRealName string    `gorm:"column:sys_user_real_name;type:varchar(255);comment:添加人真实名称;" description:"添加人真实名称"`
+	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"`
+}
+
+func (m *RagQuestionItem) ToView() rag.QuestionView {
+	var modifyTime, createTime string
+
+	if !m.CreateTime.IsZero() {
+		createTime = m.CreateTime.Format(utils.FormatDateTime)
+	}
+	if !m.ModifyTime.IsZero() {
+		modifyTime = m.ModifyTime.Format(utils.FormatDateTime)
+	}
+
+	return rag.QuestionView{
+		QuestionId:      m.QuestionId,
+		QuestionTitle:   m.QuestionTitle,
+		QuestionContent: m.QuestionContent,
+		Sort:            m.Sort,
+		SysUserId:       m.SysUserId,
+		SysUserRealName: m.SysUserRealName,
+		ModifyTime:      modifyTime,
+		CreateTime:      createTime,
+	}
+}
+
+func (m *RagQuestionItem) ToViewList(list []*RagQuestionItem) (wechatArticleViewList []rag.QuestionView) {
+	wechatArticleViewList = make([]rag.QuestionView, 0)
+
+	for _, v := range list {
+		wechatArticleViewList = append(wechatArticleViewList, v.ToView())
+	}
+	return
+}
+
+// RagQuestionEsAddOrEdit
+// @Description: 新增/编辑微信文章
+// @author: Roc
+// @datetime 2025-03-13 10:24:05
+// @param docId string
+// @param item WechatArticleAndPlatform
+// @return err error
+func RagQuestionEsAddOrEdit(docId string, item RagQuestionItem) (err error) {
+	if docId == "" {
+		return
+	}
+	if EsRagQuestionName == `` {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("WechatArticleEsAddOrEdit Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Index().Index(EsRagQuestionName).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 RagQuestionEsDel(docId string) (err error) {
+	if docId == "" {
+		return
+	}
+	if EsRagQuestionName == `` {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Delete().Index(EsRagQuestionName).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
+}
+
+// RagQuestionEsSearch
+// @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 []*RagQuestionItem
+// @return err error
+func RagQuestionEsSearch(keywordStr string, from, size int, sortMap map[string]string) (total int64, list []*RagQuestionItem, err error) {
+	indexName := EsRagQuestionName
+	list = make([]*RagQuestionItem, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	query := elastic.NewBoolQuery()
+
+	// 名字匹配
+	if keywordStr != `` {
+		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, "QuestionContent"))
+	}
+
+	// 排序
+	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 searchRagQuestion(indexName, query, sortList, from, size)
+}
+
+// searchRagQuestion 查询es中的数据
+func searchRagQuestion(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (total int64, list []*RagQuestionItem, err error) {
+	total, err = searchRagQuestionTotal(indexName, query)
+	if err != nil {
+		return
+	}
+
+	// 获取列表数据
+	list, err = searchRagQuestionList(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 searchRagQuestionTotal(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 searchRagQuestionList(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (list []*RagQuestionItem, err error) {
+	list = make([]*RagQuestionItem, 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(RagQuestionItem)
+				tmpErr = json.Unmarshal(itemJson, &item)
+				if tmpErr != nil {
+					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
+					err = tmpErr
+					return
+				}
+				if len(v.Highlight["QuestionContent"]) > 0 {
+					item.QuestionContent = v.Highlight["QuestionContent"][0]
+				}
+				list = append(list, item)
+				searchMap[v.Id] = v.Id
+			}
+		}
+	}
+
+	return
+}

+ 20 - 0
services/material/material.go

@@ -1,6 +1,7 @@
 package materialService
 
 import (
+	"encoding/json"
 	"eta/eta_api/models"
 	aiPredictModel "eta/eta_api/models/ai_predict_model"
 	"eta/eta_api/models/data_manage"
@@ -189,6 +190,25 @@ func AddToMaterial(req material.SaveAsMaterialReq, opUserId int, opUserName stri
 		return
 	}
 
+	// 兼容部分内网客户替换OSS地址
+	conf, e := models.GetBusinessConfByKey(models.BusinessConfOssUrlReplace)
+	if e != nil && !utils.IsErrNoRow(e) {
+		errMsg = "操作失败"
+		err = fmt.Errorf("获取内网配置失败, %v", e)
+		return
+	}
+	if conf != nil && conf.ConfVal != "" {
+		var urlReplace models.OssUrlReplace
+		if e := json.Unmarshal([]byte(conf.ConfVal), &urlReplace); e != nil {
+			errMsg = "操作失败"
+			err = fmt.Errorf("内网配置解析失败, %v", e)
+			return
+		}
+		if urlReplace.IsReplace && urlReplace.OssUrlOrigin != "" {
+			oldRsourceUrl = strings.ReplaceAll(oldRsourceUrl, urlReplace.OssUrlOrigin, urlReplace.OssUrlNew)
+		}
+	}
+
 	resourceUrl, err, errMsg := uploadToMaterial(oldRsourceUrl)
 	if err != nil {
 		return

+ 6 - 4
services/report_rai.go

@@ -119,6 +119,7 @@ func HandleInsertRaiReport(raiReportId int) (err error) {
 			}
 		}
 		state := reportInfo.State
+
 		// 报告已存在,更新报告
 		if (articleResult.PublishStatus == 2 || articleResult.PublishStatus == 4) && articleResult.IsActive {
 			// 报告状态为未发布,则更新报告
@@ -132,6 +133,7 @@ func HandleInsertRaiReport(raiReportId int) (err error) {
 				return
 			}
 			go UpdateReportEs(reportInfo.Id, 1)
+			return
 		}else {
 			// 报告状态为未发布,则更新报告
 			state = models.ReportStateUnpublished
@@ -153,8 +155,8 @@ func HandleInsertRaiReport(raiReportId int) (err error) {
 		reportInfo.State = state
 		reportInfo.Content = html.EscapeString(articleResult.Content.Body)
 		reportInfo.ContentSub = html.EscapeString(contentSub)
-		updateTime, _ := time.ParseInLocation(utils.FormatDate, articleResult.UpdateDate, time.Local)
-		reportInfo.ModifyTime = updateTime
+		//updateTime, _ := time.ParseInLocation(utils.FormatDateTime, articleResult.UpdateDate, time.Local)
+		reportInfo.ModifyTime = articleResult.UpdateDate
 
 		// 报告更新
 		updateCols := []string{"ClassifyIdFirst","ClassifyNameFirst","ClassifyIdSecond","ClassifyNameSecond","Title","Abstract","Author","Frequency","State","Content","ContentSub","ModifyTime","PublishTime"}
@@ -215,8 +217,8 @@ func HandleInsertRaiReport(raiReportId int) (err error) {
 			item.Stage = 0
 			item.ContentSub = html.EscapeString(contentSub)
 			item.CreateTime = time.Now().Format(utils.FormatDateTime)
-			updateTime, _ := time.ParseInLocation(utils.FormatDate, articleResult.UpdateDate, time.Local)
-			item.ModifyTime = updateTime
+			//updateTime, _ := time.ParseInLocation(utils.FormatDateTime, articleResult.UpdateDate, time.Local)
+			item.ModifyTime = articleResult.UpdateDate
 			item.ReportVersion = 2
 			item.AdminId = 0
 			item.AdminRealName = ""

+ 62 - 3
services/wechat_platform.go

@@ -534,7 +534,7 @@ func getAnswerByContent(wechatArticleId int, docId string) (answer string, addAr
 	addArticleChatRecordList = make([]*rag.WechatArticleChatRecord, 0)
 
 	questionObj := rag.Question{}
-	questionList, err := questionObj.GetListByCondition(``, []interface{}{}, 0, 100)
+	questionList, err := questionObj.GetListByCondition(``, ``, []interface{}{}, 0, 100)
 	if err != nil {
 		err = fmt.Errorf("获取问题列表失败,Err:" + err.Error())
 		return
@@ -1014,8 +1014,8 @@ func AddOrEditEsWechatArticleAbstract(articleAbstractId int) {
 	err = elastic.WechatArticleAbstractEsAddOrEdit(strconv.Itoa(articleAbstractId), esItem)
 }
 
-// AddOrEditEsWechatArticleAbstract
-// @Description: 新增/编辑微信文章摘要入ES
+// DelEsWechatArticleAbstract
+// @Description: 删除ES中的微信文章摘要
 // @author: Roc
 // @datetime 2025-03-13 14:13:47
 // @param articleAbstractId int
@@ -1034,3 +1034,62 @@ func DelEsWechatArticleAbstract(articleAbstractId int) {
 
 	err = elastic.WechatArticleAbstractEsDel(strconv.Itoa(articleAbstractId))
 }
+
+// AddOrEditEsRagQuestion
+// @Description: 新增/编辑知识库问题入ES
+// @author: Roc
+// @datetime 2025-03-28 11:25:50
+// @param questionId int
+func AddOrEditEsRagQuestion(questionId 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.Question{}
+	questionInfo, err := obj.GetByID(questionId)
+	if err != nil {
+		err = fmt.Errorf("获取公众号文章信息失败,Err:" + err.Error())
+		return
+	}
+
+	esItem := elastic.RagQuestionItem{
+		QuestionId:      questionInfo.QuestionId,
+		QuestionTitle:   questionInfo.QuestionTitle,
+		QuestionContent: questionInfo.QuestionContent,
+		Sort:            questionInfo.Sort,
+		SysUserId:       questionInfo.SysUserId,
+		SysUserRealName: questionInfo.SysUserRealName,
+		ModifyTime:      questionInfo.ModifyTime,
+		CreateTime:      questionInfo.CreateTime,
+	}
+
+	err = elastic.RagQuestionEsAddOrEdit(strconv.Itoa(questionInfo.QuestionId), esItem)
+}
+
+// DelEsRagQuestion
+// @Description: 删除ES中的知识库问题
+// @author: Roc
+// @datetime 2025-03-28 11:26:40
+// @param questionId int
+func DelEsRagQuestion(questionId 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.RagQuestionEsDel(strconv.Itoa(questionId))
+}

+ 17 - 1
utils/common.go

@@ -1869,7 +1869,7 @@ func GetDateByDateTypeV2(dateType int, tmpStartDate, tmpEndDate string, startYea
 			startDate = startDate + "-01"
 		}
 		if strings.Count(endDate, "-") == 1 {
-			endTime, err := time.ParseInLocation(FormatYearMonthDate, endDate,time.Local)
+			endTime, err := time.ParseInLocation(FormatYearMonthDate, endDate, time.Local)
 			if err != nil {
 				return
 			}
@@ -3095,3 +3095,19 @@ func RemoveSpecialChars(text string) string {
 	reg := regexp.MustCompile(`[^\p{Han}\p{L}\p{N}\x{3000}-\x{303F}]`)
 	return reg.ReplaceAllString(text, "")
 }
+
+// GetFirstNChars
+// @Description: 截取字符串的前N个字符
+// @author: Roc
+// @datetime 2025-03-28 10:17:23
+// @param s string
+// @param max int
+// @return string
+func GetFirstNChars(s string, max int) string {
+	s = strings.NewReplacer("\r", "", "\n", "").Replace(strings.TrimSpace(s))
+	runes := []rune(s)
+	if len(runes) < max {
+		max = len(runes)
+	}
+	return string(runes[:max])
+}

+ 1 - 0
utils/config.go

@@ -148,6 +148,7 @@ var (
 	EsDataSourceIndexName          string // 数据源ES索引名称
 	EsWechatArticleName            string // ES索引名称-微信文章
 	EsWechatArticleAbstractName    string // ES索引名称-微信文章摘要
+	EsRagQuestionName              string // ES索引名称-知识库问题
 )
 
 var (

+ 6 - 3
utils/constants.go

@@ -237,6 +237,9 @@ const (
 	CACHE_ACCESS_TOKEN_LOGIN_NO_TRUST = "pc_eta_admin:login:no_trust:"        //管理后台登录(不可信登录态)
 	CACHE_ABNORMAL_LOGIN              = "pc_eta_admin:login:abnormal:"        //管理后台登录-异常登录
 	CACHE_LOGIN_ERR_PASS              = "pc_eta_admin:login:errPass:"         //管理后台登录-输入错误密码次数
+	MOBILE_CACHE_ABNORMAL_LOGIN       = "mobile_eta_admin:login:abnormal:"        //管理后台登录-异常登录
+	MOBILE_CACHE_LOGIN_ERR_PASS             = "mobile_eta_admin:login:errPass:"         //管理后台登录-输入错误密码次数
+
 	CACHE_FIND_PASS_VERIFY            = "pc_eta_admin:findPass:verify:"       //找回密码校验成功标记
 	CACHE_KEY_MYSTEEL_REFRESH         = "mysteel_chemical:refresh"            //上海钢联刷新
 	CACHE_KEY_DAYNEW_REFRESH          = "admin:day_new:refresh"               //每日资讯拉取企业微信聊天记录
@@ -268,9 +271,9 @@ const (
 	CACHE_DATA_SOURCE_ES_HANDLE             = "eta:data_source_es:handle"            // 数据源es处理队列
 	CACHE_WECHAT_PLATFORM_ARTICLE           = "wechat_platform:article:op"           //微信文章处理
 	CACHE_WECHAT_PLATFORM_ARTICLE_KNOWLEDGE = "wechat_platform:article:knowledge:op" //微信文章入知识库处理
-	CACHE_CHART_AUTH        = "eta:chart:auth:"        //图表数据授权
-	CACHE_REPORT_SHARE_AUTH = "eta:report:auth:share:" //报告短链与报告图表授权映射key
-	CACHE_REPORT_AUTH       = "eta:report:auth:"       //报告图表数据授权
+	CACHE_CHART_AUTH                        = "eta:chart:auth:"                      //图表数据授权
+	CACHE_REPORT_SHARE_AUTH                 = "eta:report:auth:share:"               //报告短链与报告图表授权映射key
+	CACHE_REPORT_AUTH                       = "eta:report:auth:"                     //报告图表数据授权
 )
 
 // 模板消息推送类型