瀏覽代碼

Merge branch 'feature/eta2.3.4_business_user' of eta_forum/eta_forum_task into master

xyxie 1 月之前
父節點
當前提交
9482807dad

+ 25 - 1
models/chart_classify.go

@@ -3,8 +3,9 @@ package models
 import (
 	"eta/eta_forum_task/utils"
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
 )
 
 type ChartClassify struct {
@@ -348,3 +349,26 @@ func GetChartClassifyBySourceAndIsJoinPermission(source, isJoinPermission int) (
 	_, err = o.Raw(sql, source, isJoinPermission).QueryRows(&items)
 	return
 }
+
+// GetChartClassifyListByCondition 根据条件获取分类列表
+func GetChartClassifyListByCondition(condition string, pars []interface{}) (items []*ChartClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_classify WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func SetForumChartInfoId(chart_info_id, forum_chart_info_id, resourceStatus int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` UPDATE  chart_info
+			SET
+              forum_chart_info_id=?,
+			  modify_time = NOW(),
+			  resource_status = ?
+			WHERE chart_info_id = ?`
+	_, err = o.Raw(sql, forum_chart_info_id, resourceStatus, chart_info_id).Exec()
+	return
+}

+ 36 - 0
models/chart_description.go

@@ -0,0 +1,36 @@
+package models
+
+import (
+	"time"
+	"github.com/beego/beego/v2/client/orm"	
+)
+
+type ChartDescription struct {
+	Id               int       `gorm:"column:id;primaryKey"`
+	Description      string    `gorm:"column:description"`
+	ChartInfoId      int       `gorm:"column:chart_info_id"` // 图表id
+	SysUserId        int       `gorm:"column:sys_user_id"`     // 创建人id
+	SysUserRealName  string    `gorm:"column:sys_user_real_name"` // 创建人姓名
+	ModifyTime       time.Time `gorm:"column:modify_time"`     // 变更时间
+	CreateTime       time.Time `gorm:"column:create_time"`     // 关系建立时间
+}
+
+
+// GetChartDescriptionByChartInfoId 根据图表ID获取图表简介
+func GetChartDescriptionByChartInfoId(chartInfoId int) (item []*ChartDescription, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_description WHERE chart_info_id = ? order by create_time desc, id desc`
+	_, err = o.Raw(sql, chartInfoId).QueryRows(&item)
+	return
+}
+
+type ChartDescriptionReq struct {
+	Id               int       
+	Description      string      // 图表id
+	ChartInfoId      int       
+	SysUserId        int         // 创建人id
+	SysUserRealName  string    	 // 创建人姓名
+	AdminName        string   	 // 创建人姓名
+	ModifyTime       time.Time 	 // 变更时间
+	CreateTime       time.Time 	 // 关系建立时间  
+}

+ 1 - 1
models/chart_edb_mapping.go

@@ -322,7 +322,7 @@ func GetChartMappingList(chartInfoId int) (list []*ChartEdbMapping, err error) {
 	sql := ` SELECT a.*
              FROM chart_edb_mapping AS a
 			 WHERE chart_info_id=? 
-             ORDER BY chart_edb_mapping_id ASC `
+             ORDER BY edb_info_id ASC `
 	_, err = o.Raw(sql, chartInfoId).QueryRows(&list)
 	return
 }

+ 1 - 0
models/db.go

@@ -60,6 +60,7 @@ func initChart() {
 		new(ChartEdbMapping),
 		new(ChartTheme),
 		new(ChartThemeType),
+		new(ForumChartEdbMapping),
 	)
 }
 

+ 67 - 0
models/edb_update_log.go

@@ -0,0 +1,67 @@
+package models
+
+import (
+	"eta/eta_forum_task/utils"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type EdbUpdateLog struct {
+	Id          uint64    `orm:"pk;column(id)"`
+	OpDbName    string    
+	OpTableName string    
+	OpType      string 
+	OldData     string   
+	NewData     string    
+	IsHandle    uint8     
+	ModifyTime  time.Time
+	CreateTime  time.Time 
+}
+
+func (EdbUpdateLog) TableName() string {
+	return "edb_update_log"
+}
+
+// 查询未处理的日志列表总数
+func GetEdbUpdateLogListCount(dateTime string) (int, error) {
+	
+	o := orm.NewOrmUsingDB("data")
+	
+	sql := `SELECT COUNT(1) FROM edb_update_log WHERE is_handle = 0 and op_table_name != "edb_info" and create_time > ?`
+
+	var count int64
+	err := o.Raw(sql, dateTime).QueryRow(&count)
+	if err != nil {
+		return 0, err
+	}
+	return int(count), nil
+}
+// 分页获取待处理的日志列表
+func GetEdbUpdateLogList(dateTime string, offset int, pageSize int) ([]*EdbUpdateLog, error) {
+
+	o := orm.NewOrmUsingDB("data")
+	
+	sql := `SELECT * FROM edb_update_log WHERE is_handle = 0 and op_table_name != "edb_info" and op_table_name != "edb_data_insert_config" and create_time > ? ORDER BY id ASC LIMIT ?, ?`
+	
+	var logs []*EdbUpdateLog
+	_, err := o.Raw(sql, dateTime, offset, pageSize).QueryRows(&logs)
+	if err != nil {
+		return nil, err
+	}
+	return logs, nil
+}
+
+
+// 批量更新日志状态
+func UpdateEdbUpdateLogStatus(logIds []int) error {
+	o := orm.NewOrmUsingDB("data")
+	
+	sql := `UPDATE edb_update_log SET is_handle = 1, modify_time = ? WHERE id IN (`+utils.GetOrmInReplace(len(logIds))+`)`
+	_, err := o.Raw(sql, time.Now(), logIds).Exec()
+	if err != nil {
+		return err
+	}
+	return nil
+}
+

+ 47 - 0
models/forum_chart_edb_mapping.go

@@ -0,0 +1,47 @@
+package models
+
+import (
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type ForumChartEdbMapping struct {
+	ID int `orm:"column(id);pk;auto" description:"主键"`
+	ChartInfoId int 
+	EdbInfoIds string 
+	CreateTime time.Time 
+	ModifyTime time.Time 
+}
+
+// 根据chartInfoId获取edbInfoIds
+func GetEdbInfoIdsByChartInfoId(chartInfoId int) (edbInfoIds string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT edb_info_ids FROM forum_chart_edb_mapping WHERE chart_info_id = ?`
+	err = o.Raw(sql, chartInfoId).QueryRow(&edbInfoIds)
+	return
+}
+
+// 新增
+func AddForumChartEdbMapping(chartInfoId int, edbInfoIds string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `INSERT INTO forum_chart_edb_mapping (chart_info_id, edb_info_ids, create_time, modify_time) VALUES (?, ?, ?, ?)`
+	_, err = o.Raw(sql, chartInfoId, edbInfoIds, time.Now(), time.Now()).Exec()
+	return
+}
+
+// 更新
+func UpdateForumChartEdbMapping(chartInfoId int, edbInfoIds string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE forum_chart_edb_mapping SET edb_info_ids = ?, modify_time = ? WHERE chart_info_id = ?`
+	_, err = o.Raw(sql, edbInfoIds, time.Now(), chartInfoId).Exec()
+	return
+}
+
+// 删除
+func DeleteForumChartEdbMapping(chartInfoId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `DELETE FROM forum_chart_edb_mapping WHERE chart_info_id = ?`
+	_, err = o.Raw(sql, chartInfoId).Exec()
+	return
+}

+ 394 - 85
services/chart_info.go

@@ -8,79 +8,30 @@ import (
 	"eta/eta_forum_task/services/eta_forum"
 	"eta/eta_forum_task/utils"
 	"fmt"
+	"strconv"
 	"time"
 )
 
 func EtaForumChartUpdate(cont context.Context) (err error) {
-	var tmpErr []error
-	deleteCache := true
-	cacheKey := "eta_forum_task:EtaForumChartUpdate"
-	defer func() {
-		if deleteCache {
-			_ = utils.Rc.Delete(cacheKey)
-		}
-		stack := ""
-		if err != nil {
-			stack = fmt.Sprintln(stack + err.Error())
-		}
-		if len(tmpErr) > 0 {
-			for _, v := range tmpErr {
-				stack = fmt.Sprintln(stack + v.Error())
-			}
-		}
-		if stack != "" {
-			go alarm_msg.SendAlarmMsg(utils.APP_NAME_CN+"更新社区图表信息失败"+time.Now().Format("2006-01-02 15:04:05")+"<br/>"+stack, 3)
-		}
-	}()
-	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
-		deleteCache = false
-		err = fmt.Errorf("系统处理中,请稍后重试!")
-		return
-	}
-	// 设置缓存判断处理中则不更新
-	condition := " and forum_chart_info_id > 0 and source=1 "
-	// 查询需要更新的图表信息总数
-	total, err := models.GetChartInfoCountByCondition(condition, []interface{}{})
-	if err != nil {
-		return
-	}
-	if total == 0 {
-		return
-	}
-	// 更新图表数据
-	offset := 0
-	pageSize := 100
-	success := 0
-
-	// 循环更新100个图表数据
-	for i := 0; offset < total; i++ {
-		// 查询需要更新的图表信息
-		chartInfos, e := models.GetChartInfoListByCondition(condition, []interface{}{}, offset, pageSize)
-		if e != nil {
-			err = fmt.Errorf("查询需要更新的图表信息失败: %v", e)
-			return
-		}
-		// 循环更新图表数据
-		for _, chartInfo := range chartInfos {
-			// 更新图表数据
-			er, msg := UpdateChart(chartInfo.ChartInfoId)
-			if er != nil {
-				er = fmt.Errorf("图表ID %d, 更新图表数据失败: %s, %v", chartInfo.ChartInfoId, msg, er)
-				tmpErr = append(tmpErr, er)
-				continue
-			}
-			success += 1
-		}
-
-		offset = (i + 1) * pageSize
-		time.Sleep(2 * time.Second)
-	}
-	fmt.Println("更新图表数据完成, 更新图表数据总数:", success)
+	err = ChartInfoSaveBatch()
 	return
 }
 
 // UpdateChart 更新社区里的图表接口
 func UpdateChart(chartInfoId int) (err error, errMsg string) {
+	// 设置缓存 防止重复更新
+	cacheKey := "eta_forum_task:UpdateChart:" + strconv.Itoa(chartInfoId)
+	if utils.Rc.Get(cacheKey) != nil {
+		err = fmt.Errorf("系统处理中,请稍后重试!")
+		return
+	}
+	utils.Rc.SetNX(cacheKey, 1, 10*time.Minute)
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg(fmt.Sprintf("更新图表至社区失败:Err:%v,ErrMsg:%s", err, errMsg), 3)
+		}
+		utils.Rc.Delete(cacheKey)
+	}()
 	// 查询图表信息
 	chartInfo, err := models.GetChartInfoById(chartInfoId)
 	if err != nil {
@@ -106,8 +57,10 @@ func UpdateChart(chartInfoId int) (err error, errMsg string) {
 		return
 	}
 	edbIds := make([]int, 0)
+	edbInfoStr := ""
 	for _, v := range chartMappingList {
 		edbIds = append(edbIds, v.EdbInfoId)
+		edbInfoStr += strconv.Itoa(v.EdbInfoId) + ","
 	}
 	chartSeriesList := make([]*models.ChartSeries, 0)
 	chartSeriesEdbList := make([]*models.ChartSeriesEdbMapping, 0)
@@ -132,12 +85,29 @@ func UpdateChart(chartInfoId int) (err error, errMsg string) {
 		edbInfoDataList []*eta_forum.AddEdbDataReq
 	)
 	//查询指标详情
-	edbInfoList, edbMappingList, edbInfoDataList, err = GetEdbListByEdbInfoId(edbIds)
+	isGetEdbData := false
+	// 查询投研资源库里的图表和指标绑定关系
+	oldEdbInfoStr, err := models.GetEdbInfoIdsByChartInfoId(chartInfoId)
+	if err != nil {
+		errMsg = "获取投研资源库里的图表和指标绑定关系失败"
+		err = fmt.Errorf("获取投研资源库里的图表和指标绑定关系失败,Err:" + err.Error())
+		return
+	}
+	if oldEdbInfoStr != edbInfoStr { // 图表更换过指标需要重新获取指标数据
+		isGetEdbData = true
+	}
+	edbInfoList, edbMappingList, edbInfoDataList, err = GetEdbListByEdbInfoId(edbIds, isGetEdbData)
 	if err != nil {
 		errMsg = "获取指标详情失败"
 		err = fmt.Errorf("获取指标详情失败,Err:" + err.Error())
 		return
 	}
+	descriptionList, err, errMsg := getChartDescriptionWithAdminNameByChartInfoId(chartInfoId)
+	if err != nil {
+		errMsg = "获取图表简介失败"
+		err = fmt.Errorf("获取图表简介失败,Err:" + err.Error())
+		return
+	}
 	req := new(eta_forum.ChartSaveLibReq)
 	req.ChartInfo = chartInfo
 	req.ChartInfo.ChartInfoId = chartInfo.ForumChartInfoId
@@ -147,6 +117,7 @@ func UpdateChart(chartInfoId int) (err error, errMsg string) {
 	req.EdbInfoCalculateMapping = edbMappingList
 	req.ChartSeries = chartSeriesList
 	req.ChartSeriesEdbMapping = chartSeriesEdbList
+	req.Description = descriptionList
 	// 查询创建者信息
 	creatorInfo, _ := models.GetSysUserById(chartInfo.SysUserId)
 	if creatorInfo != nil {
@@ -171,21 +142,31 @@ func UpdateChart(chartInfoId int) (err error, errMsg string) {
 		err = fmt.Errorf(respItem.ErrMsg)
 		return
 	}
-
+	// 更新投研资源库里的图表和指标绑定关系
+	if oldEdbInfoStr != edbInfoStr {
+		err = models.UpdateForumChartEdbMapping(chartInfoId, edbInfoStr)
+		if err != nil {
+			errMsg = "更新投研资源库里的图表和指标绑定关系失败"
+			err = fmt.Errorf("更新投研资源库里的图表和指标绑定关系失败,Err:" + err.Error())
+			return
+		}
+	}
 	return
 }
 
-func GetEdbListByEdbInfoId(edbInfoIds []int) (edbInfoList []*models.EdbInfo, edbMappingList []*models.EdbInfoCalculateMapping, edbInfoDataList []*eta_forum.AddEdbDataReq, err error) {
+func GetEdbListByEdbInfoId(edbInfoIds []int, isGetEdbData bool) (edbInfoList []*models.EdbInfo, edbMappingList []*models.EdbInfoCalculateMapping, edbInfoDataList []*eta_forum.AddEdbDataReq, err error) {
 	//查询指标信息
 	//查询指标映射
 	//查询所有指标数据
 	//查询这个指标相关的mapping信息放到数组里,
 	//将得到的指标ID信息放到数组里
+	chartEdbInfoIdMap := make(map[int]struct{}) //只查询图表上直接相关的指标数据
 	hasFindMap := make(map[int]struct{})
 	edbInfoIdMap := make(map[int]struct{})
 	edbMappingList = make([]*models.EdbInfoCalculateMapping, 0)
 	edbMappingMap := make(map[int]struct{})
 	for _, edbInfoId := range edbInfoIds {
+		chartEdbInfoIdMap[edbInfoId] = struct{}{}
 		edbMappingList, err = traceEdbInfoByEdbInfoId(edbInfoId, hasFindMap, edbInfoIdMap, edbMappingList, edbMappingMap)
 		if err != nil {
 			return
@@ -202,26 +183,31 @@ func GetEdbListByEdbInfoId(edbInfoIds []int) (edbInfoList []*models.EdbInfo, edb
 		err = fmt.Errorf("traceEdbInfoByEdbInfoId GetEdbInfoByIdList err: %s", err.Error())
 		return
 	}
+	if isGetEdbData {
+		for _, v := range edbInfoList {
+			if _, ok := chartEdbInfoIdMap[v.EdbInfoId]; !ok {
+				continue
+			}
+			var dataList []*models.EdbDataBase
+			if v.Source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo {
+				dataList, err = models.GetEdbDataBaseMongoByEdbInfoId(v.EdbInfoId, v.Source, v.SubSource)
+			} else if v.Source == utils.DATA_SOURCE_THS && v.SubSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && utils.UseMongo {
+				dataList, err = models.GetThsHfEdbDataBaseMongoByEdbInfoId(v.EdbInfoId, v.Source, v.SubSource)
+			} else {
+				dataList, err = models.GetEdbDataBaseByEdbInfoId(v.EdbInfoId, v.Source, v.SubSource)
+			}
+			if err != nil {
+				err = fmt.Errorf("查询指标数据失败 Err: %s", err.Error())
+				return
+			}
 
-	for _, v := range edbInfoList {
-		var dataList []*models.EdbDataBase
-		if v.Source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo {
-			dataList, err = models.GetEdbDataBaseMongoByEdbInfoId(v.EdbInfoId, v.Source, v.SubSource)
-		} else if v.Source == utils.DATA_SOURCE_THS && v.SubSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && utils.UseMongo {
-			dataList, err = models.GetThsHfEdbDataBaseMongoByEdbInfoId(v.EdbInfoId, v.Source, v.SubSource)
-		} else {
-			dataList, err = models.GetEdbDataBaseByEdbInfoId(v.EdbInfoId, v.Source, v.SubSource)
-		}
-		if err != nil {
-			err = fmt.Errorf("查询指标数据失败 Err: %s", err.Error())
-			return
+			tmp := new(eta_forum.AddEdbDataReq)
+			tmp.EdbInfoId = v.EdbInfoId
+			tmp.EdbCode = v.EdbCode
+			tmp.EdbType = v.EdbType
+			tmp.DataList = dataList
+			edbInfoDataList = append(edbInfoDataList, tmp)
 		}
-
-		tmp := new(eta_forum.AddEdbDataReq)
-		tmp.EdbCode = v.EdbCode
-		tmp.EdbType = v.EdbType
-		tmp.DataList = dataList
-		edbInfoDataList = append(edbInfoDataList, tmp)
 	}
 	return
 }
@@ -290,3 +276,326 @@ func traceEdbInfoByEdbInfoId(edbInfoId int, hasFindMap map[int]struct{}, edbInfo
 	hasFindMap[edbInfoId] = struct{}{}
 	return
 }
+
+// 批量上传图表分类信息
+func ChartInfoSaveBatch() (err error) {
+	var tmpErr []error
+	cacheKey := "eta_forum_task:ChartInfoSaveBatchAdmin"
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Minute) {
+		err = fmt.Errorf("系统处理中,请稍后重试!")
+		return
+	}
+	defer func() {
+		utils.Rc.Delete(cacheKey)
+		stack := ""
+		if err != nil {
+			stack = fmt.Sprintln(stack + err.Error())
+		}
+		if len(tmpErr) > 0 {
+			for _, v := range tmpErr {
+				stack = fmt.Sprintln(stack + v.Error())
+			}
+		}
+		if stack != "" {
+			utils.FileLog.Error("批量上传资源库图表信息失败"+"<br/>"+stack)
+			go alarm_msg.SendAlarmMsg("批量上传资源库图表信息失败"+"<br/>"+stack, 3)
+		}
+	}()
+	// 已上架的图表都更新,批量更新图表信息
+	condition := " and source=1 and forum_chart_info_id > 0 and resource_status =1"
+	// 查询需要更新的图表信息总数
+	total, err := models.GetChartInfoCountByCondition(condition, []interface{}{})
+	if err != nil {
+		return
+	}
+	if total > 0 {
+		// 批量上传图表信息
+		offset := 0
+		pageSize := 100
+		success := 0
+
+		// 循环更新100个图表数据
+		for i := 0; offset < total; i++ {
+			// 查询需要更新的图表信息
+			chartInfos, e := models.GetChartInfoListByCondition(condition, []interface{}{}, offset, pageSize)
+			if e != nil {
+				err = fmt.Errorf("查询需要更新的图表信息失败: %v", e)
+				return
+			}
+			if len(chartInfos) == 0 {
+				break
+			}
+			// 循环更新图表数据
+			for _, chartInfo := range chartInfos {
+				var er error
+				var msg string
+				// 更新图表数据
+				er, msg = UpdateChart(chartInfo.ChartInfoId)
+				
+				if er != nil {
+					er = fmt.Errorf("图表ID %d, 更新图表数据失败: %s, %v", chartInfo.ChartInfoId, msg, er)
+					tmpErr = append(tmpErr, er)
+					continue
+				}
+				success += 1
+			}
+
+			offset += pageSize
+		}
+		utils.FileLog.Info("更新图表数据完成, 更新图表数据总数:", success)
+	}
+	// 更新指标数据
+	utils.Rc.LPush(utils.CACHE_KEY_EDB_DATA_UPDATE_LOG, []byte("1"))
+	sysUser, err := models.GetSysUserByAdminName("admin")
+	if err != nil {
+		err = fmt.Errorf("获取系统用户失败,Err:" + err.Error())
+		return
+	}
+	// 获取精选资源分类已经上架的分类
+	classifyCondition := " AND source=? and is_selected=1 and resource_status=1 "
+	var classifyPars []interface{}
+	classifyPars = append(classifyPars, utils.CHART_SOURCE_DEFAULT)
+	classifyList, err := models.GetChartClassifyListByCondition(classifyCondition, classifyPars)
+	if err != nil {
+		return
+	}
+	chartClassifyIdList := make([]string, 0)
+	for _, v := range classifyList {
+		chartClassifyIdList = append(chartClassifyIdList, strconv.Itoa(v.ChartClassifyId))
+	}
+	if len(chartClassifyIdList) == 0 {
+		return
+	}
+	// 批量上传图表信息
+	condition = " and source=1 and forum_chart_info_id = 0  and chart_classify_id in ("+utils.GetOrmInReplace(len(chartClassifyIdList))+") and resource_status !=2"
+	// 查询需要更新的图表信息总数
+	total, err = models.GetChartInfoCountByCondition(condition, []interface{}{chartClassifyIdList})
+	if err != nil {
+		return
+	}
+	if total == 0 {
+		return
+	}
+
+	// 批量上传图表信息
+	offset := 0
+	pageSize := 100
+	success := 0
+
+	// 循环更新100个图表数据
+	for i := 0; offset < total; i++ {
+		// 查询需要更新的图表信息
+		chartInfos, e := models.GetChartInfoListByCondition(condition, []interface{}{chartClassifyIdList}, offset, pageSize)
+		if e != nil {
+			err = fmt.Errorf("查询需要更新的图表信息失败: %v", e)
+			return
+		}
+		if len(chartInfos) == 0 {
+			break
+		}
+		// 循环更新图表数据
+		for _, chartInfo := range chartInfos {
+			var er error
+			var msg string
+			// 上传图表数据
+			er, msg = UploadChart(chartInfo.ChartInfoId, "", sysUser)
+			
+			if er != nil {
+				er = fmt.Errorf("图表ID %d, 上传图表数据失败: %s, %v", chartInfo.ChartInfoId, msg, er)
+				tmpErr = append(tmpErr, er)
+				continue
+			}
+			success += 1
+		}
+
+		offset += pageSize
+	}
+	utils.FileLog.Info("上传图表数据完成, 上传图表数据总数:", success)
+
+	
+	return
+}
+
+// UploadChart 上传图表接口
+func UploadChart(chartInfoId int, description string, uploaderInfo *models.Admin) (err error, errMsg string) {
+	// 设置缓存 防止重复上传
+	cacheKey := "eta_forum_task:UploadChart:" + strconv.Itoa(chartInfoId)
+	if utils.Rc.Get(cacheKey) != nil {
+		err = fmt.Errorf("系统处理中,请稍后重试!")
+		return
+	}
+	utils.Rc.SetNX(cacheKey, 1, 10*time.Minute)
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg(fmt.Sprintf("上传图表至社区失败:Err:%v,ErrMsg:%s", err, errMsg), 3)
+		}
+		utils.Rc.Delete(cacheKey)
+	}()
+
+	// 查询图表信息
+	chartInfo, err := models.GetChartInfoById(chartInfoId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = "图表不存在"
+			err = fmt.Errorf(errMsg)
+			return
+		}
+		errMsg = "获取图表信息失败"
+		err = fmt.Errorf("获取图表信息失败,Err:" + err.Error())
+		return
+	}
+	if chartInfo.ForumChartInfoId > 0 {
+		errMsg = "该图表已上传至社区,无法再次上传"
+		err = fmt.Errorf(errMsg)
+		return
+	}
+	//查询图表主题
+
+	//查询图表指标
+	//获取原图表关联的指标信息列表
+	chartMappingList, err := models.GetChartMappingList(chartInfoId)
+	if err != nil {
+		errMsg = "获取图表关联的指标信息失败"
+		err = fmt.Errorf("获取图表关联的指标信息失败,Err:" + err.Error())
+		return
+	}
+	edbIds := make([]int, 0)
+	edbInfoStr := ""
+	for _, v := range chartMappingList {
+		edbIds = append(edbIds, v.EdbInfoId)
+		edbInfoStr += strconv.Itoa(v.EdbInfoId) + ","
+	}
+	chartSeriesList := make([]*models.ChartSeries, 0)
+	chartSeriesEdbList := make([]*models.ChartSeriesEdbMapping, 0)
+	if chartInfo.ChartType == utils.CHART_TYPE_SECTION_COMBINE {
+		chartSeriesList, err = models.GetChartSeriesByChartInfoId(chartInfoId)
+		if err != nil {
+			errMsg = "获取图表关联的系列信息失败"
+			err = fmt.Errorf("获取图表关联的系列信息失败,Err:" + err.Error())
+			return
+		}
+
+		chartSeriesEdbList, err = models.GetChartSeriesEdbByChartInfoId(chartInfoId)
+		if err != nil {
+			errMsg = "获取图表关联的系列指标信息失败"
+			err = fmt.Errorf("获取图表关联的系列指标信息失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	var (
+		edbInfoList     []*models.EdbInfo
+		edbMappingList  []*models.EdbInfoCalculateMapping
+		edbInfoDataList []*eta_forum.AddEdbDataReq
+	)
+	//查询指标详情
+	edbInfoList, edbMappingList, edbInfoDataList, err = GetEdbListByEdbInfoId(edbIds, true)
+	if err != nil {
+		errMsg = "获取指标详情失败"
+		err = fmt.Errorf("获取指标详情失败,Err:" + err.Error())
+		return
+	}
+	descriptionList, err, errMsg := getChartDescriptionWithAdminNameByChartInfoId(chartInfoId)
+	if err != nil {
+		errMsg = "获取图表简介失败"
+		err = fmt.Errorf("获取图表简介失败,Err:" + err.Error())
+		return
+	}
+
+	req := new(eta_forum.ChartSaveLibReq)
+	req.ChartInfo = chartInfo
+	req.ChartEdbMapping = chartMappingList
+	req.EdbInfoList = edbInfoList
+	req.EdbInfoDataList = edbInfoDataList
+	req.EdbInfoCalculateMapping = edbMappingList
+	req.Description = descriptionList
+	req.ChartSeries = chartSeriesList
+	req.ChartSeriesEdbMapping = chartSeriesEdbList
+
+	// 查询创建者信息
+	creatorInfo, _ := models.GetSysUserById(chartInfo.SysUserId)
+	if creatorInfo != nil {
+		req.CreatorInfo = creatorInfo
+	}
+
+	req.UploaderInfo = uploaderInfo
+	// 添加计算指标
+	reqJson, err := json.Marshal(req)
+	if err != nil {
+		errMsg = "参数解析异常"
+		err = fmt.Errorf("参数解析异常,Err:" + err.Error())
+		return
+	}
+	respItem, err := eta_forum.ChartSaveLib(string(reqJson))
+	if err != nil {
+		errMsg = "上传失败"
+		err = fmt.Errorf("上传失败,Err:" + err.Error())
+		return
+	}
+	if respItem.Ret != 200 {
+		errMsg = "上传失败"
+		err = fmt.Errorf(respItem.ErrMsg)
+		return
+	}
+
+	if respItem.Data != nil && respItem.Data.ChartInfoId != 0 {
+		// 更新社区返回的图表ID
+		err = models.SetForumChartInfoId(chartInfoId, respItem.Data.ChartInfoId, utils.ChartClassifyResourceStatusUp)
+		if err != nil {
+			errMsg = "更新图表ID失败"
+			err = fmt.Errorf("更新图表ID失败,Err:" + err.Error())
+			return
+		}
+
+		// 新增投研资源库里的图表和指标绑定关系
+		err = models.AddForumChartEdbMapping(chartInfoId, edbInfoStr)
+		if err != nil {
+			errMsg = "新增投研资源库里的图表和指标绑定关系失败"
+			err = fmt.Errorf("新增投研资源库里的图表和指标绑定关系失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	return
+}
+
+func getChartDescriptionWithAdminNameByChartInfoId(chartInfoId int) (list []*models.ChartDescriptionReq, err error, errMsg string) {
+	descriptionList, err := models.GetChartDescriptionByChartInfoId(chartInfoId)
+	if err != nil {
+		errMsg = "获取图表简介失败"
+		err = fmt.Errorf("获取图表简介失败,Err:" + err.Error())
+		return
+	}
+	// 查询创建者信息
+	adminIdList := make([]int, 0)
+	for _, v := range descriptionList {
+		adminIdList = append(adminIdList, v.SysUserId)
+	}
+	adminList, err := models.GetAdminListByIdList(adminIdList)
+	if err != nil {
+		errMsg = "获取创建者信息失败"
+		err = fmt.Errorf("获取创建者信息失败,Err:" + err.Error())
+		return
+	}
+	adminMap := make(map[int]string)
+	for _, v := range adminList {
+		adminMap[v.AdminId] = v.AdminName
+	}
+	for _, v := range descriptionList {
+		adminName, ok := adminMap[v.SysUserId]
+		if !ok {
+			adminName = ""
+		}
+		list = append(list, &models.ChartDescriptionReq{
+			Id: v.Id,
+			ChartInfoId: v.ChartInfoId,
+			Description: v.Description,
+			AdminName:   adminName,
+			SysUserId:   v.SysUserId,
+			SysUserRealName: v.SysUserRealName,
+			ModifyTime: v.ModifyTime,
+			CreateTime: v.CreateTime,
+		})
+	}
+	return
+}

+ 126 - 0
services/edb_data.go

@@ -0,0 +1,126 @@
+package services
+
+import (
+	"encoding/json"
+	"fmt"
+	"time"
+
+	"eta/eta_forum_task/models"
+	"eta/eta_forum_task/services/alarm_msg"
+	"eta/eta_forum_task/services/eta_forum"
+	"eta/eta_forum_task/utils"
+)
+
+type EdbDataBinlogDataReq struct {
+	Item 	 string  `description:"指标数据列表"`
+	OpType   string  `description:"操作类型"`
+}
+
+type EdbDataBinlogReq struct {
+	List []*EdbDataBinlogDataReq `description:"指标数据列表"`
+}
+
+func HandleBinlogEdbUpdateLog() (err error) {
+	utils.FileLog.Info("HandleBinlogEdbUpdateLog 开始")
+	// 设置缓存防止重复调用
+	cacheKey := utils.CACHE_KEY_EDB_DATA_UPDATE_LOG
+	if utils.Rc.Get(cacheKey) != nil {
+		utils.FileLog.Info("HandleBinlogEdbUpdateLog cacheKey exists")
+		return nil
+	}
+	utils.Rc.SetNX(cacheKey, "1", 10*time.Minute)
+	defer func() {
+		utils.Rc.Delete(cacheKey)
+		if err := recover(); err != nil {
+			utils.FileLog.Error("[HandleBinlogEdbUpdateLog]", err)
+		}
+	}()
+	//查询记录总数
+	dateTime := "2024-10-14 00:00:00"
+	total, err := models.GetEdbUpdateLogListCount(dateTime)
+	if err != nil {
+		return err
+	}
+
+	//分页获取待处理的日志列表	
+	if total == 0 {
+		return nil
+	}
+	offset := 0
+	pageSize := 1000
+	// 计算需要分多少页
+	pageNum := total / pageSize
+	if total % pageSize != 0 {
+		pageNum += 1
+	}
+
+	// 循环更新1000个图表数据
+	for i := 0; i < pageNum; i++ {
+		// 查询需要更新的图表信息
+		logs, err := models.GetEdbUpdateLogList(dateTime, offset, pageSize)
+		if err != nil {
+			return err
+		}
+		if len(logs) == 0 {
+			break
+		}
+		//处理日志
+		list := make([]*EdbDataBinlogDataReq, 0)
+		logIds := make([]int, 0)
+		for _, log := range logs {
+			logIds = append(logIds, int(log.Id))
+			//根据op_table_name查询表结构
+			if log.OpType == "insert" || log.OpType == "update" {
+				tmp := &EdbDataBinlogDataReq{
+					Item: log.NewData,
+					OpType: log.OpType,
+				}
+				list = append(list, tmp)
+			}else if log.OpType == "delete" {
+				tmp := &EdbDataBinlogDataReq{
+					Item: log.OldData,
+					OpType: log.OpType,
+				}
+				list = append(list, tmp)
+			}
+		}
+		if len(list) == 0 {
+			continue
+		}
+		req := &EdbDataBinlogReq{
+			List: list,
+		}
+		//批量上传
+		reqJson, err := json.Marshal(req)
+		if err != nil {
+			return err
+		}
+		resp, err := eta_forum.EdbDataBatchSaveLib(string(reqJson))
+		if err != nil {
+			return err
+		}
+		if resp.Ret != 200 {
+			return fmt.Errorf("上传失败,Err:%s", resp.ErrMsg)
+		}
+		// 批量更新日志状态
+		err = models.UpdateEdbUpdateLogStatus(logIds)
+		if err != nil {
+			return err
+		}
+	}
+	utils.FileLog.Info("HandleBinlogEdbUpdateLog 结束")
+	return nil
+}
+
+// the service for log
+func AutoUpdateEdbDataToEtaForum() {
+	for {
+		utils.Rc.Brpop(utils.CACHE_KEY_EDB_DATA_UPDATE_LOG, func(b []byte) {
+			err := HandleBinlogEdbUpdateLog()
+			if err != nil {
+				utils.FileLog.Info("[AutoUpdateEdbDataToEtaForum]", err)
+				go alarm_msg.SendAlarmMsg(fmt.Sprintf("[AutoUpdateEdbDataToEtaForum] 更新指标数据失败,Err:%s", err), 3)
+			}
+		})
+	}
+}

+ 6 - 4
services/eta_forum/eta_forum_hub.go

@@ -16,7 +16,7 @@ type UpdateChartToForumReq struct {
 
 type ChartSaveLibReq struct {
 	ChartInfo               *models.ChartInfo
-	Description             string `description:"逻辑简述"`
+	Description             []*models.ChartDescriptionReq `description:"逻辑简述"`
 	EdbInfoList             []*models.EdbInfo
 	ChartThemeList          []*chart_theme.ChartTheme
 	EdbInfoDataList         []*AddEdbDataReq
@@ -25,6 +25,7 @@ type ChartSaveLibReq struct {
 	ChartSeries             []*models.ChartSeries
 	ChartSeriesEdbMapping   []*models.ChartSeriesEdbMapping
 	CreatorInfo             *models.Admin //创建者的账号信息
+	UploaderInfo            *models.Admin //上传者的账号信息
 }
 
 type ChartSaveLibResp struct {
@@ -39,9 +40,10 @@ type ChartSaveLibResp struct {
 }
 
 type AddEdbDataReq struct {
-	EdbCode  string
-	EdbType  int `description:"指标类型:1:基础指标,2:计算指标"`
-	DataList []*models.EdbDataBase
+	EdbInfoId int
+	EdbCode   string
+	EdbType   int `description:"指标类型:1:基础指标,2:计算指标"`
+	DataList  []*models.EdbDataBase
 }
 
 type DeleteChartReq struct {

+ 20 - 0
services/eta_forum/eta_forum_hub_lib.go

@@ -10,6 +10,17 @@ import (
 	"strings"
 )
 
+// ChartSaveLib 上传图表信息
+func ChartSaveLib(req string) (resp *ChartSaveLibResp, err error) {
+	_, resultByte, err := post(req, "/v1/chart/save")
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	return
+}
+
+
 // ChartUpdateLib 更新图表信息
 func ChartUpdateLib(req string) (resp *ChartSaveLibResp, err error) {
 	_, resultByte, err := post(req, "/v1/chart/update")
@@ -30,6 +41,15 @@ func AdminBatchSaveLib(req string) (resp *models.BaseResponse, err error) {
 	return
 }
 
+// 指标数据批量上传
+func EdbDataBatchSaveLib(req string) (resp *models.BaseResponse, err error) {
+	_, resultByte, err := post(req, "/v1/edb_data/save_by_binlog")
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	return
+}
 // ETA 试用客户禁用
 func ETATrialDisabled() (resp *models.BaseResponse, err error) {
 	_, resultByte, err := post("", "/v1/eta_trial/admin/auto_disable")

+ 4 - 3
services/task.go

@@ -12,15 +12,16 @@ func Task() {
 	if utils.RunMode == "release" {
 		releaseTask()
 	}
-	// 定时更新图表数据到eta社区
-	etaForumChartUpdate := task.NewTask("publishSmartReport", "0 */30 * * * *", EtaForumChartUpdate)
+	// 定时更新图表数据到eta社区,更新改成了9-21点,每隔3小时更新一次
+	etaForumChartUpdate := task.NewTask("etaForumChartUpdate", "0 0 9-21/3 * * *", EtaForumChartUpdate)
 	task.AddTask("定时更新图表数据到eta社区", etaForumChartUpdate)
 
 	// 每隔1小时,定时更新管理员数据到eta社区
-	etaForumAdminUpdate := task.NewTask("etaForumAdminUpdate", "0 0 */1 * * *", AdminBatchSaveTask)
+	etaForumAdminUpdate := task.NewTask("etaForumAdminUpdate", "0 0 */2 * * *", AdminBatchSaveTask)
 	task.AddTask("定时更新管理员数据到eta社区", etaForumAdminUpdate)
 	task.StartTask()
 	fmt.Println("task end")
+	go AutoUpdateEdbDataToEtaForum()
 }
 
 func releaseTask() {

+ 12 - 0
utils/constants.go

@@ -255,3 +255,15 @@ const (
 	CHART_TYPE_RADAR           = 11 //雷达图
 	CHART_TYPE_SECTION_COMBINE = 14 //截面组合图
 )
+
+// 图表分类设置精选资源分类
+const (
+	ChartClassifyIsSelected = 1 // 图表分类设置精选资源分类
+	ChartClassifyResourceStatusUp = 1 // 图表分类上架状态
+	ChartClassifyResourceStatusDown = 2 // 图表分类下架状态
+	ChartClassifyResourceStatusDefault = 0 // 图表分类默认状态
+)
+
+const (
+	CACHE_KEY_EDB_DATA_UPDATE_LOG = "eta_forum:edb_data_update_log" // 经济数据库数据更新日志
+)